Propagate lots 'o work from the development branch.

Including:

Preliminary work on internationalizing error messages

Preliminary work on exposing runtime errors as catchable exceptions

ECMA-proposed throw and try/catch/finally, with multiple catch clauses
and catchguards

ECMA-proposed in/instanceof operators

IEEE-conformant number to string conversion

Fixes and other good stuff.
This commit is contained in:
mccabe%netscape.com 1998-08-29 00:38:43 +00:00
Родитель 3055ac58c7
Коммит 7d3a211f53
42 изменённых файлов: 4541 добавлений и 5023 удалений

Просмотреть файл

@ -26,8 +26,12 @@ OS_CPUARCH := $(shell uname -m)
ifeq ($(OS_CPUARCH),i86pc) ifeq ($(OS_CPUARCH),i86pc)
OS_RELEASE := $(shell uname -r)_$(OS_CPUARCH) OS_RELEASE := $(shell uname -r)_$(OS_CPUARCH)
else else
ifeq ($(OS_ARCH),AIX)
OS_RELEASE := $(shell uname -v).$(shell uname -r)
else
OS_RELEASE := $(shell uname -r) OS_RELEASE := $(shell uname -r)
endif endif
endif
# Virtually all Linux versions are identical. # Virtually all Linux versions are identical.
# Any distinctions are handled in linux.h # Any distinctions are handled in linux.h
@ -40,6 +44,8 @@ endif
ASFLAGS = ASFLAGS =
DEFINES = DEFINES =
#NS_USE_NATIVE = 1
include config/$(OS_CONFIG).mk include config/$(OS_CONFIG).mk
ifdef BUILD_OPT ifdef BUILD_OPT
@ -83,6 +89,20 @@ CFLAGS = $(OPTIMIZER) $(OS_CFLAGS) $(DEFINES) $(INCLUDES) \
-DJSFILE $(XCFLAGS) -DJSFILE $(XCFLAGS)
LDFLAGS = -lm $(XLDFLAGS) LDFLAGS = -lm $(XLDFLAGS)
#
# Ask perl what flags it was built with, so we can build js with similar flags
# and link properly. Viva gmake.
#
ifdef PERLCONNECT
DEFINES += -DPERLCONNECT
PERLCFLAGS := $(shell perl -MExtUtils::Embed -e ccopts)
PERLLDFLAGS := $(shell perl -MExtUtils::Embed -e ldopts)
CFLAGS += $(PERLCFLAGS)
LDFLAGS += $(PERLLDFLAGS)
endif
# For purify # For purify
PURE_CFLAGS = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \ PURE_CFLAGS = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \
$(INCLUDES) $(XCFLAGS) $(INCLUDES) $(XCFLAGS)
@ -114,6 +134,7 @@ JS_HFILES = \
jscntxt.h \ jscntxt.h \
jsdate.h \ jsdate.h \
jsemit.h \ jsemit.h \
jsexn.h \
jsfun.h \ jsfun.h \
jsgc.h \ jsgc.h \
jsinterp.h \ jsinterp.h \
@ -160,6 +181,7 @@ JS_CFILES = \
jsdate.c \ jsdate.c \
jsdbgapi.c \ jsdbgapi.c \
jsemit.c \ jsemit.c \
jsexn.c \
jsfun.c \ jsfun.c \
jsgc.c \ jsgc.c \
jsinterp.c \ jsinterp.c \
@ -177,6 +199,10 @@ JS_CFILES = \
jsxdrapi.c \ jsxdrapi.c \
$(NULL) $(NULL)
ifdef PERLCONNECT
JS_CFILES += jsperl.c
endif
LIB_CFILES = $(PR_CFILES) $(JS_CFILES) LIB_CFILES = $(PR_CFILES) $(JS_CFILES)
LIB_ASFILES := $(wildcard *_$(OS_ARCH).s) LIB_ASFILES := $(wildcard *_$(OS_ARCH).s)
PROG_CFILES = js.c PROG_CFILES = js.c

Просмотреть файл

@ -1,56 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for IRIX
#
CPU_ARCH = mips
GFX_ARCH = x
RANLIB = /bin/true
#NS_USE_GCC = 1
ifdef NS_USE_GCC
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 -32 -DIRIX6_2
endif
ifeq ($(OS_RELEASE),6.3)
CC = cc -32 -DIRIX6_3
endif
CCC = 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) -shared

Просмотреть файл

@ -1,20 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for IRIX5.3
#
include config/IRIX.mk

Просмотреть файл

@ -1,20 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for IRIX6.3
#
include config/IRIX.mk

Просмотреть файл

@ -1,44 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
# Config for all versions of Linux
CC = gcc -Wall -Wno-format
CCC = g++ -Wall -Wno-format
RANLIB = echo
#.c.o:
# $(CC) -c -MD $*.d $(CFLAGS) $<
CPU_ARCH = $(shell uname -m)
ifeq (86,$(findstring 86,$(CPU_ARCH)))
CPU_ARCH = x86
endif
GFX_ARCH = x
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DLINUX
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

Просмотреть файл

@ -1,78 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# 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 =

Просмотреть файл

@ -1,65 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for SunOS5.3
#
CC = gcc -Wall -Wno-format
CCC = g++ -Wall -Wno-format
#CC = /opt/SUNWspro/SC3.0.1/bin/cc
RANLIB = echo
#.c.o:
# $(CC) -c -MD $*.d $(CFLAGS) $<
CPU_ARCH = sparc
GFX_ARCH = x
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -DSOLARIS
OS_LIBS = -lsocket -lnsl -ldl
ASFLAGS += -P -L -K PIC -D_ASM -D__STDC__=0
HAVE_PURIFY = 1
NOSUCHFILE = /solaris-rm-f-sucks
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus
ULTRA_OPTIONSD := -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
ULTRA_OPTIONSD :=
endif
ifeq ($(OS_CPUARCH),sun4u)
DEFINES += $(ULTRA_OPTIONSD)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,$(ULTRA_OPTIONS),$(ULTRA_OPTIONSD)
else
ASFLAGS += $(ULTRA_OPTIONS) $(ULTRA_OPTIONSD)
endif
endif
ifeq ($(OS_CPUARCH),sun4m)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,-xarch=v8
else
ASFLAGS += -xarch=v8
endif
endif

Просмотреть файл

@ -1,66 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for SunOS5.4
#
ifdef NS_USE_NATIVE
CC = cc
CCC = CC
else
CC = gcc -Wall -Wno-format
CCC = g++ -Wall -Wno-format
endif
RANLIB = echo
CPU_ARCH = sparc
GFX_ARCH = x
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D__svr4 -DSOLARIS
OS_LIBS = -lsocket -lnsl -ldl
ASFLAGS += -P -L -K PIC -D_ASM -D__STDC__=0
HAVE_PURIFY = 1
NOSUCHFILE = /solaris-rm-f-sucks
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus
ULTRA_OPTIONSD := -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
ULTRA_OPTIONSD :=
endif
ifeq ($(OS_CPUARCH),sun4u)
DEFINES += $(ULTRA_OPTIONSD)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,$(ULTRA_OPTIONS),$(ULTRA_OPTIONSD)
else
ASFLAGS += $(ULTRA_OPTIONS) $(ULTRA_OPTIONSD)
endif
endif
ifeq ($(OS_CPUARCH),sun4m)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,-xarch=v8
else
ASFLAGS += -xarch=v8
endif
endif

Просмотреть файл

@ -1,65 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for SunOS5.5
#
AS = as
CC = gcc -Wall -Wno-format
CCC = g++ -Wall -Wno-format
#CC = /opt/SUNWspro/SC3.0.1/bin/cc
RANLIB = echo
#.c.o:
# $(CC) -c -MD $*.d $(CFLAGS) $<
CPU_ARCH = sparc
GFX_ARCH = x
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -DSOLARIS -D_SVID_GETTOD
OS_LIBS = -lsocket -lnsl -ldl
ASFLAGS += -P -L -K PIC -D_ASM -D__STDC__=0
HAVE_PURIFY = 1
NOSUCHFILE = /solaris-rm-f-sucks
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus
ULTRA_OPTIONSD := -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
ULTRA_OPTIONSD :=
endif
ifeq ($(OS_CPUARCH),sun4u)
DEFINES += $(ULTRA_OPTIONSD)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,$(ULTRA_OPTIONS),$(ULTRA_OPTIONSD)
else
ASFLAGS += $(ULTRA_OPTIONS) $(ULTRA_OPTIONSD)
endif
endif
ifeq ($(OS_CPUARCH),sun4m)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,-xarch=v8
else
ASFLAGS += -xarch=v8
endif
endif

Просмотреть файл

@ -1,60 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# Config stuff for SunOS5.5
#
AS = as
CC = gcc -Wall -Wno-format
CCC = g++ -Wall -Wno-format
#CC = /opt/SUNWspro/SC3.0.1/bin/cc
RANLIB = echo
#.c.o:
# $(CC) -c -MD $*.d $(CFLAGS) $<
CPU_ARCH = sparc
GFX_ARCH = x
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -DSOLARIS -D_SVID_GETTOD
OS_LIBS = -lsocket -lnsl -ldl
ASFLAGS += -P -L -K PIC -D_ASM -D__STDC__=0
HAVE_PURIFY = 1
NOSUCHFILE = /solaris-rm-f-sucks
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
endif
ifeq ($(OS_CPUARCH),sun4u)
ASFLAGS += $(ULTRA_OPTIONS)
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,$(ULTRA_OPTIONS)
endif
else
ifeq ($(OS_CPUARCH),sun4m)
ASFLAGS += -xarch=v8
ifeq ($(findstring gcc,$(CC)),gcc)
DEFINES += -Wa,-xarch=v8
endif
endif
endif

Просмотреть файл

@ -1,44 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
# Config for Windows NT using MS Visual C++ (version?)
CC = cl
RANLIB = echo
#.c.o:
# $(CC) -c -MD $*.d $(CFLAGS) $<
CPU_ARCH = x86 # XXX fixme
GFX_ARCH = win32
OS_CFLAGS = -DXP_PC -DWIN32 -D_WINDOWS -D_WIN32
OS_LIBS = -lm -lc
PREBUILT_CPUCFG = 1
USE_MSVC = 1
LIB_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib /nologo\
/subsystem:windows /dll /incremental:yes /debug\
/machine:I386
CAFEDIR = t:/cafe
JCLASSPATH = $(CAFEDIR)/Java/Lib/classes.zip
JAVAC = $(CAFEDIR)/Bin/sj.exe
JAVAH = $(CAFEDIR)/Java/Bin/javah.exe
JCFLAGS = -I$(CAFEDIR)/Java/Include -I$(CAFEDIR)/Java/Include/win32

Просмотреть файл

@ -104,6 +104,8 @@ static JSDJContext *_jsdjc;
#endif /* JSDEBUGGER_JAVA_UI */ #endif /* JSDEBUGGER_JAVA_UI */
#endif /* JSDEBUGGER */ #endif /* JSDEBUGGER */
static int reportWarnings;
static void static void
Process(JSContext *cx, JSObject *obj, char *filename) Process(JSContext *cx, JSObject *obj, char *filename)
{ {
@ -161,6 +163,31 @@ Process(JSContext *cx, JSObject *obj, char *filename)
if (str) if (str)
printf("%s\n", JS_GetStringBytes(str)); printf("%s\n", JS_GetStringBytes(str));
} }
if (JS_IsExceptionPending(cx) &&
JS_GetPendingException(cx, &result))
{
/*
* Calling JS_ValueToString could cause another error (and
* throw an associated exception) - so we disable the error
* reporter so nothing gets reported, and we always clear
* the pending exception... which might be different than
* the one we just got in &result.
*/
JSErrorReporter older;
older = JS_SetErrorReporter(cx, NULL);
str = JS_ValueToString(cx, result);
JS_SetErrorReporter(cx, older);
/* XXX non-i18nized strings... */
if (str) {
fprintf(stderr, "Uncaught javascript exception: %s\n",
JS_GetStringBytes(str));
} else {
fprintf(stderr, "Uncaught javascript exception\n");
}
JS_ClearPendingException(cx);
}
JS_DestroyScript(cx, script); JS_DestroyScript(cx, script);
} }
} }
@ -180,7 +207,7 @@ static int
usage(void) usage(void)
{ {
fprintf(stderr, "%s\n", JS_GetImplementationVersion()); fprintf(stderr, "%s\n", JS_GetImplementationVersion());
fprintf(stderr, "usage: js [-v version] [-f scriptfile] [scriptfile] [scriptarg...]\n"); fprintf(stderr, "usage: js [-w] [-v version] [-f scriptfile] [scriptfile] [scriptarg...]\n");
return 2; return 2;
} }
@ -204,6 +231,9 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
JS_SetVersion(cx, atoi(argv[i+1])); JS_SetVersion(cx, atoi(argv[i+1]));
i++; i++;
break; break;
case 'w':
reportWarnings++;
break;
case 'f': case 'f':
if (i+1 == argc) { if (i+1 == argc) {
@ -423,7 +453,7 @@ Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
int32 i; int32 i;
if (argc == 0) { if (argc == 0) {
JS_ReportError(cx, "usage: trap [fun] [pc] expr"); JS_ReportErrorNumber(cx, NULL, JSMSG_TRAP_USAGE);
return JS_FALSE; return JS_FALSE;
} }
argc--; argc--;
@ -457,7 +487,7 @@ LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
jsbytecode *pc; jsbytecode *pc;
if (argc == 0) { if (argc == 0) {
JS_ReportError(cx, "usage: line2pc [fun] line"); JS_ReportErrorNumber(cx, NULL, JSMSG_LINE2PC_USAGE);
return JS_FALSE; return JS_FALSE;
} }
script = cx->fp->down->script; script = cx->fp->down->script;
@ -619,13 +649,14 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
return JS_FALSE; return JS_FALSE;
if (!fun->script || !fun->script->filename) { if (!fun->script || !fun->script->filename) {
JS_ReportError(cx, "only works on JS scripts read from files"); JS_ReportErrorNumber(cx, NULL, JSMSG_FILE_SCRIPTS_ONLY);
return JS_FALSE; return JS_FALSE;
} }
file = fopen(fun->script->filename, "r"); file = fopen(fun->script->filename, "r");
if (!file) { if (!file) {
JS_ReportError(cx, "can't open %s: %s", fun->script->filename, strerror(errno)); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_OPEN,
fun->script->filename, strerror(errno));
return JS_FALSE; return JS_FALSE;
} }
@ -652,9 +683,9 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
bupline = 0; bupline = 0;
while (line1 < line2) { while (line1 < line2) {
if (!fgets(linebuf, LINE_BUF_LEN, file)) { if (!fgets(linebuf, LINE_BUF_LEN, file)) {
JS_ReportError(cx, "unexpected EOF in %s", JS_ReportErrorNumber(cx, NULL, JSMSG_UNEXPECTED_EOF,
fun->script->filename); fun->script->filename);
goto bail; goto bail;
} }
line1++; line1++;
printf("%s %3u: %s", sep, line1, linebuf); printf("%s %3u: %s", sep, line1, linebuf);
@ -826,7 +857,7 @@ DoExport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
uintN attrs; uintN attrs;
if (argc != 2) { if (argc != 2) {
JS_ReportError(cx, "usage: doexp obj id"); JS_ReportErrorNumber(cx, NULL, JSMSG_DOEXP_USAGE);
return JS_FALSE; return JS_FALSE;
} }
if (!JS_ValueToObject(cx, argv[0], &obj)) if (!JS_ValueToObject(cx, argv[0], &obj))
@ -1120,24 +1151,52 @@ static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{ {
int i, j, k, n; int i, j, k, n;
char *prefix = NULL, *tmp;
fputs("js: ", stderr);
if (!report) { if (!report) {
fprintf(stderr, "%s\n", message); fprintf(stderr, "%s\n", message);
return; return;
} }
if (report->filename) /*
fprintf(stderr, "%s, ", report->filename); * Conditionally ignore reported warnings, and ignore error reports for
if (report->lineno) * which a JavaScript exception has been thrown.
fprintf(stderr, "line %u: ", report->lineno); */
fputs(message, stderr); if ((JSREPORT_IS_WARNING(report->flags) && !reportWarnings) ||
if (!report->linebuf) { JSREPORT_IS_EXCEPTION(report->flags)) {
putc('\n', stderr); return;
return;
} }
fprintf(stderr, ":\n%s\n", report->linebuf); if (report->filename)
prefix = PR_smprintf("%s:", report->filename);
if (report->lineno) {
tmp = prefix;
prefix = PR_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
JS_free(cx, tmp);
}
if (JSREPORT_IS_WARNING(report->flags)) {
tmp = prefix;
prefix = PR_smprintf("%swarning: ", tmp ? tmp : "");
JS_free(cx, tmp);
}
/* embedded newlines -- argh! */
while ((tmp = strchr(message, '\n'))) {
tmp++;
fputs(prefix, stderr);
fwrite(message, 1, tmp - message, stderr);
message = tmp;
}
/* If there were no filename or lineno, the prefix might be empty */
if (prefix) fputs(prefix, stderr);
fputs(message, stderr);
if (!report->linebuf) {
putc('\n', stderr);
goto out;
}
fprintf(stderr, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
n = report->tokenptr - report->linebuf; n = report->tokenptr - report->linebuf;
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
if (report->linebuf[i] == '\t') { if (report->linebuf[i] == '\t') {
@ -1149,6 +1208,8 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
j++; j++;
} }
fputs("^\n", stderr); fputs("^\n", stderr);
out:
JS_free(cx, prefix);
} }
#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
@ -1265,6 +1326,12 @@ main(int argc, char **argv)
JSContext *cx; JSContext *cx;
JSObject *glob, *it; JSObject *glob, *it;
int result; int result;
#ifdef LIVECONNECT
JavaVM *java_vm = NULL;
#endif
#ifdef JSDEBUGGER_JAVA_UI
JNIEnv *java_env;
#endif
#ifdef XP_OS2 #ifdef XP_OS2
/* these streams are normally line buffered on OS/2 and need a \n, * /* these streams are normally line buffered on OS/2 and need a \n, *
@ -1278,10 +1345,10 @@ main(int argc, char **argv)
#endif #endif
version = JSVERSION_DEFAULT; version = JSVERSION_DEFAULT;
#ifndef LIVECONNECT
argc--; argc--;
argv++; argv++;
#endif
rt = JS_NewRuntime(8L * 1024L * 1024L); rt = JS_NewRuntime(8L * 1024L * 1024L);
if (!rt) if (!rt)
return 1; return 1;
@ -1309,15 +1376,10 @@ main(int argc, char **argv)
return 1; return 1;
#ifdef PERLCONNECT #ifdef PERLCONNECT
if (!js_InitPerlClass(cx, glob)) if (!JS_InitPerlClass(cx, glob))
return 1; return 1;
#endif #endif
#ifdef LIVECONNECT
if (!JSJ_SimpleInit(cx, glob, NULL, getenv("CLASSPATH")))
return 1;
#endif
#ifdef JSDEBUGGER #ifdef JSDEBUGGER
/* /*
* XXX A command line option to enable debugging (or not) would be good * XXX A command line option to enable debugging (or not) would be good
@ -1332,7 +1394,9 @@ main(int argc, char **argv)
if (! _jsdjc) if (! _jsdjc)
return 1; return 1;
JSDJ_SetJSDContext(_jsdjc, _jsdc); JSDJ_SetJSDContext(_jsdjc, _jsdc);
JSDJ_CreateJavaVMAndStartDebugger(_jsdjc); java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc);
if (java_env)
(*java_env)->GetJavaVM(java_env, &java_vm);
/* /*
* XXX This would be the place to wait for the debugger to start. * XXX This would be the place to wait for the debugger to start.
* Waiting would be nice in general, but especially when a js file * Waiting would be nice in general, but especially when a js file
@ -1344,6 +1408,11 @@ main(int argc, char **argv)
#endif /* JSDEBUGGER_C_UI */ #endif /* JSDEBUGGER_C_UI */
#endif /* JSDEBUGGER */ #endif /* JSDEBUGGER */
#ifdef LIVECONNECT
if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
return 1;
#endif
result = ProcessArgs(cx, glob, argv, argc); result = ProcessArgs(cx, glob, argv, argc);
#ifdef JSDEBUGGER #ifdef JSDEBUGGER

Просмотреть файл

@ -36,6 +36,7 @@
#include "jsconfig.h" #include "jsconfig.h"
#include "jsdate.h" #include "jsdate.h"
#include "jsemit.h" #include "jsemit.h"
#include "jsexn.h"
#include "jsfun.h" #include "jsfun.h"
#include "jsgc.h" #include "jsgc.h"
#include "jsinterp.h" #include "jsinterp.h"
@ -113,10 +114,12 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
if (required) { if (required) {
fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE); fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
if (fun) { if (fun) {
JS_ReportError(cx, char numBuf[12];
"%s requires more than %u argument%s", sprintf(numBuf, "%u", argc);
JS_GetFunctionName(fun), JS_ReportErrorNumber(cx, NULL, JSMSG_MORE_ARGS_NEEDED,
argc, (argc == 1) ? "" : "s"); JS_GetFunctionName(fun),
numBuf,
(argc == 1) ? "" : "s");
} }
return JS_FALSE; return JS_FALSE;
} }
@ -184,9 +187,12 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
break; break;
case '*': case '*':
break; break;
default: default: {
JS_ReportError(cx, "invalid format character %c", *cp); char charBuf[2] = " ";
charBuf[0] = *cp;
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_CHAR, charBuf);
return JS_FALSE; return JS_FALSE;
}
} }
i++; i++;
} }
@ -239,9 +245,12 @@ JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
if (ok) if (ok)
*vp = BOOLEAN_TO_JSVAL(b); *vp = BOOLEAN_TO_JSVAL(b);
break; break;
default: default: {
JS_ReportError(cx, "unknown type %d", (int)type); char numBuf[12];
sprintf(numBuf, "%d", (int)type);
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_TYPE, numBuf);
ok = JS_FALSE; ok = JS_FALSE;
}
break; break;
} }
return ok; return ok;
@ -366,6 +375,22 @@ JS_NewRuntime(uint32 maxbytes)
{ {
JSRuntime *rt; JSRuntime *rt;
#ifdef DEBUG
PR_BEGIN_MACRO
/*
* This code asserts that the numbers associated with the error names in
* jsmsg.def are monotonically increasing. It uses values for the error
* names enumerated in jscntxt.c. It's not a compiletime check, but it's
* better than nothing.
*/
int errorNumber = 0;
#define MSG_DEF(name, number, count, exception, format) \
PR_ASSERT(name == errorNumber++);
#include "jsmsg.def"
#undef MSG_DEF
PR_END_MACRO;
#endif /* DEBUG */
if (!js_InitStringGlobals()) if (!js_InitStringGlobals())
return NULL; return NULL;
rt = malloc(sizeof(JSRuntime)); rt = malloc(sizeof(JSRuntime));
@ -663,6 +688,9 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
#endif #endif
#if JS_HAS_SCRIPT_OBJECT #if JS_HAS_SCRIPT_OBJECT
js_InitScriptClass(cx, obj) && js_InitScriptClass(cx, obj) &&
#endif
#if JS_HAS_ERROR_EXCEPTIONS
js_InitExceptionClasses(cx, obj) &&
#endif #endif
js_InitDateClass(cx, obj); js_InitDateClass(cx, obj);
} }
@ -679,7 +707,7 @@ JS_malloc(JSContext *cx, size_t nbytes)
{ {
void *p; void *p;
#if defined(XP_OS2) || defined(XP_MAC) #if defined(XP_OS2) || defined(XP_MAC) || defined(AIX)
if (nbytes == 0) /*DSR072897 - Windows allows this, OS/2 & Mac don't*/ if (nbytes == 0) /*DSR072897 - Windows allows this, OS/2 & Mac don't*/
nbytes = 1; nbytes = 1;
#endif #endif
@ -797,7 +825,7 @@ JS_LockGCThing(JSContext *cx, void *thing)
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
ok = js_LockGCThing(cx, thing); ok = js_LockGCThing(cx, thing);
if (!ok) if (!ok)
JS_ReportError(cx, "can't lock memory"); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_LOCK);
return ok; return ok;
} }
@ -809,7 +837,7 @@ JS_UnlockGCThing(JSContext *cx, void *thing)
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
ok = js_UnlockGCThing(cx, thing); ok = js_UnlockGCThing(cx, thing);
if (!ok) if (!ok)
JS_ReportError(cx, "can't unlock memory"); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_UNLOCK);
return ok; return ok;
} }
@ -1015,7 +1043,7 @@ JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
if (argv) { if (argv) {
fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE); fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
if (fun) { if (fun) {
JS_ReportError(cx, "%s.prototype.%s called on incompatible %s", JS_ReportErrorNumber(cx, NULL, JSMSG_INCOMPATIBLE_PROTO,
clasp->name, JS_GetFunctionName(fun), clasp->name, JS_GetFunctionName(fun),
OBJ_GET_CLASS(cx, obj)->name); OBJ_GET_CLASS(cx, obj)->name);
} }
@ -1108,7 +1136,7 @@ JS_GetConstructor(JSContext *cx, JSObject *proto)
if (!ok) if (!ok)
return NULL; return NULL;
if (!JSVAL_IS_FUNCTION(cx, cval)) { if (!JSVAL_IS_FUNCTION(cx, cval)) {
JS_ReportError(cx, "%s has no constructor", JS_ReportErrorNumber(cx, NULL, JSMSG_NO_CONSTRUCTOR,
OBJ_GET_CLASS(cx, proto)->name); OBJ_GET_CLASS(cx, proto)->name);
return NULL; return NULL;
} }
@ -1323,7 +1351,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
} }
if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) { if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) {
OBJ_DROP_PROPERTY(cx, obj2, prop); OBJ_DROP_PROPERTY(cx, obj2, prop);
JS_ReportError(cx, "can't alias %s to %s in class %s", JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_ALIAS,
alias, name, OBJ_GET_CLASS(cx, obj2)->name); alias, name, OBJ_GET_CLASS(cx, obj2)->name);
return JS_FALSE; return JS_FALSE;
} }
@ -1361,17 +1389,14 @@ LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop)
return rval; return rval;
} }
JS_PUBLIC_API(JSBool) static JSBool
JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, GetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
uintN *attrsp, JSBool *foundp) uintN *attrsp, JSBool *foundp)
{ {
JSAtom *atom;
JSObject *obj2; JSObject *obj2;
JSProperty *prop; JSProperty *prop;
JSBool ok; JSBool ok;
CHECK_REQUEST(cx);
atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
@ -1389,17 +1414,14 @@ JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
return ok; return ok;
} }
JS_PUBLIC_API(JSBool) static JSBool
JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, SetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
uintN attrs, JSBool *foundp) uintN attrs, JSBool *foundp)
{ {
JSAtom *atom;
JSObject *obj2; JSObject *obj2;
JSProperty *prop; JSProperty *prop;
JSBool ok; JSBool ok;
CHECK_REQUEST(cx);
atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
@ -1417,6 +1439,27 @@ JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
return ok; return ok;
} }
JS_PUBLIC_API(JSBool)
JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
uintN *attrsp, JSBool *foundp)
{
CHECK_REQUEST(cx);
return GetPropertyAttributes(cx, obj,
js_Atomize(cx, name, strlen(name), 0),
attrsp, foundp);
}
JS_PUBLIC_API(JSBool)
JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
uintN attrs, JSBool *foundp)
{
CHECK_REQUEST(cx);
return SetPropertyAttributes(cx, obj,
js_Atomize(cx, name, strlen(name), 0),
attrs, foundp);
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
{ {
@ -1488,6 +1531,28 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj,
attrs, NULL); attrs, NULL);
} }
JS_PUBLIC_API(JSBool)
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen,
uintN *attrsp, JSBool *foundp)
{
CHECK_REQUEST(cx);
return GetPropertyAttributes(cx, obj,
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
attrsp, foundp);
}
JS_PUBLIC_API(JSBool)
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen,
uintN attrs, JSBool *foundp)
{
CHECK_REQUEST(cx);
return SetPropertyAttributes(cx, obj,
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
attrs, foundp);
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen, const jschar *name, size_t namelen,
@ -1633,9 +1698,11 @@ JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
return JS_FALSE; return JS_FALSE;
} }
if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) { if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) {
char numBuf[12];
OBJ_DROP_PROPERTY(cx, obj2, prop); OBJ_DROP_PROPERTY(cx, obj2, prop);
JS_ReportError(cx, "can't alias %ld to %s in class %s", sprintf(numBuf, "%ld", (long)alias);
(long)alias, name, OBJ_GET_CLASS(cx, obj2)->name); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_ALIAS,
numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
return JS_FALSE; return JS_FALSE;
} }
scope = (JSScope *) obj->map; scope = (JSScope *) obj->map;
@ -2423,7 +2490,30 @@ JS_ReportError(JSContext *cx, const char *format, ...)
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
va_start(ap, format); va_start(ap, format);
js_ReportErrorVA(cx, format, ap); js_ReportErrorVA(cx, JSREPORT_ERROR, format, ap);
va_end(ap);
}
JS_PUBLIC_API(void)
JS_ReportErrorNumber(JSContext *cx, JSErrorCallBack errCallBack,
const uintN errorNumber, ...)
{
va_list ap;
CHECK_REQUEST(cx);
va_start(ap, errorNumber);
js_ReportErrorNumberVA(cx, JSREPORT_ERROR,
errCallBack, errorNumber, ap);
va_end(ap);
}
PR_PUBLIC_API(void)
JS_ReportWarning(JSContext *cx, const char *format, ...)
{
va_list ap;
va_start(ap, format);
js_ReportErrorVA(cx, JSREPORT_WARNING, format, ap);
va_end(ap); va_end(ap);
} }
@ -2464,7 +2554,7 @@ JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags)
JS_free(cx, chars); JS_free(cx, chars);
return obj; return obj;
#else #else
JS_ReportError(cx, "sorry, regular expression are not supported"); JS_ReportErrorNumber(cx, NULL, JSMSG_NO_REG_EXPS);
return NULL; return NULL;
#endif #endif
} }
@ -2476,7 +2566,7 @@ JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags)
#if JS_HAS_REGEXPS #if JS_HAS_REGEXPS
return js_NewRegExpObject(cx, chars, length, flags); return js_NewRegExpObject(cx, chars, length, flags);
#else #else
JS_ReportError(cx, "sorry, regular expression are not supported"); JS_ReportErrorNumber(cx, NULL, JSMSG_NO_REG_EXPS);
return NULL; return NULL;
#endif #endif
} }
@ -2528,7 +2618,7 @@ JS_IsExceptionPending(JSContext *cx)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
#if JS_HAS_EXCEPTIONS #if JS_HAS_EXCEPTIONS
return (JSBool) cx->fp->throwing; return (JSBool) cx->throwing;
#else #else
return JS_FALSE; return JS_FALSE;
#endif #endif
@ -2539,9 +2629,9 @@ JS_GetPendingException(JSContext *cx, jsval *vp)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
#if JS_HAS_EXCEPTIONS #if JS_HAS_EXCEPTIONS
if (!cx->fp->throwing) if (!cx->throwing)
return JS_FALSE; return JS_FALSE;
*vp = cx->fp->exception; *vp = cx->exception;
return JS_TRUE; return JS_TRUE;
#else #else
return JS_FALSE; return JS_FALSE;
@ -2553,8 +2643,8 @@ JS_SetPendingException(JSContext *cx, jsval v)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
#if JS_HAS_EXCEPTIONS #if JS_HAS_EXCEPTIONS
cx->fp->throwing = JS_TRUE; cx->throwing = JS_TRUE;
cx->fp->exception = v; cx->exception = v;
#endif #endif
} }
@ -2563,7 +2653,7 @@ JS_ClearPendingException(JSContext *cx)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
#if JS_HAS_EXCEPTIONS #if JS_HAS_EXCEPTIONS
cx->fp->throwing = JS_FALSE; cx->throwing = JS_FALSE;
#endif #endif
} }

Просмотреть файл

@ -605,6 +605,29 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj,
JSPropertyOp getter, JSPropertyOp setter, JSPropertyOp getter, JSPropertyOp setter,
uintN attrs); uintN attrs);
/*
* Determine the attributes (JSPROP_* flags) of a property on a given object.
*
* If the object does not have a property by that name, *foundp will be
* JS_FALSE and the value of *attrsp is undefined.
*/
extern JS_PUBLIC_API(JSBool)
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen,
uintN *attrsp, JSBool *foundp);
/*
* Set the attributes of a property on a given object.
*
* If the object does not have a property by that name, *foundp will be
* JS_FALSE and nothing will be altered.
*/
extern JS_PUBLIC_API(JSBool)
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen,
uintN attrs, JSBool *foundp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
const jschar *name, size_t namelen, const jschar *name, size_t namelen,
@ -904,6 +927,19 @@ JS_CompareStrings(JSString *str1, JSString *str2);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_ReportError(JSContext *cx, const char *format, ...); JS_ReportError(JSContext *cx, const char *format, ...);
/*
* As above, but use an errorNumber for the format string
*/
extern JS_PUBLIC_API(void)
JS_ReportErrorNumber(JSContext *cx, JSErrorCallBack errCallBack,
const uintN errorNumber, ...);
/*
* As above, but report a warning instead (JSREPORT_IS_WARNING(report->flags)).
*/
extern PR_PUBLIC_API(void)
JS_ReportWarning(JSContext *cx, const char *format, ...);
/* /*
* Complain when out of memory. * Complain when out of memory.
*/ */
@ -917,8 +953,33 @@ struct JSErrorReport {
const char *tokenptr; /* pointer to error token in linebuf */ const char *tokenptr; /* pointer to error token in linebuf */
const jschar *uclinebuf; /* unicode (original) line buffer */ const jschar *uclinebuf; /* unicode (original) line buffer */
const jschar *uctokenptr;/* unicode (original) token pointer */ const jschar *uctokenptr;/* unicode (original) token pointer */
uintN flags; /* error/warning, etc. */
uintN errorNumber; /* the error number, e.g. see jsmsg.def */
JSString *ucmessage; /* the (default) error message */
JSString **messageArgs; /* arguments for the error message */
}; };
/*
* JSErrorReport flag values.
*/
/* XXX need better classification system */
#define JSREPORT_ERROR 0x0
#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
/*
* If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
* has been thrown for this runtime error, and the host should ignore it.
* Exception-aware hosts should also check for JS_IsPendingException if
* JS_ExecuteScript returns failure, and signal or propagate the exception, as
* appropriate.
*/
#define JSREPORT_EXCEPTION 0x2
#define JSREPORT_IS_WARNING(flags) (flags & JSREPORT_WARNING)
#define JSREPORT_IS_EXCEPTION(flags) (flags & JSREPORT_EXCEPTION)
extern JS_PUBLIC_API(JSErrorReporter) extern JS_PUBLIC_API(JSErrorReporter)
JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);

Просмотреть файл

@ -495,8 +495,7 @@ array_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool static JSBool
array_nyi(JSContext *cx, const char *what) array_nyi(JSContext *cx, const char *what)
{ {
JS_ReportError(cx, "sorry, Array.prototype.%s is not yet implemented", JS_ReportErrorNumber(cx, NULL, JSMSG_NO_PROTO, what);
what);
return JS_FALSE; return JS_FALSE;
} }
#endif #endif
@ -699,7 +698,7 @@ array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (argc > 0) { if (argc > 0) {
if (JSVAL_IS_PRIMITIVE(argv[0])) { if (JSVAL_IS_PRIMITIVE(argv[0])) {
JS_ReportError(cx, "invalid Array.prototype.sort argument"); JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_PROTO_SORT);
return JS_FALSE; return JS_FALSE;
} }
fval = argv[0]; fval = argv[0];

Просмотреть файл

@ -605,7 +605,9 @@ js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
PR_ASSERT(map->vector && i < map->length); PR_ASSERT(map->vector && i < map->length);
if (!map->vector || i >= map->length) { if (!map->vector || i >= map->length) {
JS_ReportError(cx, "internal error: no index for atom %ld", (long)i); char numBuf[12];
sprintf(numBuf, "%s", (long)i);
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_ATOMIC_NUMBER, numBuf);
return NULL; return NULL;
} }
atom = map->vector[i]; atom = map->vector[i];
@ -629,7 +631,7 @@ js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
count = al->count; count = al->count;
if (count >= ATOM_INDEX_LIMIT) { if (count >= ATOM_INDEX_LIMIT) {
JS_ReportError(cx, "too many literals"); JS_ReportErrorNumber(cx, NULL, JSMSG_TOO_MANY_LITERALS);
return JS_FALSE; return JS_FALSE;
} }
vector = JS_malloc(cx, (size_t) count * sizeof *vector); vector = JS_malloc(cx, (size_t) count * sizeof *vector);

Просмотреть файл

@ -32,6 +32,7 @@
#include "jscntxt.h" #include "jscntxt.h"
#include "jsconfig.h" #include "jsconfig.h"
#include "jsdbgapi.h" #include "jsdbgapi.h"
#include "jsexn.h"
#include "jsgc.h" #include "jsgc.h"
#include "jslock.h" #include "jslock.h"
#include "jsobj.h" #include "jsobj.h"
@ -168,7 +169,7 @@ js_ContextIterator(JSRuntime *rt, JSContext **iterp)
} }
void void
js_ReportErrorVA(JSContext *cx, const char *format, va_list ap) js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
{ {
JSStackFrame *fp; JSStackFrame *fp;
JSErrorReport report, *reportp; JSErrorReport report, *reportp;
@ -181,8 +182,10 @@ js_ReportErrorVA(JSContext *cx, const char *format, va_list ap)
/* XXX should fetch line somehow */ /* XXX should fetch line somehow */
report.linebuf = NULL; report.linebuf = NULL;
report.tokenptr = NULL; report.tokenptr = NULL;
report.flags = flags;
reportp = &report; reportp = &report;
} else { } else {
/* XXXshaver still fill out report here for flags? */
reportp = NULL; reportp = NULL;
} }
last = PR_vsmprintf(format, ap); last = PR_vsmprintf(format, ap);
@ -193,6 +196,161 @@ js_ReportErrorVA(JSContext *cx, const char *format, va_list ap)
free(last); free(last);
} }
JSBool
js_ExpandErrorArguments(JSContext *cx, JSErrorCallBack callback,
const uintN errorNumber, char **message,
JSErrorReport *reportp, va_list ap)
/*
The arguments from va_list need to be packaged up into an array and stored
into the report struct.
Then...
if JS_HAS_DFLT_MSG_STRINGS
The format string addressed by the error number may contain operands
identified by the format {N}, where N is a decimal digit. Each of these
is to be replaced by the Nth argument from the va_list. The complete
message is placed into reportp->ucmessage converted to a JSString.
else
reportp->ucmessage is left NULL, to indicate that the installed error
reporter is to use the errorNumber & arguments as it wishes
endif
returns true/false if the expansion succeeds
*/
{
/* make sure this is a legal error number */
if ((errorNumber > 0) && (errorNumber < JSErr_Limit)) {
const JSErrorFormatString *fmtData;
int i;
int argCount;
if (callback)
fmtData = (*callback)(errorNumber);
else
fmtData = &js_ErrorFormatString[errorNumber];
argCount = fmtData->argCount;
if (argCount > 0) {
/*
gather the arguments into a char * array, the
messageArgs field is supposed to be an array of
JSString's and we'll convert them later.
*/
reportp->messageArgs = (JSString **)malloc(sizeof(char *) * argCount);
if (!reportp->messageArgs) return JS_FALSE;
for (i = 0; i < argCount; i++)
reportp->messageArgs[i] = (JSString *) va_arg(ap, char *);
}
#if JS_HAS_DFLT_MSG_STRINGS
/*
parse the error format, substituting the argument X
for {X} in the format
*/
if (argCount > 0) {
const char *fmt;
char *out;
int expandedLength
= strlen(fmtData->format)
- (3 * argCount);
for (i = 0; i < argCount; i++)
expandedLength += strlen((char *)(reportp->messageArgs[i]));
*message = out = malloc(expandedLength + 1);
if (!out) {
if (reportp->messageArgs) free(reportp->messageArgs);
return JS_FALSE;
}
fmt = fmtData->format;
while (*fmt) {
if (*fmt == '{') {
if (isdigit(fmt[1])) {
strcpy(out, (char *)(reportp->messageArgs[JS7_UNDEC(fmt[1])]));
out += strlen((char *)(reportp->messageArgs[JS7_UNDEC(fmt[1])]));
fmt += 3;
}
else
*out++ = *fmt++;
}
else
*out++ = *fmt++;
}
*out = '\0';
/*
Now convert all the arguments to JSString's
*/
for (i = 0; i < argCount; i++) {
reportp->messageArgs[i]
= JS_NewStringCopyZ(cx, (char *)(reportp->messageArgs[i]));
}
}
else
*message = JS_strdup(cx, fmtData->format);
/*
And finally convert the message
*/
reportp->ucmessage = JS_NewStringCopyZ(cx, *message);
#else
/*
If we're not providing the error string we just pass
the arguments array but also need to pass some content
for 'message' though this should never be seen.
*/
*message = JS_strdup(cx, "No Error Message Available");
#endif
}
return JS_TRUE;
}
void
js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallBack callback,
const uintN errorNumber, va_list ap)
{
JSStackFrame *fp;
JSErrorReport report, *reportp;
char *message;
report.messageArgs = NULL;
report.ucmessage = NULL;
message = NULL;
fp = cx->fp;
if (fp && fp->script && fp->pc) {
report.filename = fp->script->filename;
report.lineno = js_PCToLineNumber(fp->script, fp->pc);
}
else {
report.filename = NULL;
report.lineno = 0;
}
/* XXX should fetch line somehow */
report.linebuf = NULL;
report.tokenptr = NULL;
report.flags = flags;
report.errorNumber = errorNumber;
reportp = &report;
if (!js_ExpandErrorArguments(cx, callback, errorNumber,
&message, reportp, ap))
return;
#if JS_HAS_ERROR_EXCEPTIONS
/*
* Check the error report, and set a JavaScript-catchable exception
* if the error is defined to have an associated exception. If an
* exception is thrown, then the JSREPORT_EXCEPTION flag will be set
* on the error report, and exception-aware hosts should ignore it.
*/
js_ErrorToException(cx, reportp);
#endif
js_ReportErrorAgain(cx, message, reportp);
if (message) free(message);
if (report.messageArgs) free(report.messageArgs);
}
JS_FRIEND_API(void) JS_FRIEND_API(void)
js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp) js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
{ {
@ -213,7 +371,7 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
void void
js_ReportIsNotDefined(JSContext *cx, const char *name) js_ReportIsNotDefined(JSContext *cx, const char *name)
{ {
JS_ReportError(cx, "%s is not defined", name); JS_ReportErrorNumber(cx, NULL, JSMSG_NOT_DEFINED, name);
} }
#if defined DEBUG && defined XP_UNIX #if defined DEBUG && defined XP_UNIX
@ -221,3 +379,14 @@ js_ReportIsNotDefined(JSContext *cx, const char *name)
void js_traceon(JSContext *cx) { cx->tracefp = stderr; } void js_traceon(JSContext *cx) { cx->tracefp = stderr; }
void js_traceoff(JSContext *cx) { cx->tracefp = NULL; } void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
#endif #endif
#if JS_HAS_DFLT_MSG_STRINGS
JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
#define MSG_DEF(name, number, count, exception, format) \
{ format, count } ,
#include "jsmsg.def"
#undef MSG_DEF
};
#endif

Просмотреть файл

@ -160,6 +160,8 @@ struct JSContext {
jsrefcount requestDepth; jsrefcount requestDepth;
#endif #endif
JSStackFrame *dormantFrameChain; /* dormant frame chains */ JSStackFrame *dormantFrameChain; /* dormant frame chains */
JSPackedBool throwing; /* is there a pending exception? */
jsval exception; /* most-recently-thrown exceptin */
}; };
typedef struct JSInterpreterHooks { typedef struct JSInterpreterHooks {
@ -188,7 +190,14 @@ js_ContextIterator(JSRuntime *rt, JSContext **iterp);
*/ */
#ifdef va_start #ifdef va_start
extern void extern void
js_ReportErrorVA(JSContext *cx, const char *format, va_list ap); js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
extern void
js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallBack callback,
const uintN errorNumber, va_list ap);
extern JS_PUBLIC_API(JSBool)
js_ExpandErrorArguments(JSContext *cx, JSErrorCallBack callback,
const uintN errorNumber, char **message,
JSErrorReport *reportp, va_list ap);
#endif #endif
/* /*
@ -200,6 +209,17 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
extern void extern void
js_ReportIsNotDefined(JSContext *cx, const char *name); js_ReportIsNotDefined(JSContext *cx, const char *name);
enum JSErrNum {
#define MSG_DEF(name, number, count, exception, format) \
name = number,
#include "jsmsg.def"
#undef MSG_DEF
JSErr_Limit
#undef MSGDEF
};
extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
PR_END_EXTERN_C PR_END_EXTERN_C
#endif /* jscntxt_h___ */ #endif /* jscntxt_h___ */

Просмотреть файл

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

Просмотреть файл

@ -345,8 +345,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
JSWatchPoint *wp; JSWatchPoint *wp;
if (!OBJ_IS_NATIVE(obj)) { if (!OBJ_IS_NATIVE(obj)) {
JS_ReportError(cx, "can't watch non-native objects of class %s", JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_WATCH,
OBJ_GET_CLASS(cx, obj)->name); OBJ_GET_CLASS(cx, obj)->name);
return JS_FALSE; return JS_FALSE;
} }
@ -580,12 +580,36 @@ JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
return fp->fun && fp->fun->call; return fp->fun && fp->fun->call;
} }
/* this is deprecated, use JS_GetFrameScopeChain instead */
JS_PUBLIC_API(JSObject *) JS_PUBLIC_API(JSObject *)
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp) JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
{ {
return fp->scopeChain; return fp->scopeChain;
} }
JS_PUBLIC_API(JSObject *)
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
{
/* Force creation of argument and call objects if not yet created */
JS_GetFrameCallObject(cx, fp);
return fp->scopeChain;
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
{
if (! fp->fun)
return NULL;
/* Force creation of argument object if not yet created */
js_GetArgsObject(cx, fp);
#if JS_HAS_CALL_OBJECT
return js_GetCallObject(cx, fp, NULL, NULL);
#else
return NULL;
#endif /* JS_HAS_CALL_OBJECT */
}
JS_PUBLIC_API(JSObject *) JS_PUBLIC_API(JSObject *)
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp) JS_GetFrameThis(JSContext *cx, JSStackFrame *fp)
{ {
@ -680,12 +704,22 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
sym = sprop->symbols; sym = sprop->symbols;
pd->id = sym ? js_IdToValue(sym_id(sym)) : JSVAL_VOID; pd->id = sym ? js_IdToValue(sym_id(sym)) : JSVAL_VOID;
pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot); if (!sym || !js_GetProperty(cx, obj, sym_id(sym), &pd->value))
pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot);
pd->flags = ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0) pd->flags = ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
| ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0) | ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0)
| ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0) | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
#if JS_HAS_CALL_OBJECT
| ((sprop->getter == js_GetCallVariable) ? JSPD_VARIABLE : 0)
#endif /* JS_HAS_CALL_OBJECT */
| ((sprop->getter == js_GetArgument) ? JSPD_ARGUMENT : 0) | ((sprop->getter == js_GetArgument) ? JSPD_ARGUMENT : 0)
| ((sprop->getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0); | ((sprop->getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0);
#if JS_HAS_CALL_OBJECT
/* for Call Object 'real' getter isn't passed in to us */
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
OBJ_GET_CLASS(cx, obj)->getProperty == sprop->getter)
pd->flags |= JSPD_ARGUMENT;
#endif /* JS_HAS_CALL_OBJECT */
pd->spare = 0; pd->spare = 0;
pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE)) pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
? JSVAL_TO_INT(sprop->id) ? JSVAL_TO_INT(sprop->id)
@ -706,11 +740,16 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
uint32 i, n; uint32 i, n;
JSPropertyDesc *pd; JSPropertyDesc *pd;
JSScopeProperty *sprop; JSScopeProperty *sprop;
jsval state;
jsid num_prop;
if (!OBJ_GET_CLASS(cx, obj)->enumerate(cx, obj)) if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, &num_prop))
return JS_FALSE; return JS_FALSE;
scope = (JSScope *)obj->map; scope = (JSScope *)obj->map;
if (!scope->props) { /* have no props, or object's scope has not mutated from that of proto */
if (!scope->props ||
(OBJ_GET_PROTO(cx,obj) &&
scope == (JSScope *)(OBJ_GET_PROTO(cx,obj)->map))) {
pda->length = 0; pda->length = 0;
pda->array = NULL; pda->array = NULL;
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -130,9 +130,16 @@ JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
extern JS_PUBLIC_API(void *) extern JS_PUBLIC_API(void *)
JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp); JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp);
/* this is deprecated, use JS_GetFrameScopeChain instead */
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp); JS_GetFrameObject(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp); JS_GetFrameThis(JSContext *cx, JSStackFrame *fp);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

212
js/ref/jsexn.c Normal file
Просмотреть файл

@ -0,0 +1,212 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS standard exception implementation.
*/
#include "jsstddef.h"
#include "prtypes.h"
#include "prassert.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsexn.h"
#if JS_HAS_ERROR_EXCEPTIONS
#if !JS_HAS_EXCEPTIONS
# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"
#endif
/* Maybe #define RANDOM_CLASS(name, prototype) 4 here? */
struct JSExnSpec {
int protoIndex;
JSClass theclass;
};
/* This must be kept in synch with the exceptions array */
typedef enum JSExnType {
JSEXN_NONE = -1,
JSEXN_EXCEPTION,
JSEXN_ERR,
JSEXN_INTERNALERR,
JSEXN_SYNTAXERR,
JSEXN_REFERENCEERR,
JSEXN_CALLERR,
JSEXN_TARGETERR,
JSEXN_CONSTRUCTORERR,
JSEXN_CONVERSIONERR,
JSEXN_TOOBJECTERR,
JSEXN_TOPRIMITIVEERR,
JSEXN_DEFAULTVALUEERR,
JSEXN_ARRAYERR,
JSEXN_LIMIT
} JSExnType;
#define FLAGS JSCLASS_HAS_PRIVATE
static struct JSExnSpec exceptions[] = {
{ JSEXN_NONE, /* No proto? */ {
"Exception", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_EXCEPTION, {
"Error", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"InternalError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"SyntaxError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"ReferenceError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"CallError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_CALLERR, {
"TargetError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"ConstructorError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"ConversionError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_CONVERSIONERR, {
"ToObjectError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_CONVERSIONERR, {
"ToPrimitiveError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_CONVERSIONERR, {
"DefaultValueError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{ JSEXN_ERR, {
"ArrayError", FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
} },
{0}
};
static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsval bval;
bval = JSVAL_FALSE;
if (!cx->fp->constructing) {
*rval = bval;
return JS_TRUE;
}
return JS_TRUE;
}
static JSFunctionSpec exception_methods[] = {
{0}
};
JSObject *
js_InitExceptionClasses(JSContext *cx, JSObject *obj)
{
JSObject *protos[JSEXN_LIMIT];
int i;
for (i = 0; exceptions[i].theclass.name != 0; i++) {
int protoidx = exceptions[i].protoIndex;
protos[i] = JS_InitClass(cx, obj,
((protoidx >= 0) ? protos[protoidx] : NULL),
&(exceptions[i].theclass),
Exception, 1,
NULL,
exception_methods,
NULL,
NULL);
}
/*
* JS_InitClass magically replaces a null prototype with Object.prototype,
* so we need to explicitly assign to the proto slot to get null.
*
* Temporarily disabled until I do toString for Exception.
*/
/* protos[0]->slots[JSSLOT_PROTO] = JSVAL_NULL; */
return protos[0];
}
static JSExnType errorToException[] = {
#define MSG_DEF(name, number, count, exception, format) \
exception,
#include "jsmsg.def"
#undef MSG_DEF
};
JSBool
js_ErrorToException(JSContext *cx, JSErrorReport *reportp) {
uintN errorNumber;
JSObject *errobj;
JSExnType exn;
PR_ASSERT(reportp);
errorNumber = reportp->errorNumber;
exn = errorToException[errorNumber];
PR_ASSERT(exn < JSEXN_LIMIT);
if (exn > JSEXN_NONE) {
errobj = js_ConstructObject(cx,
&(exceptions[exn].theclass),
NULL, NULL);
JS_SetPendingException(cx, OBJECT_TO_JSVAL(errobj));
reportp->flags |= JSREPORT_EXCEPTION;
return JS_TRUE;
}
return JS_FALSE;
}
#endif /* JS_HAS_ERROR_EXCEPTIONS */

47
js/ref/jsexn.h Normal file
Просмотреть файл

@ -0,0 +1,47 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS runtime exception classes.
*/
#ifndef jsexn_h___
#define jsexn_h___
PR_BEGIN_EXTERN_C
/*
* Initialize exception object hierarchy.
*/
extern JSObject *
js_InitExceptionClasses(JSContext *cx, JSObject *obj);
/*
* Given a JSErrorReport, check to see if there is an exception associated
* with the error number. If there is, then create an appropriate exception
* object, set it as the pending exception, and set the JSREPORT_EXCEPTION
* flag on the error report. Exception-aware host error reporters will
* know to ignore error reports so flagged. Returns JS_TRUE if an associated
* exception is found, JS_FALSE if none.
*/
extern JSBool
js_ErrorToException(JSContext *cx, JSErrorReport *reportp);
PR_END_EXTERN_C
#endif /* jsexn_h___ */

Просмотреть файл

@ -891,7 +891,7 @@ fun_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
_readonly: _readonly:
if (JSVERSION_IS_ECMA(cx->version)) if (JSVERSION_IS_ECMA(cx->version))
return fun_getProperty(cx, obj, id, vp); return fun_getProperty(cx, obj, id, vp);
JS_ReportError(cx, "%s is read-only", js_arguments_str); JS_ReportErrorNumber(cx, NULL, JSMSG_READ_ONLY, js_arguments_str);
return JS_FALSE; return JS_FALSE;
} }
@ -1130,21 +1130,36 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
#if JS_HAS_INSTANCEOF #if JS_HAS_INSTANCEOF
/*
* [[HasInstance]] internal method for Function objects - takes the .prototype
* property of its target, and walks the prototype chain of v (if v is an
* object,) returning true if .prototype is found.
*/
static JSBool static JSBool
fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
{ {
jsval pval; jsval pval;
JSString *str;
if (!OBJ_GET_PROPERTY(cx, obj, if (!OBJ_GET_PROPERTY(cx, obj,
(jsid)cx->runtime->atomState.classPrototypeAtom, (jsid)cx->runtime->atomState.classPrototypeAtom,
&pval)) { &pval)) {
return JS_FALSE; return JS_FALSE;
} }
if (JSVAL_IS_PRIMITIVE(pval)) { if (!JSVAL_IS_PRIMITIVE(pval))
*bp = JS_FALSE; return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
return JS_TRUE;
/*
* Throw a runtime error if instanceof is called on a function
* that has a non-Object as its .prototype value.
*/
str = js_DecompileValueGenerator(cx, OBJECT_TO_JSVAL(obj), NULL);
if (str) {
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_PROTOTYPE,
JS_GetStringBytes(str));
} }
return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp); return JS_FALSE;
} }
#else /* !JS_HAS_INSTANCEOF */ #else /* !JS_HAS_INSTANCEOF */
@ -1446,7 +1461,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
* TOK_ERROR. * TOK_ERROR.
*/ */
if (tt != TOK_NAME) { if (tt != TOK_NAME) {
JS_ReportError(cx, "missing formal parameter"); JS_ReportErrorNumber(cx, NULL, JSMSG_NO_FORMAL);
goto badargs; goto badargs;
} }
/* Get the atom corresponding to the name from the tokenstream; /* Get the atom corresponding to the name from the tokenstream;
@ -1461,8 +1476,8 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#ifdef CHECK_ARGUMENT_HIDING #ifdef CHECK_ARGUMENT_HIDING
PR_ASSERT(sprop->getter == js_GetArgument); PR_ASSERT(sprop->getter == js_GetArgument);
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
JS_ReportError(cx, "duplicate formal argument %s", JS_ReportErrorNumber(cx, NULL, JSMSG_SAME_FORMAL,
ATOM_BYTES(atom)); ATOM_BYTES(atom));
goto badargs; goto badargs;
#else #else
/* A duplicate parameter name. We create a dummy symbol /* A duplicate parameter name. We create a dummy symbol
@ -1714,7 +1729,7 @@ js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing)
if (fp) if (fp)
fp->sp = sp; fp->sp = sp;
if (str) { if (str) {
JS_ReportError(cx, "%s is not a %s", JS_ReportErrorNumber(cx, NULL, JSMSG_DENY,
JS_GetStringBytes(str), JS_GetStringBytes(str),
constructing ? "constructor" : "function"); constructing ? "constructor" : "function");
} }

Просмотреть файл

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

Просмотреть файл

@ -583,8 +583,18 @@ gc_root_marker(PRHashEntry *he, intN i, void *arg)
{ {
void **rp = (void **)he->key; void **rp = (void **)he->key;
if (*rp) if (*rp) {
#ifdef DEBUG
PRArena *a;
JSRuntime *rt = (JSRuntime *)arg;
for (a = rt->gcArenaPool.first.next; a; a = a->next) {
PR_ASSERT(!rp ||
(*rp >= (void *)a->base && *rp <= (void *)a->avail));
}
#endif
GC_MARK(arg, *rp, he->value ? he->value : "root", NULL); GC_MARK(arg, *rp, he->value ? he->value : "root", NULL);
}
return HT_ENUMERATE_NEXT; return HT_ENUMERATE_NEXT;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

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

198
js/ref/jsmsg.def Normal file
Просмотреть файл

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

Просмотреть файл

@ -212,7 +212,9 @@ num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!js_ValueToECMAInt32(cx, argv[0], &base)) if (!js_ValueToECMAInt32(cx, argv[0], &base))
return JS_FALSE; return JS_FALSE;
if (base < 2 || base > 36) { if (base < 2 || base > 36) {
JS_ReportError(cx, "illegal radix %d", base); char numBuf[12];
sprintf(numBuf, "%d", base);
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_RADIX, numBuf);
return JS_FALSE; return JS_FALSE;
} }
if (base != 10 && JSDOUBLE_IS_FINITE(d)) { if (base != 10 && JSDOUBLE_IS_FINITE(d)) {
@ -473,8 +475,9 @@ js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
str = js_DecompileValueGenerator(cx, v, NULL); str = js_DecompileValueGenerator(cx, v, NULL);
badstr: badstr:
if (str) { if (str) {
JS_ReportError(cx, "%s is not a number", JS_ReportErrorNumber(cx, NULL, JSMSG_NAN,
JS_GetStringBytes(str)); JS_GetStringBytes(str));
} }
return JS_FALSE; return JS_FALSE;
#else #else
@ -557,8 +560,9 @@ js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) { if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
str = js_DecompileValueGenerator(cx, v, NULL); str = js_DecompileValueGenerator(cx, v, NULL);
if (str) { if (str) {
JS_ReportError(cx, "can't convert %s to an integer", JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_CONVERT,
JS_GetStringBytes(str)); JS_GetStringBytes(str));
} }
return JS_FALSE; return JS_FALSE;
} }

Просмотреть файл

@ -138,7 +138,7 @@ obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
slot = JSVAL_TO_INT(id); slot = JSVAL_TO_INT(id);
while (obj2) { while (obj2) {
if (obj2 == obj) { if (obj2 == obj) {
JS_ReportError(cx, "cyclic %s value", object_props[slot].name); JS_ReportErrorNumber(cx, NULL, JSMSG_CYCLIC_VALUE, object_props[slot].name);
return JS_FALSE; return JS_FALSE;
} }
obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot)); obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot));
@ -1806,7 +1806,7 @@ _readonly:
return JS_TRUE; return JS_TRUE;
str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL); str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL);
if (str) if (str)
JS_ReportError(cx, "%s is read-only", JS_GetStringBytes(str)); JS_ReportErrorNumber(cx, NULL, JSMSG_READ_ONLY, JS_GetStringBytes(str));
return JS_FALSE; return JS_FALSE;
} }
@ -1942,7 +1942,7 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
} }
str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL); str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL);
if (str) if (str)
JS_ReportError(cx, "%s is permanent", JS_GetStringBytes(str)); JS_ReportErrorNumber(cx, NULL, JSMSG_PERMANENT, JS_GetStringBytes(str));
return JS_FALSE; return JS_FALSE;
} }
@ -2056,7 +2056,7 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
*vp = OBJECT_TO_JSVAL(obj); *vp = OBJECT_TO_JSVAL(obj);
str = js_DecompileValueGenerator(cx, v, str); str = js_DecompileValueGenerator(cx, v, str);
if (str) { if (str) {
JS_ReportError(cx, "can't convert %s to %s", JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_CONVERT_TO,
JS_GetStringBytes(str), JS_GetStringBytes(str),
(hint == JSTYPE_VOID) (hint == JSTYPE_VOID)
? "primitive type" ? "primitive type"
@ -2388,7 +2388,7 @@ js_ValueToNonNullObject(JSContext *cx, jsval v)
if (!obj) { if (!obj) {
str = js_DecompileValueGenerator(cx, v, NULL); str = js_DecompileValueGenerator(cx, v, NULL);
if (str) { if (str) {
JS_ReportError(cx, "%s has no properties", JS_ReportErrorNumber(cx, NULL, JSMSG_NO_PROPERTIES,
JS_GetStringBytes(str)); JS_GetStringBytes(str));
} }
} }
@ -2474,7 +2474,9 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
} else { } else {
clasp = JS_FindClassById(xdr, classId); clasp = JS_FindClassById(xdr, classId);
if (!clasp) { if (!clasp) {
JS_ReportError(cx, "can't find class id %ld", (long)classId); char numBuf[12];
sprintf(numBuf, "%d", (long)classId);
JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_FIND_CLASS, numBuf);
ok = JS_FALSE; ok = JS_FALSE;
goto out; goto out;
} }
@ -2482,7 +2484,7 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
} }
if (!clasp->xdrObject) { if (!clasp->xdrObject) {
JS_ReportError(cx, "can't XDR class %s", clasp->name); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_XDR_CLASS, clasp->name);
ok = JS_FALSE; ok = JS_FALSE;
} else { } else {
ok = clasp->xdrObject(xdr, objp); ok = clasp->xdrObject(xdr, objp);

Просмотреть файл

@ -111,7 +111,11 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
op = (JSOp)*pc; op = (JSOp)*pc;
if (op >= JSOP_LIMIT) { if (op >= JSOP_LIMIT) {
JS_ReportError(cx, "bytecode %d too large (limit %d)", op, JSOP_LIMIT); char numBuf1[12];
char numBuf2[12];
sprintf(numBuf1, "%d", op);
sprintf(numBuf2, "%d", JSOP_LIMIT);
JS_ReportErrorNumber(cx, NULL, JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
return 0; return 0;
} }
cs = &js_CodeSpec[op]; cs = &js_CodeSpec[op];
@ -221,9 +225,12 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
fprintf(fp, " %u", GET_VARNO(pc)); fprintf(fp, " %u", GET_VARNO(pc));
break; break;
default: default: {
JS_ReportError(cx, "unknown bytecode format %x", cs->format); char numBuf[12];
sprintf(numBuf, "%x", cs->format);
JS_ReportErrorNumber(cx, NULL, JSMSG_UNKNOWN_FORMAT, numBuf);
return 0; return 0;
}
} }
fputs("\n", fp); fputs("\n", fp);
return len; return len;
@ -836,7 +843,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
len = js_GetSrcNoteOffset(sn, 0); len = js_GetSrcNoteOffset(sn, 0);
pc += 4; /* initprop, enterwith */ pc += 4; /* initprop, enterwith */
if (len) { if (len) {
js_printf(jp, " if "); js_printf(jp, " : ");
DECOMPILE_CODE(pc, len - 3); /* don't decompile ifeq */ DECOMPILE_CODE(pc, len - 3); /* don't decompile ifeq */
js_printf(jp, "%s", POP_STR()); js_printf(jp, "%s", POP_STR());
pc += len; pc += len;
@ -879,8 +886,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
todo = Sprint(&ss->sprinter, ""); todo = Sprint(&ss->sprinter, "");
break; break;
case JSOP_JSR: case JSOP_GOSUB:
case JSOP_RETSUB: case JSOP_RETSUB:
case JSOP_SETSP:
todo = -2; todo = -2;
break; break;

Просмотреть файл

@ -194,9 +194,10 @@ OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE)
/* debugger op */ /* debugger op */
OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE) OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE)
/* jsr/return for finally handling */ /* gosub/retsub for finally handling */
OPDEF(JSOP_JSR, 114,"jsr", NULL, 3, 0, 1, 0, JOF_JUMP) OPDEF(JSOP_GOSUB, 114,"gosub", NULL, 3, 0, 1, 0, JOF_JUMP)
OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE) OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE)
/* more exception handling ops */ /* more exception handling ops */
OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE) OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE)
OPDEF(JSOP_SETSP, 117,"setsp", NULL, 3, 0, 0, 0, JOF_UINT16)

Просмотреть файл

@ -97,16 +97,18 @@ static JSParser PrimaryExpr;
* Insist that the next token be of type tt, or report err and throw or fail. * Insist that the next token be of type tt, or report err and throw or fail.
* NB: this macro uses cx and ts from its lexical environment. * NB: this macro uses cx and ts from its lexical environment.
*/ */
#define MUST_MATCH_TOKEN_THROW(tt, err, throw) \
#define MUST_MATCH_TOKEN_THROW(tt, errNo, throw) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
if (js_GetToken(cx, ts) != tt) { \ if (js_GetToken(cx, ts) != tt) { \
js_ReportCompileError(cx, ts, err); \ js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR, errNo); \
throw; \ throw; \
} \ } \
PR_END_MACRO PR_END_MACRO
#define MUST_MATCH_TOKEN(tt, err) \ #define MUST_MATCH_TOKEN(tt, errNo) \
MUST_MATCH_TOKEN_THROW(tt, err, return NULL) MUST_MATCH_TOKEN_THROW(tt, errNo, return NULL)
/* /*
* Allocate a JSParseNode from cx's temporary arena. * Allocate a JSParseNode from cx's temporary arena.
@ -160,10 +162,17 @@ WellTerminated(JSContext *cx, JSTokenStream *ts, JSTokenType lastExprType)
#if JS_HAS_LEXICAL_CLOSURE #if JS_HAS_LEXICAL_CLOSURE
if ((tt == TOK_FUNCTION || lastExprType == TOK_FUNCTION) && if ((tt == TOK_FUNCTION || lastExprType == TOK_FUNCTION) &&
cx->version < JSVERSION_1_2) { cx->version < JSVERSION_1_2) {
/*
* Checking against version < 1.2 and version >= 1.0
* in the above line breaks old javascript, so we keep it
* this way for now... XXX warning needed?
*/
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
js_ReportCompileError(cx, ts, "missing ; before statement"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_SEMI_BEFORE_STMNT);
return JS_FALSE; return JS_FALSE;
} }
return JS_TRUE; return JS_TRUE;
@ -254,7 +263,7 @@ out:
static JSBool static JSBool
CheckFinalReturn(JSParseNode *pn) CheckFinalReturn(JSParseNode *pn)
{ {
JSBool ok; JSBool ok, hasDefault;
JSParseNode *pn2, *pn3; JSParseNode *pn2, *pn3;
switch (pn->pn_type) { switch (pn->pn_type) {
@ -266,16 +275,21 @@ CheckFinalReturn(JSParseNode *pn)
ok = CheckFinalReturn(pn->pn_kid2); ok = CheckFinalReturn(pn->pn_kid2);
ok &= pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3); ok &= pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3);
return ok; return ok;
#if JS_HAS_SWITCH_STATEMENT
case TOK_SWITCH: case TOK_SWITCH:
/* If a final switch has no default case, we judge it harshly. */ ok = JS_TRUE;
ok = pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3);
for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) { for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) {
if (pn2->pn_type == TOK_DEFAULT)
hasDefault = JS_TRUE;
pn3 = pn2->pn_right; pn3 = pn2->pn_right;
PR_ASSERT(pn3->pn_type == TOK_LC); PR_ASSERT(pn3->pn_type == TOK_LC);
if (pn3->pn_head) if (pn3->pn_head)
ok &= CheckFinalReturn(PN_LAST(pn3)); ok &= CheckFinalReturn(PN_LAST(pn3));
} }
/* If a final switch has no default case, we judge it harshly. */
ok &= hasDefault;
return ok; return ok;
#endif /* JS_HAS_SWITCH_STATEMENT */
case TOK_WITH: case TOK_WITH:
return CheckFinalReturn(pn->pn_right); return CheckFinalReturn(pn->pn_right);
case TOK_RETURN: case TOK_RETURN:
@ -285,8 +299,6 @@ CheckFinalReturn(JSParseNode *pn)
} }
} }
static char badreturn_str[] = "function does not always return a value";
#endif /* CHECK_RETURN_EXPR */ #endif /* CHECK_RETURN_EXPR */
static JSParseNode * static JSParseNode *
@ -314,7 +326,8 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
/* Check for falling off the end of a function that returns a value. */ /* Check for falling off the end of a function that returns a value. */
if (pn && (tc->flags & TCF_RETURN_EXPR)) { if (pn && (tc->flags & TCF_RETURN_EXPR)) {
if (!CheckFinalReturn(pn)) { if (!CheckFinalReturn(pn)) {
js_ReportCompileError(cx, ts, badreturn_str); js_ReportCompileErrorNumber(cx, ts,
JSREPORT_ERROR, JSMSG_NO_RETURN_VALUE);
pn = NULL; pn = NULL;
} }
} }
@ -417,12 +430,12 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
} }
/* Now parse formal argument list and compute fun->nargs. */ /* Now parse formal argument list and compute fun->nargs. */
MUST_MATCH_TOKEN_THROW(TOK_LP, "missing ( before formal parameters", MUST_MATCH_TOKEN_THROW(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL,
ok = JS_FALSE; goto out); ok = JS_FALSE; goto out);
/* balance) */ /* balance) */
if (!js_MatchToken(cx, ts, TOK_RP)) { if (!js_MatchToken(cx, ts, TOK_RP)) {
do { do {
MUST_MATCH_TOKEN_THROW(TOK_NAME, "missing formal parameter", MUST_MATCH_TOKEN_THROW(TOK_NAME, JSMSG_MISSING_FORMAL,
ok = JS_FALSE; goto out); ok = JS_FALSE; goto out);
argAtom = ts->token.t_atom; argAtom = ts->token.t_atom;
pobj = NULL; pobj = NULL;
@ -434,8 +447,8 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (sprop->getter == js_GetArgument) { if (sprop->getter == js_GetArgument) {
#ifdef CHECK_ARGUMENT_HIDING #ifdef CHECK_ARGUMENT_HIDING
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
js_ReportCompileError(cx, ts, js_ReportCompileErrorNumber(cx, ts,JSREPORT_ERROR,
"duplicate formal argument %s", JSMSG_DUPLICATE_FORMAL,
ATOM_BYTES(argAtom)); ATOM_BYTES(argAtom));
ok = JS_FALSE; ok = JS_FALSE;
goto out; goto out;
@ -476,11 +489,11 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
} while (js_MatchToken(cx, ts, TOK_COMMA)); } while (js_MatchToken(cx, ts, TOK_COMMA));
/* (balance: */ /* (balance: */
MUST_MATCH_TOKEN_THROW(TOK_RP, "missing ) after formal parameters", MUST_MATCH_TOKEN_THROW(TOK_RP, JSMSG_PAREN_AFTER_FORMAL,
ok = JS_FALSE; goto out); ok = JS_FALSE; goto out);
} }
MUST_MATCH_TOKEN_THROW(TOK_LC, "missing { before function body", MUST_MATCH_TOKEN_THROW(TOK_LC, JSMSG_CURLY_BEFORE_BODY,
ok = JS_FALSE; goto out); ok = JS_FALSE; goto out);
pn->pn_pos.begin = ts->token.pos.begin; pn->pn_pos.begin = ts->token.pos.begin;
@ -491,7 +504,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
goto out; goto out;
} }
MUST_MATCH_TOKEN_THROW(TOK_RC, "missing } after function body", MUST_MATCH_TOKEN_THROW(TOK_RC, JSMSG_CURLY_AFTER_BODY,
ok = JS_FALSE; goto out); ok = JS_FALSE; goto out);
pn->pn_pos.end = ts->token.pos.end; pn->pn_pos.end = ts->token.pos.end;
@ -576,22 +589,23 @@ Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
{ {
JSParseNode *pn, *pn2; JSParseNode *pn, *pn2;
MUST_MATCH_TOKEN(TOK_LP, "missing ( before condition"); MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);
pn = Expr(cx, ts, tc); pn = Expr(cx, ts, tc);
if (!pn) if (!pn)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_RP, "missing ) after condition"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);
/* /*
* Check for (a = b) and "correct" it to (a == b). * Check for (a = b) and "correct" it to (a == b).
* XXX not ECMA, but documented in several books -- need a compile option * XXX not ECMA, but documented in several books -- need a compile option
*/ */
if (pn->pn_type == TOK_ASSIGN && pn->pn_op == JSOP_NOP) { if (pn->pn_type == TOK_ASSIGN && pn->pn_op == JSOP_NOP) {
#ifdef CHECK_EQUALITY_ASSIGNMENT js_ReportCompileErrorNumber(cx, ts,JSREPORT_WARNING,
js_ReportCompileError(cx, ts, JSMSG_EQUAL_AS_ASSIGN,
"test for equality (==) mistyped as assignment (=)?\n" (JSVERSION_IS_ECMA(cx->version) ? "" :
"Assuming equality test"); "\nAssuming equality test"));
#endif if (JSVERSION_IS_ECMA(cx->version))
goto no_rewrite;
pn->pn_type = TOK_EQOP; pn->pn_type = TOK_EQOP;
pn->pn_op = cx->jsop_eq; pn->pn_op = cx->jsop_eq;
pn2 = pn->pn_left; pn2 = pn->pn_left;
@ -615,6 +629,7 @@ Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
PR_ASSERT(0); PR_ASSERT(0);
} }
} }
no_rewrite:
return pn; return pn;
} }
@ -650,7 +665,7 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSParseNode *pn, *pn2, *pn3; JSParseNode *pn, *pn2, *pn3;
JSTokenType tt; JSTokenType tt;
MUST_MATCH_TOKEN(TOK_NAME, "missing name in import statement"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
pn = NewParseNode(cx, &ts->token, PN_NULLARY); pn = NewParseNode(cx, &ts->token, PN_NULLARY);
if (!pn) if (!pn)
return NULL; return NULL;
@ -673,7 +688,7 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn2->pn_op = JSOP_IMPORTALL; pn2->pn_op = JSOP_IMPORTALL;
pn2->pn_atom = NULL; pn2->pn_atom = NULL;
} else { } else {
MUST_MATCH_TOKEN(TOK_NAME, "missing name after . operator"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
pn2->pn_op = JSOP_GETPROP; pn2->pn_op = JSOP_GETPROP;
pn2->pn_atom = ts->token.t_atom; pn2->pn_atom = ts->token.t_atom;
pn2->pn_slot = -1; pn2->pn_slot = -1;
@ -690,7 +705,7 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
/* [balance: */ /* [balance: */
MUST_MATCH_TOKEN(TOK_RB, "missing ] in index expression"); MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
pn2->pn_pos.begin = pn->pn_pos.begin; pn2->pn_pos.begin = pn->pn_pos.begin;
pn2->pn_pos.end = ts->token.pos.end; pn2->pn_pos.end = ts->token.pos.end;
@ -731,7 +746,8 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return pn; return pn;
bad_import: bad_import:
js_ReportCompileError(cx, ts, "invalid import expression"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_IMPORT);
return NULL; return NULL;
} }
#endif /* JS_HAS_EXPORT_IMPORT */ #endif /* JS_HAS_EXPORT_IMPORT */
@ -762,7 +778,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
PN_APPEND(pn, pn2); PN_APPEND(pn, pn2);
} else { } else {
do { do {
MUST_MATCH_TOKEN(TOK_NAME, "missing name in export statement"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);
pn2 = NewParseNode(cx, &ts->token, PN_NULLARY); pn2 = NewParseNode(cx, &ts->token, PN_NULLARY);
if (!pn2) if (!pn2)
return NULL; return NULL;
@ -831,30 +847,28 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
{ {
uintN newlines; uintN newlines;
JSParseNode *pn5, *pn6; JSParseNode *pn5, *pn6;
JSBool seenDefault = JS_FALSE;
pn = NewParseNode(cx, &ts->token, PN_TERNARY); pn = NewParseNode(cx, &ts->token, PN_BINARY);
if (!pn) if (!pn)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_LP, "missing ( before switch expression"); MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
/* pn1 points to the switch's discriminant. */ /* pn1 points to the switch's discriminant. */
pn1 = Expr(cx, ts, tc); pn1 = Expr(cx, ts, tc);
if (!pn1) if (!pn1)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_RP, "missing ) after switch expression"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
MUST_MATCH_TOKEN(TOK_LC, "missing { before switch body"); MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
/* balance} */ /* balance} */
/* pn2 is a list of case nodes, not including the default case. */ /* pn2 is a list of case nodes. The default case has pn_left == NULL */
pn2 = NewParseNode(cx, &ts->token, PN_LIST); pn2 = NewParseNode(cx, &ts->token, PN_LIST);
if (!pn2) if (!pn2)
return NULL; return NULL;
PN_INIT_LIST(pn2); PN_INIT_LIST(pn2);
/* If not null, pn3 points to the default case's node. */
pn3 = NULL;
js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1); js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
newlines = ts->flags & TSF_NEWLINES; newlines = ts->flags & TSF_NEWLINES;
if (newlines) if (newlines)
@ -862,37 +876,43 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
while ((tt = js_GetToken(cx, ts)) != TOK_RC) { while ((tt = js_GetToken(cx, ts)) != TOK_RC) {
switch (tt) { switch (tt) {
case TOK_DEFAULT:
if (seenDefault) {
js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_TOO_MANY_DEFAULTS);
goto bad_switch;
}
seenDefault = JS_TRUE;
/* fall through */
case TOK_CASE: case TOK_CASE:
pn4 = NewParseNode(cx, &ts->token, PN_BINARY); pn4 = NewParseNode(cx, &ts->token, PN_BINARY);
if (!pn4) if (!pn4)
goto bad_switch; goto bad_switch;
pn4->pn_left = Expr(cx, ts, tc); if (tt == TOK_DEFAULT) {
if (!pn4->pn_left) pn4->pn_left = NULL;
} else {
pn4->pn_left = Expr(cx, ts, tc);
if (!pn4->pn_left)
goto bad_switch;
}
PN_APPEND(pn2, pn4);
if (pn2->pn_count == PR_BIT(16)) {
js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_TOO_MANY_CASES);
goto bad_switch; goto bad_switch;
PN_APPEND(pn2, pn4); }
if (pn2->pn_count == PR_BIT(16)) { break;
js_ReportCompileError(cx, ts, "too many switch cases");
goto bad_switch;
}
break;
case TOK_DEFAULT:
if (pn3) {
js_ReportCompileError(cx, ts,
"more than one switch default");
goto bad_switch;
}
pn4 = NULL;
break;
case TOK_ERROR: case TOK_ERROR:
goto bad_switch; goto bad_switch;
default: default:
js_ReportCompileError(cx, ts, "invalid switch statement"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_SWITCH);
goto bad_switch; goto bad_switch;
} }
MUST_MATCH_TOKEN(TOK_COLON, "missing : after case label"); MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
pn5 = NewParseNode(cx, &ts->token, PN_LIST); pn5 = NewParseNode(cx, &ts->token, PN_LIST);
if (!pn5) if (!pn5)
@ -909,12 +929,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn5->pn_pos.end = pn6->pn_pos.end; pn5->pn_pos.end = pn6->pn_pos.end;
PN_APPEND(pn5, pn6); PN_APPEND(pn5, pn6);
} }
if (pn4) { pn4->pn_pos.end = pn5->pn_pos.end;
pn4->pn_pos.end = pn5->pn_pos.end; pn4->pn_right = pn5;
pn4->pn_right = pn5;
} else {
pn3 = pn5;
}
} }
if (newlines) if (newlines)
@ -924,7 +940,6 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn->pn_pos.end = pn2->pn_pos.end = ts->token.pos.end; pn->pn_pos.end = pn2->pn_pos.end = ts->token.pos.end;
pn->pn_kid1 = pn1; pn->pn_kid1 = pn1;
pn->pn_kid2 = pn2; pn->pn_kid2 = pn2;
pn->pn_kid3 = pn3;
return pn; return pn;
bad_switch: bad_switch:
@ -961,7 +976,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (!pn2) if (!pn2)
return NULL; return NULL;
pn->pn_left = pn2; pn->pn_left = pn2;
MUST_MATCH_TOKEN(TOK_WHILE, "missing while after do-loop body"); MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
pn2 = Condition(cx, ts, tc); pn2 = Condition(cx, ts, tc);
if (!pn2) if (!pn2)
return NULL; return NULL;
@ -978,7 +993,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1); js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
MUST_MATCH_TOKEN(TOK_LP, "missing ( after for"); /* balance) */ MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR); /* balance) */
tt = js_PeekToken(cx, ts); tt = js_PeekToken(cx, ts);
if (tt == TOK_SEMI) { if (tt == TOK_SEMI) {
/* No initializer -- set first kid of left sub-node to null. */ /* No initializer -- set first kid of left sub-node to null. */
@ -1024,7 +1039,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn1->pn_type != TOK_NAME && pn1->pn_type != TOK_NAME &&
pn1->pn_type != TOK_DOT && pn1->pn_type != TOK_DOT &&
pn1->pn_type != TOK_LB) { pn1->pn_type != TOK_LB) {
js_ReportCompileError(cx, ts, "invalid for/in left-hand side"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_FOR_LEFTSIDE);
return NULL; return NULL;
} }
@ -1035,7 +1051,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn->pn_left = pn2; pn->pn_left = pn2;
} else { } else {
/* Parse the loop condition or null into pn2. */ /* Parse the loop condition or null into pn2. */
MUST_MATCH_TOKEN(TOK_SEMI, "missing ; after for-loop initializer"); MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);
if (js_PeekToken(cx, ts) == TOK_SEMI) { if (js_PeekToken(cx, ts) == TOK_SEMI) {
pn2 = NULL; pn2 = NULL;
} else { } else {
@ -1045,7 +1061,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} }
/* Parse the update expression or null into pn3. */ /* Parse the update expression or null into pn3. */
MUST_MATCH_TOKEN(TOK_SEMI, "missing ; after for-loop condition"); MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);
if (js_PeekToken(cx, ts) == TOK_RP) { if (js_PeekToken(cx, ts) == TOK_RP) {
pn3 = NULL; pn3 = NULL;
} else { } else {
@ -1066,7 +1082,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} }
/* (balance: */ /* (balance: */
MUST_MATCH_TOKEN(TOK_RP, "missing ) after for-loop control"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
/* Parse the loop body into pn->pn_right. */ /* Parse the loop body into pn->pn_right. */
pn2 = Statement(cx, ts, tc); pn2 = Statement(cx, ts, tc);
@ -1103,13 +1119,13 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = NewParseNode(cx, &ts->token, PN_TERNARY); pn = NewParseNode(cx, &ts->token, PN_TERNARY);
pn->pn_op = JSOP_NOP; pn->pn_op = JSOP_NOP;
MUST_MATCH_TOKEN(TOK_LC, "missing { after before try block"); MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
/* } balance */ /* } balance */
pn->pn_kid1 = Statements(cx, ts, tc); pn->pn_kid1 = Statements(cx, ts, tc);
if (!pn->pn_kid1) if (!pn->pn_kid1)
return NULL; return NULL;
/* { balance */ /* { balance */
MUST_MATCH_TOKEN(TOK_RC, "missing } after try block"); MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
pn->pn_kid2 = NULL; pn->pn_kid2 = NULL;
catchtail = pn; catchtail = pn;
@ -1121,8 +1137,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
*/ */
if (!catchtail->pn_kid1->pn_expr) { if (!catchtail->pn_kid1->pn_expr) {
js_ReportCompileError(cx, ts, js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING,
"catch clause after general catch"); JSMSG_CATCH_AFTER_GENERAL);
return NULL; return NULL;
} }
@ -1139,8 +1155,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
(void)js_GetToken(cx, ts); /* eat `catch' */ (void)js_GetToken(cx, ts); /* eat `catch' */
MUST_MATCH_TOKEN(TOK_LP, "missing ( after catch"); /* balance) */ MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH); /* balance) */
MUST_MATCH_TOKEN(TOK_NAME, "missing identifier in catch"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER);
pn3->pn_atom = ts->token.t_atom; pn3->pn_atom = ts->token.t_atom;
if (js_PeekToken(cx, ts) == TOK_COLON) { if (js_PeekToken(cx, ts) == TOK_COLON) {
(void)js_GetToken(cx, ts); /* eat `:' */ (void)js_GetToken(cx, ts); /* eat `:' */
@ -1153,30 +1169,31 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn2->pn_kid1 = pn3; pn2->pn_kid1 = pn3;
/* ( balance: */ /* ( balance: */
MUST_MATCH_TOKEN(TOK_RP, "missing ) after catch"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
MUST_MATCH_TOKEN(TOK_LC, "missing { before catch block"); MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
pn2->pn_kid3 = Statements(cx, ts, tc); pn2->pn_kid3 = Statements(cx, ts, tc);
if (!pn2->pn_kid3) if (!pn2->pn_kid3)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_RC, "missing } after catch block"); MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
catchtail = catchtail->pn_kid2 = pn2; catchtail = catchtail->pn_kid2 = pn2;
} }
catchtail->pn_kid2 = NULL; catchtail->pn_kid2 = NULL;
if (js_MatchToken(cx, ts, TOK_FINALLY)) { if (js_MatchToken(cx, ts, TOK_FINALLY)) {
MUST_MATCH_TOKEN(TOK_LC, "missing { before finally block"); tc->tryCount++;
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
pn->pn_kid3 = Statements(cx, ts, tc); pn->pn_kid3 = Statements(cx, ts, tc);
if (!pn->pn_kid3) if (!pn->pn_kid3)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_RC, "missing } after finally block"); MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
} else { } else {
pn->pn_kid3 = NULL; pn->pn_kid3 = NULL;
} }
if (!pn->pn_kid2 && !pn->pn_kid3) { if (!pn->pn_kid2 && !pn->pn_kid3) {
js_ReportCompileError(cx, ts, js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
"missing catch or finally after try"); JSMSG_CATCH_OR_FINALLY);
return NULL; return NULL;
} }
tc->tryCount++; tc->tryCount++;
@ -1200,11 +1217,13 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
/* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */ /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
case TOK_CATCH: case TOK_CATCH:
js_ReportCompileError(cx, ts, "catch without try"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_CATCH_WITHOUT_TRY);
return NULL; return NULL;
case TOK_FINALLY: case TOK_FINALLY:
js_ReportCompileError(cx, ts, "finally without try"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_FINALLY_WITHOUT_TRY);
return NULL; return NULL;
#endif /* JS_HAS_EXCEPTIONS */ #endif /* JS_HAS_EXCEPTIONS */
@ -1220,7 +1239,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (label) { if (label) {
for (; ; stmt = stmt->down) { for (; ; stmt = stmt->down) {
if (!stmt) { if (!stmt) {
js_ReportCompileError(cx, ts, "label not found"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_LABEL_NOT_FOUND);
return NULL; return NULL;
} }
if (stmt->type == STMT_LABEL && stmt->label == label) if (stmt->type == STMT_LABEL && stmt->label == label)
@ -1229,7 +1249,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} else { } else {
for (; ; stmt = stmt->down) { for (; ; stmt = stmt->down) {
if (!stmt) { if (!stmt) {
js_ReportCompileError(cx, ts, "invalid break"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_TOUGH_BREAK);
return NULL; return NULL;
} }
if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH) if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)
@ -1251,13 +1272,15 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (label) { if (label) {
for (stmt2 = NULL; ; stmt = stmt->down) { for (stmt2 = NULL; ; stmt = stmt->down) {
if (!stmt) { if (!stmt) {
js_ReportCompileError(cx, ts, "label not found"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_LABEL_NOT_FOUND);
return NULL; return NULL;
} }
if (stmt->type == STMT_LABEL) { if (stmt->type == STMT_LABEL) {
if (stmt->label == label) { if (stmt->label == label) {
if (!stmt2 || !STMT_IS_LOOP(stmt2)) { if (!stmt2 || !STMT_IS_LOOP(stmt2)) {
js_ReportCompileError(cx, ts, "invalid continue"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_CONTINUE);
return NULL; return NULL;
} }
break; break;
@ -1269,7 +1292,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} else { } else {
for (; ; stmt = stmt->down) { for (; ; stmt = stmt->down) {
if (!stmt) { if (!stmt) {
js_ReportCompileError(cx, ts, "invalid continue"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_CONTINUE);
return NULL; return NULL;
} }
if (STMT_IS_LOOP(stmt)) if (STMT_IS_LOOP(stmt))
@ -1284,13 +1308,13 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = NewParseNode(cx, &ts->token, PN_BINARY); pn = NewParseNode(cx, &ts->token, PN_BINARY);
if (!pn) if (!pn)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_LP, "missing ( before with-statement object"); MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
/* balance) */ /* balance) */
pn2 = Expr(cx, ts, tc); pn2 = Expr(cx, ts, tc);
if (!pn2) if (!pn2)
return NULL; return NULL;
/* (balance: */ /* (balance: */
MUST_MATCH_TOKEN(TOK_RP, "missing ) after with-statement object"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
pn->pn_left = pn2; pn->pn_left = pn2;
js_PushStatement(tc, &stmtInfo, STMT_WITH, -1); js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);
@ -1317,7 +1341,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_RETURN: case TOK_RETURN:
if (!(tc->flags & TCF_IN_FUNCTION)) { if (!(tc->flags & TCF_IN_FUNCTION)) {
js_ReportCompileError(cx, ts, "invalid return"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_RETURN);
return NULL; return NULL;
} }
pn = NewParseNode(cx, &ts->token, PN_UNARY); pn = NewParseNode(cx, &ts->token, PN_UNARY);
@ -1350,7 +1375,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#ifdef CHECK_RETURN_EXPR #ifdef CHECK_RETURN_EXPR
if ((tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == if ((tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) ==
(TCF_RETURN_EXPR | TCF_RETURN_VOID)) { (TCF_RETURN_EXPR | TCF_RETURN_VOID)) {
js_ReportCompileError(cx, ts, badreturn_str); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_NO_RETURN_VALUE);
return NULL; return NULL;
} }
#endif #endif
@ -1363,7 +1389,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
/* {balance: */ /* {balance: */
MUST_MATCH_TOKEN(TOK_RC, "missing } in compound statement"); MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
js_PopStatement(tc); js_PopStatement(tc);
return pn; return pn;
@ -1400,13 +1426,15 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
tt = ts->pushback.type; tt = ts->pushback.type;
if (tt == TOK_COLON) { if (tt == TOK_COLON) {
if (pn2->pn_type != TOK_NAME) { if (pn2->pn_type != TOK_NAME) {
js_ReportCompileError(cx, ts, "invalid label"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_LABEL);
return NULL; return NULL;
} }
label = pn2->pn_atom; label = pn2->pn_atom;
for (stmt = tc->topStmt; stmt; stmt = stmt->down) { for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
if (stmt->type == STMT_LABEL && stmt->label == label) { if (stmt->type == STMT_LABEL && stmt->label == label) {
js_ReportCompileError(cx, ts, "duplicate label"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_DUPLICATE_LABEL);
return NULL; return NULL;
} }
} }
@ -1494,7 +1522,7 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} }
do { do {
MUST_MATCH_TOKEN(TOK_NAME, "missing variable name"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_VARIABLE_NAME);
atom = ts->token.t_atom; atom = ts->token.t_atom;
pn2 = NewParseNode(cx, &ts->token, PN_NAME); pn2 = NewParseNode(cx, &ts->token, PN_NAME);
@ -1514,8 +1542,9 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (sprop->getter == js_GetArgument) { if (sprop->getter == js_GetArgument) {
getter = sprop->getter; getter = sprop->getter;
#ifdef CHECK_ARGUMENT_HIDING #ifdef CHECK_ARGUMENT_HIDING
js_ReportCompileError(cx, ts, "variable %s hides argument", js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
ATOM_BYTES(atom)); JSMSG_VAR_HIDES_ARG,
ATOM_BYTES(atom));
ok = JS_FALSE; ok = JS_FALSE;
#else #else
ok = JS_TRUE; ok = JS_TRUE;
@ -1593,8 +1622,8 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (js_MatchToken(cx, ts, TOK_ASSIGN)) { if (js_MatchToken(cx, ts, TOK_ASSIGN)) {
if (ts->token.t_op != JSOP_NOP) { if (ts->token.t_op != JSOP_NOP) {
js_ReportCompileError(cx, ts, js_ReportCompileErrorNumber(cx, ts,JSREPORT_ERROR,
"invalid variable initialization"); JSMSG_BAD_VAR_INIT);
ok = JS_FALSE; ok = JS_FALSE;
} else { } else {
pn2->pn_expr = AssignExpr(cx, ts, tc); pn2->pn_expr = AssignExpr(cx, ts, tc);
@ -1729,7 +1758,8 @@ AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn2->pn_op = JSOP_SETELEM; pn2->pn_op = JSOP_SETELEM;
break; break;
default: default:
js_ReportCompileError(cx, ts, "invalid assignment left-hand side"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_LEFTSIDE_OF_ASS);
return NULL; return NULL;
} }
pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc)); pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc));
@ -1767,7 +1797,7 @@ CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (!pn2) if (!pn2)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_COLON, "missing : in conditional expression"); MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
pn3 = AssignExpr(cx, ts, tc); pn3 = AssignExpr(cx, ts, tc);
if (!pn3) if (!pn3)
return NULL; return NULL;
@ -1951,7 +1981,8 @@ SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
if (kid->pn_type != TOK_NAME && if (kid->pn_type != TOK_NAME &&
kid->pn_type != TOK_DOT && kid->pn_type != TOK_DOT &&
kid->pn_type != TOK_LB) { kid->pn_type != TOK_LB) {
js_ReportCompileError(cx, ts, "invalid %s operand", name); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_OPERAND, name);
return NULL; return NULL;
} }
pn->pn_kid = kid; pn->pn_kid = kid;
@ -2108,7 +2139,7 @@ ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
} while (js_MatchToken(cx, ts, TOK_COMMA)); } while (js_MatchToken(cx, ts, TOK_COMMA));
/* (balance: */ /* (balance: */
MUST_MATCH_TOKEN(TOK_RP, "missing ) after argument list"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_ARGS);
} }
return listNode; return listNode;
} }
@ -2141,7 +2172,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
return NULL; return NULL;
} }
if (pn->pn_count - 1 >= ARGC_LIMIT) { if (pn->pn_count - 1 >= ARGC_LIMIT) {
JS_ReportError(cx, "too many constructor arguments"); JS_ReportErrorNumber(cx, NULL, JSMSG_TOO_MANY_CON_ARGS);
return NULL; return NULL;
} }
pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
@ -2156,7 +2187,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
pn2 = NewParseNode(cx, &ts->token, PN_NAME); pn2 = NewParseNode(cx, &ts->token, PN_NAME);
if (!pn2) if (!pn2)
return NULL; return NULL;
MUST_MATCH_TOKEN(TOK_NAME, "missing name after . operator"); MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
pn2->pn_pos.begin = pn->pn_pos.begin; pn2->pn_pos.begin = pn->pn_pos.begin;
pn2->pn_pos.end = ts->token.pos.end; pn2->pn_pos.end = ts->token.pos.end;
pn2->pn_op = JSOP_GETPROP; pn2->pn_op = JSOP_GETPROP;
@ -2171,7 +2202,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
return NULL; return NULL;
/* [balance: */ /* [balance: */
MUST_MATCH_TOKEN(TOK_RB, "missing ] in index expression"); MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
pn2->pn_pos.begin = pn->pn_pos.begin; pn2->pn_pos.begin = pn->pn_pos.begin;
pn2->pn_pos.end = ts->token.pos.end; pn2->pn_pos.end = ts->token.pos.end;
@ -2198,7 +2229,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (!pn2) if (!pn2)
return NULL; return NULL;
if (pn2->pn_count - 1 >= ARGC_LIMIT) { if (pn2->pn_count - 1 >= ARGC_LIMIT) {
JS_ReportError(cx, "too many function arguments"); JS_ReportErrorNumber(cx, NULL, JSMSG_TOO_MANY_FUN_ARGS);
return NULL; return NULL;
} }
pn2->pn_pos.end = PN_LAST(pn2)->pn_pos.end; pn2->pn_pos.end = PN_LAST(pn2)->pn_pos.end;
@ -2293,7 +2324,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} }
/* [balance: */ /* [balance: */
MUST_MATCH_TOKEN(TOK_RB, "missing ] after element list"); MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
} }
pn->pn_pos.end = ts->token.pos.end; pn->pn_pos.end = ts->token.pos.end;
return pn; return pn;
@ -2331,11 +2362,12 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_RC: case TOK_RC:
goto end_obj_init; goto end_obj_init;
default: default:
js_ReportCompileError(cx, ts, "invalid property id"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_PROP_ID);
return NULL; return NULL;
} }
MUST_MATCH_TOKEN(TOK_COLON, "missing : after property id"); MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_ID);
pn2 = NewBinary(cx, TOK_COLON, JSOP_INITPROP, pn3, pn2 = NewBinary(cx, TOK_COLON, JSOP_INITPROP, pn3,
AssignExpr(cx, ts, tc)); AssignExpr(cx, ts, tc));
if (!pn2) if (!pn2)
@ -2344,7 +2376,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
} while (js_MatchToken(cx, ts, TOK_COMMA)); } while (js_MatchToken(cx, ts, TOK_COMMA));
/* {balance: */ /* {balance: */
MUST_MATCH_TOKEN(TOK_RC, "missing } after property list"); MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
} }
end_obj_init: end_obj_init:
pn->pn_pos.end = ts->token.pos.end; pn->pn_pos.end = ts->token.pos.end;
@ -2397,7 +2429,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
/* (balance: */ /* (balance: */
MUST_MATCH_TOKEN(TOK_RP, "missing ) in parenthetical"); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
pn->pn_type = TOK_RP; pn->pn_type = TOK_RP;
pn->pn_pos.end = ts->token.pos.end; pn->pn_pos.end = ts->token.pos.end;
pn->pn_kid = pn2; pn->pn_kid = pn2;
@ -2450,7 +2482,8 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_IMPORT: case TOK_IMPORT:
#endif #endif
case TOK_RESERVED: case TOK_RESERVED:
js_ReportCompileError(cx, ts, "%s is a reserved identifier", js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_RESERVED_ID,
js_DeflateString(cx, ts->token.ptr, js_DeflateString(cx, ts->token.ptr,
ts->token.pos.end.index - ts->token.pos.end.index -
ts->token.pos.begin.index)); ts->token.pos.begin.index));
@ -2461,7 +2494,8 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
default: default:
js_ReportCompileError(cx, ts, "syntax error"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_SYNTAX_ERROR);
return NULL; return NULL;
} }
@ -2469,7 +2503,8 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (defsharp) { if (defsharp) {
if (notsharp) { if (notsharp) {
badsharp: badsharp:
js_ReportCompileError(cx, ts, "invalid sharp variable definition"); js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
JSMSG_BAD_SHARP_VAR_DEF);
return NULL; return NULL;
} }
defsharp->pn_kid = pn; defsharp->pn_kid = pn;
@ -2511,10 +2546,10 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn)
break; break;
case PN_BINARY: case PN_BINARY:
/* Neither kid may be null. */ /* First kid may be null (for default case in switch). */
pn1 = pn->pn_left; pn1 = pn->pn_left;
pn2 = pn->pn_right; pn2 = pn->pn_right;
if (!js_FoldConstants(cx, pn1)) if (pn1 && !js_FoldConstants(cx, pn1))
return JS_FALSE; return JS_FALSE;
if (!js_FoldConstants(cx, pn2)) if (!js_FoldConstants(cx, pn2))
return JS_FALSE; return JS_FALSE;

Просмотреть файл

@ -290,4 +290,12 @@ typedef void
(* CRT_CALL JSErrorReporter)(JSContext *cx, const char *message, (* CRT_CALL JSErrorReporter)(JSContext *cx, const char *message,
JSErrorReport *report); JSErrorReport *report);
typedef struct JSErrorFormatString {
const char *format;
const uintN argCount;
} JSErrorFormatString;
typedef const JSErrorFormatString *
(* CRT_CALL JSErrorCallBack)(const uintN errorNumber);
#endif /* jspubtd_h___ */ #endif /* jspubtd_h___ */

Просмотреть файл

@ -649,14 +649,14 @@ loop:
case '{': case '{':
c = *++cp; c = *++cp;
if (!JS7_ISDEC(c)) { if (!JS7_ISDEC(c)) {
JS_ReportError(state->context, "invalid quantifier %s", state->cp); JS_ReportErrorNumber(state->context, NULL, JSMSG_BAD_QUANTIFIER, state->cp);
return NULL; return NULL;
} }
min = (uint32)JS7_UNDEC(c); min = (uint32)JS7_UNDEC(c);
for (c = *++cp; JS7_ISDEC(c); c = *++cp) { for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
min = 10 * min + (uint32)JS7_UNDEC(c); min = 10 * min + (uint32)JS7_UNDEC(c);
if (min >> 16) { if (min >> 16) {
JS_ReportError(state->context, "overlarge minimum %s", JS_ReportErrorNumber(state->context, NULL, JSMSG_MIN_TOO_BIG,
state->cp); state->cp);
return NULL; return NULL;
} }
@ -668,7 +668,7 @@ loop:
for (c = *++cp; JS7_ISDEC(c); c = *++cp) { for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
max = 10 * max + (uint32)JS7_UNDEC(c); max = 10 * max + (uint32)JS7_UNDEC(c);
if (max >> 16) { if (max >> 16) {
JS_ReportError(state->context, "overlarge maximum %s", JS_ReportErrorNumber(state->context, NULL, JSMSG_MAX_TOO_BIG,
up); up);
return NULL; return NULL;
} }
@ -676,8 +676,8 @@ loop:
if (max == 0) if (max == 0)
goto zero_quant; goto zero_quant;
if (min > max) { if (min > max) {
JS_ReportError(state->context, JS_ReportErrorNumber(state->context, NULL,
"maximum %s less than minimum", up); JSMSG_OUT_OF_ORDER, up);
return NULL; return NULL;
} }
} else { } else {
@ -688,13 +688,14 @@ loop:
/* Exactly n times. */ /* Exactly n times. */
if (min == 0) { if (min == 0) {
zero_quant: zero_quant:
JS_ReportError(state->context, "zero quantifier %s", state->cp); JS_ReportErrorNumber(state->context, NULL, JSMSG_ZERO_QUANTIFIER,
state->cp);
return NULL; return NULL;
} }
max = min; max = min;
} }
if (*cp != '}') { if (*cp != '}') {
JS_ReportError(state->context, "unterminated quantifier %s", JS_ReportErrorNumber(state->context, NULL, JSMSG_UNTERM_QUANTIFIER,
state->cp); state->cp);
return NULL; return NULL;
} }
@ -712,8 +713,8 @@ loop:
case '*': case '*':
if (!(ren->flags & RENODE_NONEMPTY)) { if (!(ren->flags & RENODE_NONEMPTY)) {
JS_ReportError(state->context, JS_ReportErrorNumber(state->context, NULL,
"regular expression before * could be empty"); JSMSG_EMPTY_BEFORE_STAR);
return NULL; return NULL;
} }
cp++; cp++;
@ -722,8 +723,8 @@ loop:
case '+': case '+':
if (!(ren->flags & RENODE_NONEMPTY)) { if (!(ren->flags & RENODE_NONEMPTY)) {
JS_ReportError(state->context, JS_ReportErrorNumber(state->context, NULL,
"regular expression before + could be empty"); JSMSG_EMPTY_BEFORE_PLUS);
return NULL; return NULL;
} }
cp++; cp++;
@ -805,7 +806,7 @@ ParseAtom(CompilerState *state)
return NULL; return NULL;
cp = state->cp; cp = state->cp;
if (*cp != ')') { if (*cp != ')') {
JS_ReportError(state->context, "unterminated parenthetical %s", JS_ReportErrorNumber(state->context, NULL, JSMSG_MISSING_PAREN,
ocp); ocp);
return NULL; return NULL;
} }
@ -846,8 +847,8 @@ ParseAtom(CompilerState *state)
while ((c = *++cp) != ']') { while ((c = *++cp) != ']') {
if (c == 0) { if (c == 0) {
bad_cclass: bad_cclass:
JS_ReportError(state->context, JS_ReportErrorNumber(state->context, NULL,
"unterminated character class %s", ocp); JSMSG_UNTERM_CLASS, ocp);
return NULL; return NULL;
} }
if (c == '\\' && cp[1] != 0) if (c == '\\' && cp[1] != 0)
@ -863,7 +864,7 @@ ParseAtom(CompilerState *state)
c = *++cp; c = *++cp;
switch (c) { switch (c) {
case 0: case 0:
JS_ReportError(state->context, "trailing \\ in regular expression"); JS_ReportErrorNumber(state->context, NULL, JSMSG_TRAILING_SLASH);
return NULL; return NULL;
case 'f': case 'f':
@ -1834,8 +1835,8 @@ EmitRegExp(CompilerState *state, RENode *ren, JSRegExp *re)
if (inrange) { if (inrange) {
if (lastc > c) { if (lastc > c) {
JS_ReportError(state->context, JS_ReportErrorNumber(state->context, NULL,
"invalid range in character class"); JSMSG_BAD_CLASS_RANGE);
return JS_FALSE; return JS_FALSE;
} }
inrange = JS_FALSE; inrange = JS_FALSE;
@ -2032,10 +2033,12 @@ js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt)
case 'i': case 'i':
flags |= JSREG_FOLD; flags |= JSREG_FOLD;
break; break;
default: default: {
JS_ReportError(cx, "invalid regular expression flag %c", char charBuf[2] = " ";
(char) *cp); charBuf[0] = (char)*cp;
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_FLAG, charBuf);
return NULL; return NULL;
}
} }
} }
} }
@ -3184,7 +3187,7 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (argc == 0) { if (argc == 0) {
str = cx->regExpStatics.input; str = cx->regExpStatics.input;
if (!str) { if (!str) {
JS_ReportError(cx, "no input for /%s/%s%s", JS_ReportErrorNumber(cx, NULL, JSMSG_NO_INPUT,
JS_GetStringBytes(re->source), JS_GetStringBytes(re->source),
(re->flags & JSREG_GLOB) ? "g" : "", (re->flags & JSREG_GLOB) ? "g" : "",
(re->flags & JSREG_FOLD) ? "i" : ""); (re->flags & JSREG_FOLD) ? "i" : "");

Просмотреть файл

@ -225,7 +225,7 @@ js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
} else { } else {
file = fopen(filename, "r"); file = fopen(filename, "r");
if (!file) { if (!file) {
JS_ReportError(cx, "can't open %s: %s", filename, strerror(errno)); JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_OPEN, filename, strerror(errno));
return NULL; return NULL;
} }
} }
@ -483,8 +483,8 @@ MatchChar(JSTokenStream *ts, int32 nextChar)
} }
void void
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, const char *format, js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
...) const char *format, ...)
{ {
va_list ap; va_list ap;
char *message; char *message;
@ -519,11 +519,13 @@ js_ReportCompileError(JSContext *cx, JSTokenStream *ts, const char *format,
: NULL; : NULL;
report.uclinebuf = ts->linebuf.base; report.uclinebuf = ts->linebuf.base;
report.uctokenptr = ts->token.ptr; report.uctokenptr = ts->token.ptr;
report.flags = flags;
(*onError)(cx, message, &report); (*onError)(cx, message, &report);
#if !defined XP_PC || !defined _MSC_VER || _MSC_VER > 800 #if !defined XP_PC || !defined _MSC_VER || _MSC_VER > 800
} else { } else {
if (!(ts->flags & TSF_INTERACTIVE)) if (!(ts->flags & TSF_INTERACTIVE))
fprintf(stderr, "JavaScript error: "); fprintf(stderr, "JavaScript %s: ",
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
if (ts->filename) if (ts->filename)
fprintf(stderr, "%s, ", ts->filename); fprintf(stderr, "%s, ", ts->filename);
if (ts->lineno) if (ts->lineno)
@ -538,6 +540,68 @@ js_ReportCompileError(JSContext *cx, JSTokenStream *ts, const char *format,
free(message); free(message);
} }
void
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
const uintN errorNumber, ...)
{
va_list ap;
jschar *limit, lastc;
JSErrorReporter onError;
JSErrorReport report;
JSString *linestr;
char *message;
report.errorNumber = errorNumber;
report.messageArgs = NULL;
report.ucmessage = NULL;
message = NULL;
va_start(ap, errorNumber);
if (!js_ExpandErrorArguments(cx, NULL, errorNumber, &message, &report, ap))
return;
va_end(ap);
PR_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
limit = ts->linebuf.limit;
lastc = limit[-1];
if (lastc == '\n')
limit[-1] = 0;
onError = cx->errorReporter;
if (onError) {
report.filename = ts->filename;
report.lineno = ts->lineno;
linestr = js_NewStringCopyZ(cx, ts->linebuf.base, 0);
report.linebuf = linestr
? JS_GetStringBytes(linestr)
: NULL;
report.tokenptr = linestr
? report.linebuf + (ts->token.ptr - ts->linebuf.base)
: NULL;
report.uclinebuf = ts->linebuf.base;
report.uctokenptr = ts->token.ptr;
report.flags = flags;
(*onError)(cx, message, &report);
#if !defined XP_PC || !defined _MSC_VER || _MSC_VER > 800
} else {
if (!(ts->flags & TSF_INTERACTIVE))
fprintf(stderr, "JavaScript %s: ",
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
if (ts->filename)
fprintf(stderr, "%s, ", ts->filename);
if (ts->lineno)
fprintf(stderr, "line %u: ", ts->lineno);
fprintf(stderr, "%s:\n%s\n",message,
js_DeflateString(cx, ts->linebuf.base,
ts->linebuf.limit - ts->linebuf.base));
#endif
}
if (lastc == '\n')
limit[-1] = lastc;
if (message) free(message);
if (report.messageArgs) free(report.messageArgs);
}
JSTokenType JSTokenType
js_PeekToken(JSContext *cx, JSTokenStream *ts) js_PeekToken(JSContext *cx, JSTokenStream *ts)
{ {
@ -691,16 +755,20 @@ retry:
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
c = GetChar(ts); c = GetChar(ts);
radix = 16; radix = 16;
} else if (JS7_ISDEC(c) && c < '8') { } else if (JS7_ISDEC(c)) {
/* /*
* XXX Warning needed. Checking against c < '8' above is * We permit 08 and 09 as decimal numbers, which makes our
* non-ECMA, but is required to support legacy code; it's * behaviour superset of the ECMA numeric grammar. We might
* likely that "08" and "09" are in use in code having to do * not always be so permissive, so we warn about it.
* with dates. So we need to support it, which makes our */
* behavior a superset of ECMA in this area. We should be if (c > '7' && JSVERSION_IS_ECMA(cx->version)) {
* raising a warning if '8' or '9' is encountered. js_ReportCompileError(cx, ts, JSREPORT_WARNING,
*/ "0%c is not an ECMA-legal numeric constant",
radix = 8; c);
radix = 10;
} else {
radix = 8;
}
} }
} }
@ -730,7 +798,8 @@ retry:
c = GetChar(ts); c = GetChar(ts);
} }
if (!JS7_ISDEC(c)) { if (!JS7_ISDEC(c)) {
js_ReportCompileError(cx, ts, "missing exponent"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"missing exponent");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
do { do {
@ -746,12 +815,14 @@ retry:
if (radix == 10) { if (radix == 10) {
if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) { if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) {
js_ReportCompileError(cx, ts, "out of memory"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"out of memory");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
} else { } else {
if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) { if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) {
js_ReportCompileError(cx, ts, "out of memory"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"out of memory");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
} }
@ -766,7 +837,8 @@ retry:
while ((c = GetChar(ts)) != qc) { while ((c = GetChar(ts)) != qc) {
if (c == '\n' || c == EOF) { if (c == '\n' || c == EOF) {
UngetChar(ts, c); UngetChar(ts, c);
js_ReportCompileError(cx, ts, "unterminated string literal"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"unterminated string literal");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
if (c == '\\') { if (c == '\\') {
@ -955,11 +1027,13 @@ skipline:
if (c == '/' && MatchChar(ts, '*')) { if (c == '/' && MatchChar(ts, '*')) {
if (MatchChar(ts, '/')) if (MatchChar(ts, '/'))
goto retry; goto retry;
js_ReportCompileError(cx, ts, "nested comment"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"nested comment");
} }
} }
if (c == EOF) { if (c == EOF) {
js_ReportCompileError(cx, ts, "unterminated comment"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"unterminated comment");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
goto retry; goto retry;
@ -974,7 +1048,7 @@ skipline:
while ((c = GetChar(ts)) != '/') { while ((c = GetChar(ts)) != '/') {
if (c == '\n' || c == EOF) { if (c == '\n' || c == EOF) {
UngetChar(ts, c); UngetChar(ts, c);
js_ReportCompileError(cx, ts, js_ReportCompileError(cx, ts,JSREPORT_ERROR,
"unterminated regular expression literal"); "unterminated regular expression literal");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
@ -998,7 +1072,7 @@ skipline:
c = PeekChar(ts); c = PeekChar(ts);
if (JS7_ISLET(c)) { if (JS7_ISLET(c)) {
ts->token.ptr = ts->linebuf.ptr - 1; ts->token.ptr = ts->linebuf.ptr - 1;
js_ReportCompileError(cx, ts, js_ReportCompileError(cx, ts,JSREPORT_ERROR,
"invalid flag after regular expression"); "invalid flag after regular expression");
(void) GetChar(ts); (void) GetChar(ts);
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
@ -1065,7 +1139,7 @@ skipline:
break; break;
n = 10 * n + JS7_UNDEC(c); n = 10 * n + JS7_UNDEC(c);
if (n >= ATOM_INDEX_LIMIT) { if (n >= ATOM_INDEX_LIMIT) {
js_ReportCompileError(cx, ts, js_ReportCompileError(cx, ts,JSREPORT_ERROR,
"overlarge sharp variable number"); "overlarge sharp variable number");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }
@ -1082,7 +1156,8 @@ skipline:
#endif /* JS_HAS_SHARP_VARS */ #endif /* JS_HAS_SHARP_VARS */
default: default:
js_ReportCompileError(cx, ts, "illegal character"); js_ReportCompileError(cx, ts, JSREPORT_ERROR,
"illegal character");
RETURN(TOK_ERROR); RETURN(TOK_ERROR);
} }

Просмотреть файл

@ -226,9 +226,12 @@ js_MapKeywords(void (*mapfun)(const char *));
* associated with cx. * associated with cx.
*/ */
extern void extern void
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, const char *format, js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
...); const char *format, ...);
void
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
const uintN errorNumber, ...);
/* /*
* Look ahead one token and return its type. * Look ahead one token and return its type.
*/ */

Просмотреть файл

@ -109,7 +109,9 @@ str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
(mask = (jsint)d) != d || (mask = (jsint)d) != d ||
mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)) mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
{ {
JS_ReportError(cx, "invalid string escape mask %x", mask); char numBuf[12];
sprintf(numBuf, "%x", mask);
JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_STRING_MASK, numBuf);
return JS_FALSE; return JS_FALSE;
} }
} else { } else {
@ -744,8 +746,7 @@ str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
static JSBool static JSBool
str_nyi(JSContext *cx, const char *what) str_nyi(JSContext *cx, const char *what)
{ {
JS_ReportError(cx, "sorry, String.prototype.%s is not yet implemented", JS_ReportErrorNumber(cx, NULL, JSMSG_NO_STRING_PROTO, what);
what);
return JS_FALSE; return JS_FALSE;
} }
#endif #endif

Просмотреть файл

@ -21,6 +21,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "prassert.h" #include "prassert.h"
#include "jsapi.h" #include "jsapi.h"
#include "jscntxt.h"
#include "jsobj.h" /* js_XDRObject */ #include "jsobj.h" /* js_XDRObject */
#include "jsstr.h" #include "jsstr.h"
#include "jsxdrapi.h" #include "jsxdrapi.h"
@ -43,13 +44,12 @@ typedef struct JSXDRMemState {
#define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count) #define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count)
#define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit) #define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit)
static char unexpected_end_of_data_str[] = "unexpected end of data";
#define MEM_LEFT(xdr, bytes) \ #define MEM_LEFT(xdr, bytes) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
if ((xdr)->mode == JSXDR_DECODE && \ if ((xdr)->mode == JSXDR_DECODE && \
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
JS_ReportError((xdr)->cx, unexpected_end_of_data_str); \ JS_ReportErrorNumber((xdr)->cx, NULL, JSMSG_END_OF_DATA); \
return 0; \ return 0; \
} \ } \
PR_END_MACRO PR_END_MACRO
@ -70,7 +70,7 @@ static char unexpected_end_of_data_str[] = "unexpected end of data";
} \ } \
} else { \ } else { \
if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \ if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \
JS_ReportError((xdr)->cx, unexpected_end_of_data_str); \ JS_ReportErrorNumber((xdr)->cx, NULL, JSMSG_END_OF_DATA); \
return 0; \ return 0; \
} \ } \
} \ } \
@ -135,7 +135,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
switch (whence) { switch (whence) {
case JSXDR_SEEK_CUR: case JSXDR_SEEK_CUR:
if ((int32)MEM_COUNT(xdr) + offset < 0) { if ((int32)MEM_COUNT(xdr) + offset < 0) {
JS_ReportError(xdr->cx, "illegal seek beyond start"); JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_SEEK_BEYOND_START);
return JS_FALSE; return JS_FALSE;
} }
if (offset > 0) if (offset > 0)
@ -144,7 +144,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
return JS_TRUE; return JS_TRUE;
case JSXDR_SEEK_SET: case JSXDR_SEEK_SET:
if (offset < 0) { if (offset < 0) {
JS_ReportError(xdr->cx, "illegal seek beyond start"); JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_SEEK_BEYOND_START);
return JS_FALSE; return JS_FALSE;
} }
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
@ -153,7 +153,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
MEM_COUNT(xdr) = offset; MEM_COUNT(xdr) = offset;
} else { } else {
if ((uint32)offset > MEM_LIMIT(xdr)) { if ((uint32)offset > MEM_LIMIT(xdr)) {
JS_ReportError(xdr->cx, "illegal seek beyond end"); JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_SEEK_BEYOND_END);
return JS_FALSE; return JS_FALSE;
} }
MEM_COUNT(xdr) = offset; MEM_COUNT(xdr) = offset;
@ -163,13 +163,16 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
if (offset >= 0 || if (offset >= 0 ||
xdr->mode == JSXDR_ENCODE || xdr->mode == JSXDR_ENCODE ||
(int32)MEM_LIMIT(xdr) + offset < 0) { (int32)MEM_LIMIT(xdr) + offset < 0) {
JS_ReportError(xdr->cx, "illegal end-based seek"); JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_END_SEEK);
return JS_FALSE; return JS_FALSE;
} }
MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset; MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset;
return JS_TRUE; return JS_TRUE;
default: default: {
JS_ReportError(xdr->cx, "unknown seek whence: %d", whence); char numBuf[12];
sprintf(numBuf, "%d", whence);
JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_WHITHER_WHENCE, numBuf);
}
return JS_FALSE; return JS_FALSE;
} }
} }
@ -468,7 +471,8 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
if (!JS_XDRUint32(xdr, (uint32 *)vp)) if (!JS_XDRUint32(xdr, (uint32 *)vp))
return JS_FALSE; return JS_FALSE;
break; break;
default: default: {
char numBuf[12];
if (type & JSVAL_INT) { if (type & JSVAL_INT) {
uint32 i; uint32 i;
if (xdr->mode == JSXDR_ENCODE) if (xdr->mode == JSXDR_ENCODE)
@ -479,7 +483,9 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
*vp = INT_TO_JSVAL(i); *vp = INT_TO_JSVAL(i);
break; break;
} }
JS_ReportError(xdr->cx, "unknown jsval type %#lx for XDR", type); sprintf(numBuf, "%#lx", type);
JS_ReportErrorNumber(xdr->cx, NULL, JSMSG_BAD_JVAL_TYPE, type);
}
return JS_FALSE; return JS_FALSE;
} }
return JS_TRUE; return JS_TRUE;

Просмотреть файл

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