summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extension/script/js/Makefile1471
-rw-r--r--src/extension/script/js/README20
-rw-r--r--src/extension/script/js/fdlibm/e_acos.c147
-rw-r--r--src/extension/script/js/fdlibm/e_acosh.c105
-rw-r--r--src/extension/script/js/fdlibm/e_asin.c156
-rw-r--r--src/extension/script/js/fdlibm/e_atan2.c165
-rw-r--r--src/extension/script/js/fdlibm/e_atanh.c110
-rw-r--r--src/extension/script/js/fdlibm/e_cosh.c133
-rw-r--r--src/extension/script/js/fdlibm/e_exp.c202
-rw-r--r--src/extension/script/js/fdlibm/e_fmod.c184
-rw-r--r--src/extension/script/js/fdlibm/e_gamma.c71
-rw-r--r--src/extension/script/js/fdlibm/e_gamma_r.c70
-rw-r--r--src/extension/script/js/fdlibm/e_hypot.c173
-rw-r--r--src/extension/script/js/fdlibm/e_j0.c524
-rw-r--r--src/extension/script/js/fdlibm/e_j1.c523
-rw-r--r--src/extension/script/js/fdlibm/e_jn.c315
-rw-r--r--src/extension/script/js/fdlibm/e_lgamma.c71
-rw-r--r--src/extension/script/js/fdlibm/e_lgamma_r.c347
-rw-r--r--src/extension/script/js/fdlibm/e_log.c184
-rw-r--r--src/extension/script/js/fdlibm/e_log10.c134
-rw-r--r--src/extension/script/js/fdlibm/e_pow.c386
-rw-r--r--src/extension/script/js/fdlibm/e_rem_pio2.c221
-rw-r--r--src/extension/script/js/fdlibm/e_remainder.c120
-rw-r--r--src/extension/script/js/fdlibm/e_scalb.c89
-rw-r--r--src/extension/script/js/fdlibm/e_sinh.c122
-rw-r--r--src/extension/script/js/fdlibm/e_sqrt.c497
-rw-r--r--src/extension/script/js/fdlibm/fdlibm.h273
-rw-r--r--src/extension/script/js/fdlibm/k_cos.c134
-rw-r--r--src/extension/script/js/fdlibm/k_rem_pio2.c354
-rw-r--r--src/extension/script/js/fdlibm/k_sin.c114
-rw-r--r--src/extension/script/js/fdlibm/k_standard.c785
-rw-r--r--src/extension/script/js/fdlibm/k_tan.c170
-rw-r--r--src/extension/script/js/fdlibm/s_asinh.c101
-rw-r--r--src/extension/script/js/fdlibm/s_atan.c175
-rw-r--r--src/extension/script/js/fdlibm/s_cbrt.c133
-rw-r--r--src/extension/script/js/fdlibm/s_ceil.c120
-rw-r--r--src/extension/script/js/fdlibm/s_copysign.c72
-rw-r--r--src/extension/script/js/fdlibm/s_cos.c118
-rw-r--r--src/extension/script/js/fdlibm/s_erf.c356
-rw-r--r--src/extension/script/js/fdlibm/s_expm1.c267
-rw-r--r--src/extension/script/js/fdlibm/s_fabs.c70
-rw-r--r--src/extension/script/js/fdlibm/s_finite.c71
-rw-r--r--src/extension/script/js/fdlibm/s_floor.c121
-rw-r--r--src/extension/script/js/fdlibm/s_frexp.c99
-rw-r--r--src/extension/script/js/fdlibm/s_ilogb.c85
-rw-r--r--src/extension/script/js/fdlibm/s_isnan.c74
-rw-r--r--src/extension/script/js/fdlibm/s_ldexp.c66
-rw-r--r--src/extension/script/js/fdlibm/s_lib_version.c73
-rw-r--r--src/extension/script/js/fdlibm/s_log1p.c211
-rw-r--r--src/extension/script/js/fdlibm/s_logb.c79
-rw-r--r--src/extension/script/js/fdlibm/s_matherr.c64
-rw-r--r--src/extension/script/js/fdlibm/s_modf.c132
-rw-r--r--src/extension/script/js/fdlibm/s_nextafter.c124
-rw-r--r--src/extension/script/js/fdlibm/s_rint.c131
-rw-r--r--src/extension/script/js/fdlibm/s_scalbn.c107
-rw-r--r--src/extension/script/js/fdlibm/s_signgam.c40
-rw-r--r--src/extension/script/js/fdlibm/s_significand.c68
-rw-r--r--src/extension/script/js/fdlibm/s_sin.c118
-rw-r--r--src/extension/script/js/fdlibm/s_tan.c112
-rw-r--r--src/extension/script/js/fdlibm/s_tanh.c122
-rw-r--r--src/extension/script/js/fdlibm/w_acos.c78
-rw-r--r--src/extension/script/js/fdlibm/w_acosh.c78
-rw-r--r--src/extension/script/js/fdlibm/w_asin.c80
-rw-r--r--src/extension/script/js/fdlibm/w_atan2.c79
-rw-r--r--src/extension/script/js/fdlibm/w_atanh.c81
-rw-r--r--src/extension/script/js/fdlibm/w_cosh.c77
-rw-r--r--src/extension/script/js/fdlibm/w_exp.c88
-rw-r--r--src/extension/script/js/fdlibm/w_fmod.c78
-rw-r--r--src/extension/script/js/fdlibm/w_gamma.c85
-rw-r--r--src/extension/script/js/fdlibm/w_gamma_r.c81
-rw-r--r--src/extension/script/js/fdlibm/w_hypot.c78
-rw-r--r--src/extension/script/js/fdlibm/w_j0.c105
-rw-r--r--src/extension/script/js/fdlibm/w_j1.c106
-rw-r--r--src/extension/script/js/fdlibm/w_jn.c128
-rw-r--r--src/extension/script/js/fdlibm/w_lgamma.c85
-rw-r--r--src/extension/script/js/fdlibm/w_lgamma_r.c81
-rw-r--r--src/extension/script/js/fdlibm/w_log.c78
-rw-r--r--src/extension/script/js/fdlibm/w_log10.c81
-rw-r--r--src/extension/script/js/fdlibm/w_pow.c99
-rw-r--r--src/extension/script/js/fdlibm/w_remainder.c77
-rw-r--r--src/extension/script/js/fdlibm/w_scalb.c95
-rw-r--r--src/extension/script/js/fdlibm/w_sinh.c77
-rw-r--r--src/extension/script/js/fdlibm/w_sqrt.c77
-rw-r--r--src/extension/script/js/js.c2333
-rw-r--r--src/extension/script/js/js.mak4025
-rw-r--r--src/extension/script/js/js.msg251
-rw-r--r--src/extension/script/js/jsapi.c4187
-rw-r--r--src/extension/script/js/jsapi.h1752
-rw-r--r--src/extension/script/js/jsarena.c565
-rw-r--r--src/extension/script/js/jsarena.h302
-rw-r--r--src/extension/script/js/jsarray.c1429
-rw-r--r--src/extension/script/js/jsarray.h77
-rw-r--r--src/extension/script/js/jsatom.c911
-rw-r--r--src/extension/script/js/jsatom.h409
-rw-r--r--src/extension/script/js/jsautocfg.h50
-rw-r--r--src/extension/script/js/jsbit.h113
-rw-r--r--src/extension/script/js/jsbool.c244
-rw-r--r--src/extension/script/js/jsbool.h62
-rw-r--r--src/extension/script/js/jsclist.h139
-rw-r--r--src/extension/script/js/jscntxt.c702
-rw-r--r--src/extension/script/js/jscntxt.h496
-rw-r--r--src/extension/script/js/jscompat.h57
-rw-r--r--src/extension/script/js/jsconfig.h489
-rw-r--r--src/extension/script/js/jscpucfg.c377
-rw-r--r--src/extension/script/js/jscpucfg.h200
-rw-r--r--src/extension/script/js/jsdate.c2234
-rw-r--r--src/extension/script/js/jsdate.h118
-rw-r--r--src/extension/script/js/jsdbgapi.c1240
-rw-r--r--src/extension/script/js/jsdbgapi.h345
-rw-r--r--src/extension/script/js/jsdhash.c763
-rw-r--r--src/extension/script/js/jsdhash.h573
-rw-r--r--src/extension/script/js/jsdtoa.c3155
-rw-r--r--src/extension/script/js/jsdtoa.h130
-rw-r--r--src/extension/script/js/jsemit.c4471
-rw-r--r--src/extension/script/js/jsemit.h547
-rw-r--r--src/extension/script/js/jsexn.c1081
-rw-r--r--src/extension/script/js/jsexn.h102
-rw-r--r--src/extension/script/js/jsfile.c2610
-rw-r--r--src/extension/script/js/jsfile.h50
-rw-r--r--src/extension/script/js/jsfun.c2059
-rw-r--r--src/extension/script/js/jsfun.h151
-rw-r--r--src/extension/script/js/jsgc.c1423
-rw-r--r--src/extension/script/js/jsgc.h230
-rw-r--r--src/extension/script/js/jshash.c479
-rw-r--r--src/extension/script/js/jshash.h152
-rw-r--r--src/extension/script/js/jsinterp.c4284
-rw-r--r--src/extension/script/js/jsinterp.h292
-rw-r--r--src/extension/script/js/jslibmath.h290
-rw-r--r--src/extension/script/js/jslock.c1241
-rw-r--r--src/extension/script/js/jslock.h289
-rw-r--r--src/extension/script/js/jslocko.asm59
-rw-r--r--src/extension/script/js/jslog2.c83
-rw-r--r--src/extension/script/js/jslong.c281
-rw-r--r--src/extension/script/js/jslong.h437
-rw-r--r--src/extension/script/js/jsmath.c477
-rw-r--r--src/extension/script/js/jsmath.h55
-rw-r--r--src/extension/script/js/jsnum.c1058
-rw-r--r--src/extension/script/js/jsnum.h280
-rw-r--r--src/extension/script/js/jsobj.c3900
-rw-r--r--src/extension/script/js/jsobj.h464
-rw-r--r--src/extension/script/js/jsopcode.c2660
-rw-r--r--src/extension/script/js/jsopcode.h273
-rw-r--r--src/extension/script/js/jsopcode.tbl333
-rw-r--r--src/extension/script/js/jsosdep.h127
-rw-r--r--src/extension/script/js/jsotypes.h211
-rw-r--r--src/extension/script/js/jsparse.c3547
-rw-r--r--src/extension/script/js/jsparse.h337
-rw-r--r--src/extension/script/js/jsprf.c1212
-rw-r--r--src/extension/script/js/jsprf.h148
-rw-r--r--src/extension/script/js/jsprvtd.h174
-rw-r--r--src/extension/script/js/jspubtd.h564
-rw-r--r--src/extension/script/js/jsregexp.c3773
-rw-r--r--src/extension/script/js/jsregexp.h168
-rw-r--r--src/extension/script/js/jsscan.c1315
-rw-r--r--src/extension/script/js/jsscan.h264
-rw-r--r--src/extension/script/js/jsscope.c1581
-rw-r--r--src/extension/script/js/jsscope.h386
-rw-r--r--src/extension/script/js/jsscript.c1287
-rw-r--r--src/extension/script/js/jsscript.h178
-rw-r--r--src/extension/script/js/jsshell.msg50
-rw-r--r--src/extension/script/js/jsstddef.h83
-rw-r--r--src/extension/script/js/jsstr.c4502
-rw-r--r--src/extension/script/js/jsstr.h439
-rw-r--r--src/extension/script/js/jstypes.h388
-rw-r--r--src/extension/script/js/jsutil.c157
-rw-r--r--src/extension/script/js/jsutil.h106
-rw-r--r--src/extension/script/js/jsxdrapi.c690
-rw-r--r--src/extension/script/js/jsxdrapi.h193
-rw-r--r--src/extension/script/js/prmjtime.c646
-rw-r--r--src/extension/script/js/prmjtime.h95
-rw-r--r--src/extension/script/js/resource.h15
171 files changed, 0 insertions, 94126 deletions
diff --git a/src/extension/script/js/Makefile b/src/extension/script/js/Makefile
deleted file mode 100644
index bd7ee7360..000000000
--- a/src/extension/script/js/Makefile
+++ /dev/null
@@ -1,1471 +0,0 @@
-# #################################
-# Unix/Linux makefile for libjs.a
-# #################################
-
-
-CC=gcc
-CFLAGS= -O2 -DXP_UNIX
-
-all: js
-
-INC += -Ifdlibm
-
-OBJ = \
- fdlibm/e_acos.o \
- fdlibm/e_acosh.o \
- fdlibm/e_asin.o \
- fdlibm/e_atan2.o \
- fdlibm/e_atanh.o \
- fdlibm/e_cosh.o \
- fdlibm/e_exp.o \
- fdlibm/e_fmod.o \
- fdlibm/e_gamma.o \
- fdlibm/e_gamma_r.o \
- fdlibm/e_hypot.o \
- fdlibm/e_j0.o \
- fdlibm/e_j1.o \
- fdlibm/e_jn.o \
- fdlibm/e_lgamma.o \
- fdlibm/e_lgamma_r.o \
- fdlibm/e_log.o \
- fdlibm/e_log10.o \
- fdlibm/e_pow.o \
- fdlibm/e_rem_pio2.o \
- fdlibm/e_remainder.o \
- fdlibm/e_scalb.o \
- fdlibm/e_sinh.o \
- fdlibm/e_sqrt.o \
- fdlibm/k_cos.o \
- fdlibm/k_rem_pio2.o \
- fdlibm/k_sin.o \
- fdlibm/k_standard.o \
- fdlibm/k_tan.o \
- fdlibm/s_asinh.o \
- fdlibm/s_atan.o \
- fdlibm/s_cbrt.o \
- fdlibm/s_ceil.o \
- fdlibm/s_copysign.o \
- fdlibm/s_cos.o \
- fdlibm/s_erf.o \
- fdlibm/s_expm1.o \
- fdlibm/s_fabs.o \
- fdlibm/s_finite.o \
- fdlibm/s_floor.o \
- fdlibm/s_frexp.o \
- fdlibm/s_ilogb.o \
- fdlibm/s_isnan.o \
- fdlibm/s_ldexp.o \
- fdlibm/s_lib_version.o \
- fdlibm/s_log1p.o \
- fdlibm/s_logb.o \
- fdlibm/s_matherr.o \
- fdlibm/s_modf.o \
- fdlibm/s_nextafter.o \
- fdlibm/s_rint.o \
- fdlibm/s_scalbn.o \
- fdlibm/s_signgam.o \
- fdlibm/s_significand.o \
- fdlibm/s_sin.o \
- fdlibm/s_tan.o \
- fdlibm/s_tanh.o \
- fdlibm/w_acos.o \
- fdlibm/w_acosh.o \
- fdlibm/w_asin.o \
- fdlibm/w_atan2.o \
- fdlibm/w_atanh.o \
- fdlibm/w_cosh.o \
- fdlibm/w_exp.o \
- fdlibm/w_fmod.o \
- fdlibm/w_gamma.o \
- fdlibm/w_gamma_r.o \
- fdlibm/w_hypot.o \
- fdlibm/w_j0.o \
- fdlibm/w_j1.o \
- fdlibm/w_jn.o \
- fdlibm/w_lgamma.o \
- fdlibm/w_lgamma_r.o \
- fdlibm/w_log.o \
- fdlibm/w_log10.o \
- fdlibm/w_pow.o \
- fdlibm/w_remainder.o \
- fdlibm/w_scalb.o \
- fdlibm/w_sinh.o \
- fdlibm/w_sqrt.o \
- jsapi.o \
- jsarena.o \
- jsarray.o \
- jsatom.o \
- jsbool.o \
- jscntxt.o \
- jscpucfg.o \
- jsdate.o \
- jsdbgapi.o \
- jsdhash.o \
- jsdtoa.o \
- jsemit.o \
- jsexn.o \
- jsfile.o \
- jsfun.o \
- jsgc.o \
- jshash.o \
- jsinterp.o \
- jslock.o \
- jslog2.o \
- jslong.o \
- jsmath.o \
- jsnum.o \
- jsobj.o \
- jsopcode.o \
- jsparse.o \
- jsprf.o \
- jsregexp.o \
- jsscan.o \
- jsscope.o \
- jsscript.o \
- jsstr.o \
- jsutil.o \
- jsxdrapi.o \
- prmjtime.o
-
-js: js.o libjs.a
- $(CC) -o js js.o libjs.a -lm
-
-libjs.a: $(OBJ)
- ar crv libjs.a $(OBJ)
- ranlib libjs.a
-
-clean:
- $(RM) js libjs.a $(OBJ)
-
-# ###########################
-# DEPENDENCIES
-# ###########################
-
-
-fdlibm/e_acos.o: \
- fdlibm/e_acos.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_acosh.o: \
- fdlibm/e_acosh.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_asin.o: \
- fdlibm/e_asin.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_atan2.o: \
- fdlibm/e_atan2.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_atanh.o: \
- fdlibm/e_atanh.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_cosh.o: \
- fdlibm/e_cosh.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_exp.o: \
- fdlibm/e_exp.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_fmod.o: \
- fdlibm/e_fmod.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_gamma.o: \
- fdlibm/e_gamma.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_gamma_r.o: \
- fdlibm/e_gamma_r.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_hypot.o: \
- fdlibm/e_hypot.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_j0.o: \
- fdlibm/e_j0.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_j1.o: \
- fdlibm/e_j1.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_jn.o: \
- fdlibm/e_jn.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_lgamma.o: \
- fdlibm/e_lgamma.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_lgamma_r.o: \
- fdlibm/e_lgamma_r.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_log.o: \
- fdlibm/e_log.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_log10.o: \
- fdlibm/e_log10.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_pow.o: \
- fdlibm/e_pow.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_rem_pio2.o: \
- fdlibm/e_rem_pio2.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_remainder.o: \
- fdlibm/e_remainder.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_scalb.o: \
- fdlibm/e_scalb.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_sinh.o: \
- fdlibm/e_sinh.c \
- fdlibm/fdlibm.h
-
-fdlibm/e_sqrt.o: \
- fdlibm/e_sqrt.c \
- fdlibm/fdlibm.h
-
-fdlibm/k_cos.o: \
- fdlibm/k_cos.c \
- fdlibm/fdlibm.h
-
-fdlibm/k_rem_pio2.o: \
- fdlibm/k_rem_pio2.c \
- fdlibm/fdlibm.h
-
-fdlibm/k_sin.o: \
- fdlibm/k_sin.c \
- fdlibm/fdlibm.h
-
-fdlibm/k_standard.o: \
- fdlibm/k_standard.c \
- fdlibm/fdlibm.h
-
-fdlibm/k_tan.o: \
- fdlibm/k_tan.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_asinh.o: \
- fdlibm/s_asinh.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_atan.o: \
- fdlibm/s_atan.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_cbrt.o: \
- fdlibm/s_cbrt.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_ceil.o: \
- fdlibm/s_ceil.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_copysign.o: \
- fdlibm/s_copysign.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_cos.o: \
- fdlibm/s_cos.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_erf.o: \
- fdlibm/s_erf.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_expm1.o: \
- fdlibm/s_expm1.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_fabs.o: \
- fdlibm/s_fabs.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_finite.o: \
- fdlibm/s_finite.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_floor.o: \
- fdlibm/s_floor.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_frexp.o: \
- fdlibm/s_frexp.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_ilogb.o: \
- fdlibm/s_ilogb.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_isnan.o: \
- fdlibm/s_isnan.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_ldexp.o: \
- fdlibm/s_ldexp.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_lib_version.o: \
- fdlibm/s_lib_version.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_log1p.o: \
- fdlibm/s_log1p.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_logb.o: \
- fdlibm/s_logb.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_matherr.o: \
- fdlibm/s_matherr.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_modf.o: \
- fdlibm/s_modf.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_nextafter.o: \
- fdlibm/s_nextafter.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_rint.o: \
- fdlibm/s_rint.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_scalbn.o: \
- fdlibm/s_scalbn.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_signgam.o: \
- fdlibm/s_signgam.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_significand.o: \
- fdlibm/s_significand.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_sin.o: \
- fdlibm/s_sin.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_tan.o: \
- fdlibm/s_tan.c \
- fdlibm/fdlibm.h
-
-fdlibm/s_tanh.o: \
- fdlibm/s_tanh.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_acos.o: \
- fdlibm/w_acos.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_acosh.o: \
- fdlibm/w_acosh.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_asin.o: \
- fdlibm/w_asin.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_atan2.o: \
- fdlibm/w_atan2.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_atanh.o: \
- fdlibm/w_atanh.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_cosh.o: \
- fdlibm/w_cosh.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_exp.o: \
- fdlibm/w_exp.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_fmod.o: \
- fdlibm/w_fmod.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_gamma.o: \
- fdlibm/w_gamma.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_gamma_r.o: \
- fdlibm/w_gamma_r.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_hypot.o: \
- fdlibm/w_hypot.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_j0.o: \
- fdlibm/w_j0.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_j1.o: \
- fdlibm/w_j1.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_jn.o: \
- fdlibm/w_jn.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_lgamma.o: \
- fdlibm/w_lgamma.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_lgamma_r.o: \
- fdlibm/w_lgamma_r.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_log.o: \
- fdlibm/w_log.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_log10.o: \
- fdlibm/w_log10.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_pow.o: \
- fdlibm/w_pow.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_remainder.o: \
- fdlibm/w_remainder.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_scalb.o: \
- fdlibm/w_scalb.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_sinh.o: \
- fdlibm/w_sinh.c \
- fdlibm/fdlibm.h
-
-fdlibm/w_sqrt.o: \
- fdlibm/w_sqrt.c \
- fdlibm/fdlibm.h
-
-js.o: \
- js.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsapi.o: \
- jsapi.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsbool.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdate.h \
- jsdhash.h \
- jsdtoa.h \
- jsemit.h \
- jsexn.h \
- jsfile.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsmath.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- prmjtime.h
-
-jsarena.o: \
- jsarena.c \
- jsarena.h \
- jsbit.h \
- jscompat.h \
- jscpucfg.h \
- jshash.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsscope.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h
-
-jsarray.o: \
- jsarray.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsatom.o: \
- jsatom.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsbool.o: \
- jsbool.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsbool.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jscntxt.o: \
- jscntxt.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsexn.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jscpucfg.o: \
- jscpucfg.c
-
-jsdate.o: \
- jsdate.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdate.h \
- jsdhash.h \
- jsdtoa.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- prmjtime.h
-
-jsdbgapi.o: \
- jsdbgapi.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsdhash.o: \
- jsdhash.c \
- jsbit.h \
- jscpucfg.h \
- jsdhash.h \
- jsosdep.h \
- jsotypes.h \
- jstypes.h \
- jsutil.h
-
-jsdtoa.o: \
- jsdtoa.c \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdtoa.h \
- jslibmath.h \
- jslong.h \
- jsnum.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jspubtd.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h
-
-jsemit.o: \
- jsemit.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsbit.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsexn.o: \
- jsexn.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsbit.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsexn.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsfile.o: \
- jsfile.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdate.h \
- jsdbgapi.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsfun.o: \
- jsfun.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsbit.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsexn.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- jsxdrapi.h
-
-jsgc.o: \
- jsgc.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jshash.o: \
- jshash.c \
- jsbit.h \
- jscompat.h \
- jscpucfg.h \
- jshash.h \
- jslong.h \
- jsosdep.h \
- jsotypes.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h
-
-jsinterp.o: \
- jsinterp.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsbool.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jslock.o: \
- jslock.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsbit.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsdtoa.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jslog2.o: \
- jslog2.c \
- jsbit.h \
- jscpucfg.h \
- jsosdep.h \
- jsotypes.h \
- jsstddef.h \
- jstypes.h
-
-jslong.o: \
- jslong.c \
- jscpucfg.h \
- jslong.h \
- jsosdep.h \
- jsotypes.h \
- jsstddef.h \
- jstypes.h
-
-jsmath.o: \
- jsmath.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslibmath.h \
- jslock.h \
- jslong.h \
- jsmath.h \
- jsnum.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- prmjtime.h
-
-jsnum.o: \
- jsnum.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsdtoa.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsobj.o: \
- jsobj.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsbool.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- jsxdrapi.h
-
-jsopcode.o: \
- jsopcode.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsdtoa.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsparse.o: \
- jsparse.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsparse.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsprf.o: \
- jsprf.c \
- jscpucfg.h \
- jslong.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h
-
-jsregexp.o: \
- jsregexp.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- jsxdrapi.h
-
-jsscan.o: \
- jsscan.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsdtoa.h \
- jsemit.h \
- jsexn.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscan.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsscope.o: \
- jsscope.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsbit.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsscript.o: \
- jsscript.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdbgapi.h \
- jsdhash.h \
- jsemit.h \
- jsfun.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- jsxdrapi.h
-
-jsstr.o: \
- jsstr.c \
- jsapi.h \
- jsarena.h \
- jsarray.h \
- jsatom.h \
- jsbool.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsnum.h \
- jsobj.h \
- jsopcode.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h
-
-jsutil.o: \
- jsutil.c \
- jscpucfg.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h
-
-jsxdrapi.o: \
- jsxdrapi.c \
- jsapi.h \
- jsarena.h \
- jsatom.h \
- jsclist.h \
- jscntxt.h \
- jscompat.h \
- jsconfig.h \
- jscpucfg.h \
- jsdhash.h \
- jsgc.h \
- jshash.h \
- jsinterp.h \
- jslock.h \
- jslong.h \
- jsobj.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsprvtd.h \
- jspubtd.h \
- jsregexp.h \
- jsscope.h \
- jsscript.h \
- jsstddef.h \
- jsstr.h \
- jstypes.h \
- jsutil.h \
- jsxdrapi.h
-
-prmjtime.o: \
- prmjtime.c \
- jscompat.h \
- jscpucfg.h \
- jslong.h \
- jsosdep.h \
- jsotypes.h \
- jsprf.h \
- jsstddef.h \
- jstypes.h \
- jsutil.h \
- prmjtime.h
-
diff --git a/src/extension/script/js/README b/src/extension/script/js/README
deleted file mode 100644
index cca453245..000000000
--- a/src/extension/script/js/README
+++ /dev/null
@@ -1,20 +0,0 @@
-//#########################################################################
-//# $Id$
-//#########################################################################
-See:
-
-$PROJECT/src/ecma/README
-
-for more information.
-
-The source is unchanged from Mozilla.org's distribution with
-the minor difference:
-
-Line 142 in jstypes.h:
-#if defined(_WIN32) && !defined(__MWERKS__)
-is modified to
-#if defined(_WIN32) && !defined(__MWERKS__) && !defined(__GNUC__)
-to allow for static linking in Mingw on Win32.
-
-
-
diff --git a/src/extension/script/js/fdlibm/e_acos.c b/src/extension/script/js/fdlibm/e_acos.c
deleted file mode 100644
index a07c1eebc..000000000
--- a/src/extension/script/js/fdlibm/e_acos.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_acos.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_acos(x)
- * Method :
- * acos(x) = pi/2 - asin(x)
- * acos(-x) = pi/2 + asin(x)
- * For |x|<=0.5
- * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
- * For x>0.5
- * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
- * = 2asin(sqrt((1-x)/2))
- * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
- * = 2f + (2c + 2s*z*R(z))
- * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
- * for f so that f+c ~ sqrt(z).
- * For x<-0.5
- * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
- * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
- *
- * Special cases:
- * if x is NaN, return x itself;
- * if |x|>1, return NaN with invalid signal.
- *
- * Function needed: sqrt
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
-pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
-pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
-pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
-pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
-pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
-pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
-pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
-pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
-qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
-qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
-qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
-qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
-
-#ifdef __STDC__
- double __ieee754_acos(double x)
-#else
- double __ieee754_acos(x)
- double x;
-#endif
-{
- fd_twoints u;
- double df;
- double z,p,q,r,w,s,c;
- int hx,ix;
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- if(ix>=0x3ff00000) { /* |x| >= 1 */
- if(((ix-0x3ff00000)|__LO(u))==0) { /* |x|==1 */
- if(hx>0) return 0.0; /* acos(1) = 0 */
- else return pi+2.0*pio2_lo; /* acos(-1)= pi */
- }
- return (x-x)/(x-x); /* acos(|x|>1) is NaN */
- }
- if(ix<0x3fe00000) { /* |x| < 0.5 */
- if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
- z = x*x;
- p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
- q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
- r = p/q;
- return pio2_hi - (x - (pio2_lo-x*r));
- } else if (hx<0) { /* x < -0.5 */
- z = (one+x)*0.5;
- p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
- q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
- s = fd_sqrt(z);
- r = p/q;
- w = r*s-pio2_lo;
- return pi - 2.0*(s+w);
- } else { /* x > 0.5 */
- z = (one-x)*0.5;
- s = fd_sqrt(z);
- u.d = s;
- __LO(u) = 0;
- df = u.d;
- c = (z-df*df)/(s+df);
- p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
- q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
- r = p/q;
- w = r*s+c;
- return 2.0*(df+w);
- }
-}
diff --git a/src/extension/script/js/fdlibm/e_acosh.c b/src/extension/script/js/fdlibm/e_acosh.c
deleted file mode 100644
index 725cceefb..000000000
--- a/src/extension/script/js/fdlibm/e_acosh.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_acosh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_acosh(x)
- * Method :
- * Based on
- * acosh(x) = log [ x + sqrt(x*x-1) ]
- * we have
- * acosh(x) := log(x)+ln2, if x is large; else
- * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
- * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
- *
- * Special cases:
- * acosh(x) is NaN with signal if x<1.
- * acosh(NaN) is NaN without signal.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.0,
-ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
-
-#ifdef __STDC__
- double __ieee754_acosh(double x)
-#else
- double __ieee754_acosh(x)
- double x;
-#endif
-{
- fd_twoints u;
- double t;
- int hx;
- u.d = x;
- hx = __HI(u);
- if(hx<0x3ff00000) { /* x < 1 */
- return (x-x)/(x-x);
- } else if(hx >=0x41b00000) { /* x > 2**28 */
- if(hx >=0x7ff00000) { /* x is inf of NaN */
- return x+x;
- } else
- return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */
- } else if(((hx-0x3ff00000)|__LO(u))==0) {
- return 0.0; /* acosh(1) = 0 */
- } else if (hx > 0x40000000) { /* 2**28 > x > 2 */
- t=x*x;
- return __ieee754_log(2.0*x-one/(x+fd_sqrt(t-one)));
- } else { /* 1<x<2 */
- t = x-one;
- return fd_log1p(t+fd_sqrt(2.0*t+t*t));
- }
-}
diff --git a/src/extension/script/js/fdlibm/e_asin.c b/src/extension/script/js/fdlibm/e_asin.c
deleted file mode 100644
index 624c4d2ce..000000000
--- a/src/extension/script/js/fdlibm/e_asin.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_asin.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_asin(x)
- * Method :
- * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
- * we approximate asin(x) on [0,0.5] by
- * asin(x) = x + x*x^2*R(x^2)
- * where
- * R(x^2) is a rational approximation of (asin(x)-x)/x^3
- * and its remez error is bounded by
- * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
- *
- * For x in [0.5,1]
- * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
- * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
- * then for x>0.98
- * asin(x) = pi/2 - 2*(s+s*z*R(z))
- * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
- * For x<=0.98, let pio4_hi = pio2_hi/2, then
- * f = hi part of s;
- * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
- * and
- * asin(x) = pi/2 - 2*(s+s*z*R(z))
- * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
- * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
- *
- * Special cases:
- * if x is NaN, return x itself;
- * if |x|>1, return NaN with invalid signal.
- *
- */
-
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-really_big = 1.000e+300,
-pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
-pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
-pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
- /* coefficient for R(x^2) */
-pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
-pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
-pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
-pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
-pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
-pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
-qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
-qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
-qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
-qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
-
-#ifdef __STDC__
- double __ieee754_asin(double x)
-#else
- double __ieee754_asin(x)
- double x;
-#endif
-{
- fd_twoints u;
- double w,t,p,q,c,r,s;
- int hx,ix;
- u.d = x;
- hx = __HI(u);
- x = u.d;
- ix = hx&0x7fffffff;
- if(ix>= 0x3ff00000) { /* |x|>= 1 */
- if(((ix-0x3ff00000)|__LO(u))==0)
- /* asin(1)=+-pi/2 with inexact */
- return x*pio2_hi+x*pio2_lo;
- return (x-x)/(x-x); /* asin(|x|>1) is NaN */
- } else if (ix<0x3fe00000) { /* |x|<0.5 */
- if(ix<0x3e400000) { /* if |x| < 2**-27 */
- if(really_big+x>one) return x;/* return x with inexact if x!=0*/
- } else
- t = x*x;
- p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
- q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
- w = p/q;
- return x+x*w;
- }
- /* 1> |x|>= 0.5 */
- w = one-fd_fabs(x);
- t = w*0.5;
- p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
- q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
- s = fd_sqrt(t);
- if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
- w = p/q;
- t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
- } else {
- u.d = s;
- __LO(u) = 0;
- w = u.d;
- c = (t-w*w)/(s+w);
- r = p/q;
- p = 2.0*s*r-(pio2_lo-2.0*c);
- q = pio4_hi-2.0*w;
- t = pio4_hi-(p-q);
- }
- if(hx>0) return t; else return -t;
-}
diff --git a/src/extension/script/js/fdlibm/e_atan2.c b/src/extension/script/js/fdlibm/e_atan2.c
deleted file mode 100644
index 9c9a2c01f..000000000
--- a/src/extension/script/js/fdlibm/e_atan2.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_atan2.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_atan2(y,x)
- * Method :
- * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
- * 2. Reduce x to positive by (if x and y are unexceptional):
- * ARG (x+iy) = arctan(y/x) ... if x > 0,
- * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
- *
- * Special cases:
- *
- * ATAN2((anything), NaN ) is NaN;
- * ATAN2(NAN , (anything) ) is NaN;
- * ATAN2(+-0, +(anything but NaN)) is +-0 ;
- * ATAN2(+-0, -(anything but NaN)) is +-pi ;
- * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
- * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
- * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
- * ATAN2(+-INF,+INF ) is +-pi/4 ;
- * ATAN2(+-INF,-INF ) is +-3pi/4;
- * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-tiny = 1.0e-300,
-zero = 0.0,
-pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
-pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
-pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
-pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
-
-#ifdef __STDC__
- double __ieee754_atan2(double y, double x)
-#else
- double __ieee754_atan2(y,x)
- double y,x;
-#endif
-{
- fd_twoints ux, uy, uz;
- double z;
- int k,m,hx,hy,ix,iy;
- unsigned lx,ly;
-
- ux.d = x; uy.d = y;
- hx = __HI(ux); ix = hx&0x7fffffff;
- lx = __LO(ux);
- hy = __HI(uy); iy = hy&0x7fffffff;
- ly = __LO(uy);
- if(((ix|((lx|-(int)lx)>>31))>0x7ff00000)||
- ((iy|((ly|-(int)ly)>>31))>0x7ff00000)) /* x or y is NaN */
- return x+y;
- if(((hx-0x3ff00000)|lx)==0) return fd_atan(y); /* x=1.0 */
- m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
-
- /* when y = 0 */
- if((iy|ly)==0) {
- switch(m) {
- case 0:
- case 1: return y; /* atan(+-0,+anything)=+-0 */
- case 2: return pi+tiny;/* atan(+0,-anything) = pi */
- case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
- }
- }
- /* when x = 0 */
- if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
-
- /* when x is INF */
- if(ix==0x7ff00000) {
- if(iy==0x7ff00000) {
- switch(m) {
- case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
- case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
- case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
- case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
- }
- } else {
- switch(m) {
- case 0: return zero ; /* atan(+...,+INF) */
- case 1: return -zero ; /* atan(-...,+INF) */
- case 2: return pi+tiny ; /* atan(+...,-INF) */
- case 3: return -pi-tiny ; /* atan(-...,-INF) */
- }
- }
- }
- /* when y is INF */
- if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
-
- /* compute y/x */
- k = (iy-ix)>>20;
- if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
- else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
- else z=fd_atan(fd_fabs(y/x)); /* safe to do y/x */
- switch (m) {
- case 0: return z ; /* atan(+,+) */
- case 1: uz.d = z;
- __HI(uz) ^= 0x80000000;
- z = uz.d;
- return z ; /* atan(-,+) */
- case 2: return pi-(z-pi_lo);/* atan(+,-) */
- default: /* case 3 */
- return (z-pi_lo)-pi;/* atan(-,-) */
- }
-}
diff --git a/src/extension/script/js/fdlibm/e_atanh.c b/src/extension/script/js/fdlibm/e_atanh.c
deleted file mode 100644
index dc4a90c8e..000000000
--- a/src/extension/script/js/fdlibm/e_atanh.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_atanh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_atanh(x)
- * Method :
- * 1.Reduced x to positive by atanh(-x) = -atanh(x)
- * 2.For x>=0.5
- * 1 2x x
- * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
- * 2 1 - x 1 - x
- *
- * For x<0.5
- * atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
- *
- * Special cases:
- * atanh(x) is NaN if |x| > 1 with signal;
- * atanh(NaN) is that NaN with no signal;
- * atanh(+-1) is +-INF with signal.
- *
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double one = 1.0, really_big = 1e300;
-#else
-static double one = 1.0, really_big = 1e300;
-#endif
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double __ieee754_atanh(double x)
-#else
- double __ieee754_atanh(x)
- double x;
-#endif
-{
- double t;
- int hx,ix;
- unsigned lx;
- fd_twoints u;
- u.d = x;
- hx = __HI(u); /* high word */
- lx = __LO(u); /* low word */
- ix = hx&0x7fffffff;
- if ((ix|((lx|(-(int)lx))>>31))>0x3ff00000) /* |x|>1 */
- return (x-x)/(x-x);
- if(ix==0x3ff00000)
- return x/zero;
- if(ix<0x3e300000&&(really_big+x)>zero) return x; /* x<2**-28 */
- u.d = x;
- __HI(u) = ix; /* x <- |x| */
- x = u.d;
- if(ix<0x3fe00000) { /* x < 0.5 */
- t = x+x;
- t = 0.5*fd_log1p(t+t*x/(one-x));
- } else
- t = 0.5*fd_log1p((x+x)/(one-x));
- if(hx>=0) return t; else return -t;
-}
diff --git a/src/extension/script/js/fdlibm/e_cosh.c b/src/extension/script/js/fdlibm/e_cosh.c
deleted file mode 100644
index 4f8d4f769..000000000
--- a/src/extension/script/js/fdlibm/e_cosh.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_cosh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_cosh(x)
- * Method :
- * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
- * 1. Replace x by |x| (cosh(x) = cosh(-x)).
- * 2.
- * [ exp(x) - 1 ]^2
- * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
- * 2*exp(x)
- *
- * exp(x) + 1/exp(x)
- * ln2/2 <= x <= 22 : cosh(x) := -------------------
- * 2
- * 22 <= x <= lnovft : cosh(x) := exp(x)/2
- * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
- * ln2ovft < x : cosh(x) := huge*huge (overflow)
- *
- * Special cases:
- * cosh(x) is |x| if x is +INF, -INF, or NaN.
- * only cosh(0)=1 is exact for finite x.
- */
-
-#include "fdlibm.h"
-
-#ifdef _WIN32
-#define huge myhuge
-#endif
-
-#ifdef __STDC__
-static const double one = 1.0, half=0.5, really_big = 1.0e300;
-#else
-static double one = 1.0, half=0.5, really_big = 1.0e300;
-#endif
-
-#ifdef __STDC__
- double __ieee754_cosh(double x)
-#else
- double __ieee754_cosh(x)
- double x;
-#endif
-{
- fd_twoints u;
- double t,w;
- int ix;
- unsigned lx;
-
- /* High word of |x|. */
- u.d = x;
- ix = __HI(u);
- ix &= 0x7fffffff;
-
- /* x is INF or NaN */
- if(ix>=0x7ff00000) return x*x;
-
- /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
- if(ix<0x3fd62e43) {
- t = fd_expm1(fd_fabs(x));
- w = one+t;
- if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */
- return one+(t*t)/(w+w);
- }
-
- /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
- if (ix < 0x40360000) {
- t = __ieee754_exp(fd_fabs(x));
- return half*t+half/t;
- }
-
- /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
- if (ix < 0x40862E42) return half*__ieee754_exp(fd_fabs(x));
-
- /* |x| in [log(maxdouble), overflowthresold] */
- lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
- if (ix<0x408633CE ||
- (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) {
- w = __ieee754_exp(half*fd_fabs(x));
- t = half*w;
- return t*w;
- }
-
- /* |x| > overflowthresold, cosh(x) overflow */
- return really_big*really_big;
-}
diff --git a/src/extension/script/js/fdlibm/e_exp.c b/src/extension/script/js/fdlibm/e_exp.c
deleted file mode 100644
index ad9cec124..000000000
--- a/src/extension/script/js/fdlibm/e_exp.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_exp.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_exp(x)
- * Returns the exponential of x.
- *
- * Method
- * 1. Argument reduction:
- * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
- * Given x, find r and integer k such that
- *
- * x = k*ln2 + r, |r| <= 0.5*ln2.
- *
- * Here r will be represented as r = hi-lo for better
- * accuracy.
- *
- * 2. Approximation of exp(r) by a special rational function on
- * the interval [0,0.34658]:
- * Write
- * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
- * We use a special Reme algorithm on [0,0.34658] to generate
- * a polynomial of degree 5 to approximate R. The maximum error
- * of this polynomial approximation is bounded by 2**-59. In
- * other words,
- * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
- * (where z=r*r, and the values of P1 to P5 are listed below)
- * and
- * | 5 | -59
- * | 2.0+P1*z+...+P5*z - R(z) | <= 2
- * | |
- * The computation of exp(r) thus becomes
- * 2*r
- * exp(r) = 1 + -------
- * R - r
- * r*R1(r)
- * = 1 + r + ----------- (for better accuracy)
- * 2 - R1(r)
- * where
- * 2 4 10
- * R1(r) = r - (P1*r + P2*r + ... + P5*r ).
- *
- * 3. Scale back to obtain exp(x):
- * From step 1, we have
- * exp(x) = 2^k * exp(r)
- *
- * Special cases:
- * exp(INF) is INF, exp(NaN) is NaN;
- * exp(-INF) is 0, and
- * for finite argument, only exp(0)=1 is exact.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Misc. info.
- * For IEEE double
- * if x > 7.09782712893383973096e+02 then exp(x) overflow
- * if x < -7.45133219101941108420e+02 then exp(x) underflow
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.0,
-halF[2] = {0.5,-0.5,},
-really_big = 1.0e+300,
-twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
-o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
-u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
-ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
- -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
-ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
- -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
-invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
-P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
-P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
-P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
-P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
-P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
-
-
-#ifdef __STDC__
- double __ieee754_exp(double x) /* default IEEE double exp */
-#else
- double __ieee754_exp(x) /* default IEEE double exp */
- double x;
-#endif
-{
- fd_twoints u;
- double y,hi,lo,c,t;
- int k, xsb;
- unsigned hx;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- xsb = (hx>>31)&1; /* sign bit of x */
- hx &= 0x7fffffff; /* high word of |x| */
-
- /* filter out non-finite argument */
- if(hx >= 0x40862E42) { /* if |x|>=709.78... */
- if(hx>=0x7ff00000) {
- u.d = x;
- if(((hx&0xfffff)|__LO(u))!=0)
- return x+x; /* NaN */
- else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
- }
- if(x > o_threshold) return really_big*really_big; /* overflow */
- if(x < u_threshold) return twom1000*twom1000; /* underflow */
- }
-
- /* argument reduction */
- if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
- if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
- hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
- } else {
- k = (int)(invln2*x+halF[xsb]);
- t = k;
- hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
- lo = t*ln2LO[0];
- }
- x = hi - lo;
- }
- else if(hx < 0x3e300000) { /* when |x|<2**-28 */
- if(really_big+x>one) return one+x;/* trigger inexact */
- }
- else k = 0;
-
- /* x is now in primary range */
- t = x*x;
- c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- if(k==0) return one-((x*c)/(c-2.0)-x);
- else y = one-((lo-(x*c)/(2.0-c))-hi);
- if(k >= -1021) {
- u.d = y;
- __HI(u) += (k<<20); /* add k to y's exponent */
- y = u.d;
- return y;
- } else {
- u.d = y;
- __HI(u) += ((k+1000)<<20);/* add k to y's exponent */
- y = u.d;
- return y*twom1000;
- }
-}
diff --git a/src/extension/script/js/fdlibm/e_fmod.c b/src/extension/script/js/fdlibm/e_fmod.c
deleted file mode 100644
index 7b5ce780f..000000000
--- a/src/extension/script/js/fdlibm/e_fmod.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_fmod.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * __ieee754_fmod(x,y)
- * Return x mod y in exact arithmetic
- * Method: shift and subtract
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double one = 1.0, Zero[] = {0.0, -0.0,};
-#else
-static double one = 1.0, Zero[] = {0.0, -0.0,};
-#endif
-
-#ifdef __STDC__
- double __ieee754_fmod(double x, double y)
-#else
- double __ieee754_fmod(x,y)
- double x,y ;
-#endif
-{
- fd_twoints ux, uy;
- int n,hx,hy,hz,ix,iy,sx,i;
- unsigned lx,ly,lz;
-
- ux.d = x; uy.d = y;
- hx = __HI(ux); /* high word of x */
- lx = __LO(ux); /* low word of x */
- hy = __HI(uy); /* high word of y */
- ly = __LO(uy); /* low word of y */
- sx = hx&0x80000000; /* sign of x */
- hx ^=sx; /* |x| */
- hy &= 0x7fffffff; /* |y| */
-
- /* purge off exception values */
- if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
- ((hy|((ly|-(int)ly)>>31))>0x7ff00000)) /* or y is NaN */
- return (x*y)/(x*y);
- if(hx<=hy) {
- if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
- if(lx==ly)
- return Zero[(unsigned)sx>>31]; /* |x|=|y| return x*0*/
- }
-
- /* determine ix = ilogb(x) */
- if(hx<0x00100000) { /* subnormal x */
- if(hx==0) {
- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
- } else {
- for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
- }
- } else ix = (hx>>20)-1023;
-
- /* determine iy = ilogb(y) */
- if(hy<0x00100000) { /* subnormal y */
- if(hy==0) {
- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
- } else {
- for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
- }
- } else iy = (hy>>20)-1023;
-
- /* set up {hx,lx}, {hy,ly} and align y to x */
- if(ix >= -1022)
- hx = 0x00100000|(0x000fffff&hx);
- else { /* subnormal x, shift x to normal */
- n = -1022-ix;
- if(n<=31) {
- hx = (hx<<n)|(lx>>(32-n));
- lx <<= n;
- } else {
- hx = lx<<(n-32);
- lx = 0;
- }
- }
- if(iy >= -1022)
- hy = 0x00100000|(0x000fffff&hy);
- else { /* subnormal y, shift y to normal */
- n = -1022-iy;
- if(n<=31) {
- hy = (hy<<n)|(ly>>(32-n));
- ly <<= n;
- } else {
- hy = ly<<(n-32);
- ly = 0;
- }
- }
-
- /* fix point fmod */
- n = ix - iy;
- while(n--) {
- hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
- if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
- else {
- if((hz|lz)==0) /* return sign(x)*0 */
- return Zero[(unsigned)sx>>31];
- hx = hz+hz+(lz>>31); lx = lz+lz;
- }
- }
- hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
- if(hz>=0) {hx=hz;lx=lz;}
-
- /* convert back to floating value and restore the sign */
- if((hx|lx)==0) /* return sign(x)*0 */
- return Zero[(unsigned)sx>>31];
- while(hx<0x00100000) { /* normalize x */
- hx = hx+hx+(lx>>31); lx = lx+lx;
- iy -= 1;
- }
- if(iy>= -1022) { /* normalize output */
- hx = ((hx-0x00100000)|((iy+1023)<<20));
- ux.d = x;
- __HI(ux) = hx|sx;
- __LO(ux) = lx;
- x = ux.d;
- } else { /* subnormal output */
- n = -1022 - iy;
- if(n<=20) {
- lx = (lx>>n)|((unsigned)hx<<(32-n));
- hx >>= n;
- } else if (n<=31) {
- lx = (hx<<(32-n))|(lx>>n); hx = sx;
- } else {
- lx = hx>>(n-32); hx = sx;
- }
- ux.d = x;
- __HI(ux) = hx|sx;
- __LO(ux) = lx;
- x = ux.d;
- x *= one; /* create necessary signal */
- }
- return x; /* exact output */
-}
diff --git a/src/extension/script/js/fdlibm/e_gamma.c b/src/extension/script/js/fdlibm/e_gamma.c
deleted file mode 100644
index a34faa32c..000000000
--- a/src/extension/script/js/fdlibm/e_gamma.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_gamma.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_gamma(x)
- * Return the logarithm of the Gamma function of x.
- *
- * Method: call __ieee754_gamma_r
- */
-
-#include "fdlibm.h"
-
-extern int signgam;
-
-#ifdef __STDC__
- double __ieee754_gamma(double x)
-#else
- double __ieee754_gamma(x)
- double x;
-#endif
-{
- return __ieee754_gamma_r(x,&signgam);
-}
diff --git a/src/extension/script/js/fdlibm/e_gamma_r.c b/src/extension/script/js/fdlibm/e_gamma_r.c
deleted file mode 100644
index f10e32e36..000000000
--- a/src/extension/script/js/fdlibm/e_gamma_r.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_gamma_r.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_gamma_r(x, signgamp)
- * Reentrant version of the logarithm of the Gamma function
- * with user provide pointer for the sign of Gamma(x).
- *
- * Method: See __ieee754_lgamma_r
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double __ieee754_gamma_r(double x, int *signgamp)
-#else
- double __ieee754_gamma_r(x,signgamp)
- double x; int *signgamp;
-#endif
-{
- return __ieee754_lgamma_r(x,signgamp);
-}
diff --git a/src/extension/script/js/fdlibm/e_hypot.c b/src/extension/script/js/fdlibm/e_hypot.c
deleted file mode 100644
index 390023087..000000000
--- a/src/extension/script/js/fdlibm/e_hypot.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_hypot.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_hypot(x,y)
- *
- * Method :
- * If (assume round-to-nearest) z=x*x+y*y
- * has error less than sqrt(2)/2 ulp, than
- * sqrt(z) has error less than 1 ulp (exercise).
- *
- * So, compute sqrt(x*x+y*y) with some care as
- * follows to get the error below 1 ulp:
- *
- * Assume x>y>0;
- * (if possible, set rounding to round-to-nearest)
- * 1. if x > 2y use
- * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
- * where x1 = x with lower 32 bits cleared, x2 = x-x1; else
- * 2. if x <= 2y use
- * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
- * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
- * y1= y with lower 32 bits chopped, y2 = y-y1.
- *
- * NOTE: scaling may be necessary if some argument is too
- * large or too tiny
- *
- * Special cases:
- * hypot(x,y) is INF if x or y is +INF or -INF; else
- * hypot(x,y) is NAN if x or y is NAN.
- *
- * Accuracy:
- * hypot(x,y) returns sqrt(x^2+y^2) with error less
- * than 1 ulps (units in the last place)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double __ieee754_hypot(double x, double y)
-#else
- double __ieee754_hypot(x,y)
- double x, y;
-#endif
-{
- fd_twoints ux, uy;
- double a=x,b=y,t1,t2,y1,y2,w;
- int j,k,ha,hb;
-
- ux.d = x; uy.d = y;
- ha = __HI(ux)&0x7fffffff; /* high word of x */
- hb = __HI(uy)&0x7fffffff; /* high word of y */
- if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
- ux.d = a; uy.d = b;
- __HI(ux) = ha; /* a <- |a| */
- __HI(uy) = hb; /* b <- |b| */
- a = ux.d; b = uy.d;
- if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
- k=0;
- if(ha > 0x5f300000) { /* a>2**500 */
- if(ha >= 0x7ff00000) { /* Inf or NaN */
- w = a+b; /* for sNaN */
- ux.d = a; uy.d = b;
- if(((ha&0xfffff)|__LO(ux))==0) w = a;
- if(((hb^0x7ff00000)|__LO(uy))==0) w = b;
- return w;
- }
- /* scale a and b by 2**-600 */
- ha -= 0x25800000; hb -= 0x25800000; k += 600;
- ux.d = a; uy.d = b;
- __HI(ux) = ha;
- __HI(uy) = hb;
- a = ux.d; b = uy.d;
- }
- if(hb < 0x20b00000) { /* b < 2**-500 */
- if(hb <= 0x000fffff) { /* subnormal b or 0 */
- uy.d = b;
- if((hb|(__LO(uy)))==0) return a;
- t1=0;
- ux.d = t1;
- __HI(ux) = 0x7fd00000; /* t1=2^1022 */
- t1 = ux.d;
- b *= t1;
- a *= t1;
- k -= 1022;
- } else { /* scale a and b by 2^600 */
- ha += 0x25800000; /* a *= 2^600 */
- hb += 0x25800000; /* b *= 2^600 */
- k -= 600;
- ux.d = a; uy.d = b;
- __HI(ux) = ha;
- __HI(uy) = hb;
- a = ux.d; b = uy.d;
- }
- }
- /* medium size a and b */
- w = a-b;
- if (w>b) {
- t1 = 0;
- ux.d = t1;
- __HI(ux) = ha;
- t1 = ux.d;
- t2 = a-t1;
- w = fd_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
- } else {
- a = a+a;
- y1 = 0;
- ux.d = y1;
- __HI(ux) = hb;
- y1 = ux.d;
- y2 = b - y1;
- t1 = 0;
- ux.d = t1;
- __HI(ux) = ha+0x00100000;
- t1 = ux.d;
- t2 = a - t1;
- w = fd_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
- }
- if(k!=0) {
- t1 = 1.0;
- ux.d = t1;
- __HI(ux) += (k<<20);
- t1 = ux.d;
- return t1*w;
- } else return w;
-}
diff --git a/src/extension/script/js/fdlibm/e_j0.c b/src/extension/script/js/fdlibm/e_j0.c
deleted file mode 100644
index 078e09641..000000000
--- a/src/extension/script/js/fdlibm/e_j0.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_j0.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_j0(x), __ieee754_y0(x)
- * Bessel function of the first and second kinds of order zero.
- * Method -- j0(x):
- * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
- * 2. Reduce x to |x| since j0(x)=j0(-x), and
- * for x in (0,2)
- * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x;
- * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
- * for x in (2,inf)
- * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
- * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
- * as follow:
- * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
- * = 1/sqrt(2) * (cos(x) + sin(x))
- * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
- * = 1/sqrt(2) * (sin(x) - cos(x))
- * (To avoid cancellation, use
- * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
- * to compute the worse one.)
- *
- * 3 Special cases
- * j0(nan)= nan
- * j0(0) = 1
- * j0(inf) = 0
- *
- * Method -- y0(x):
- * 1. For x<2.
- * Since
- * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
- * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
- * We use the following function to approximate y0,
- * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
- * where
- * U(z) = u00 + u01*z + ... + u06*z^6
- * V(z) = 1 + v01*z + ... + v04*z^4
- * with absolute approximation error bounded by 2**-72.
- * Note: For tiny x, U/V = u0 and j0(x)~1, hence
- * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
- * 2. For x>=2.
- * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
- * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
- * by the method mentioned above.
- * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static double pzero(double), qzero(double);
-#else
-static double pzero(), qzero();
-#endif
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-really_big = 1e300,
-one = 1.0,
-invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
-tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
- /* R0/S0 on [0, 2.00] */
-R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
-R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
-R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
-R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
-S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
-S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
-S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
-S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double __ieee754_j0(double x)
-#else
- double __ieee754_j0(x)
- double x;
-#endif
-{
- fd_twoints un;
- double z, s,c,ss,cc,r,u,v;
- int hx,ix;
-
- un.d = x;
- hx = __HI(un);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) return one/(x*x);
- x = fd_fabs(x);
- if(ix >= 0x40000000) { /* |x| >= 2.0 */
- s = fd_sin(x);
- c = fd_cos(x);
- ss = s-c;
- cc = s+c;
- if(ix<0x7fe00000) { /* make sure x+x not overflow */
- z = -fd_cos(x+x);
- if ((s*c)<zero) cc = z/ss;
- else ss = z/cc;
- }
- /*
- * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
- * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
- */
- if(ix>0x48000000) z = (invsqrtpi*cc)/fd_sqrt(x);
- else {
- u = pzero(x); v = qzero(x);
- z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(x);
- }
- return z;
- }
- if(ix<0x3f200000) { /* |x| < 2**-13 */
- if(really_big+x>one) { /* raise inexact if x != 0 */
- if(ix<0x3e400000) return one; /* |x|<2**-27 */
- else return one - 0.25*x*x;
- }
- }
- z = x*x;
- r = z*(R02+z*(R03+z*(R04+z*R05)));
- s = one+z*(S01+z*(S02+z*(S03+z*S04)));
- if(ix < 0x3FF00000) { /* |x| < 1.00 */
- return one + z*(-0.25+(r/s));
- } else {
- u = 0.5*x;
- return((one+u)*(one-u)+z*(r/s));
- }
-}
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
-u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
-u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
-u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
-u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
-u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
-u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
-v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
-v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
-v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
-v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
-
-#ifdef __STDC__
- double __ieee754_y0(double x)
-#else
- double __ieee754_y0(x)
- double x;
-#endif
-{
- fd_twoints un;
- double z, s,c,ss,cc,u,v;
- int hx,ix,lx;
-
- un.d = x;
- hx = __HI(un);
- ix = 0x7fffffff&hx;
- lx = __LO(un);
- /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */
- if(ix>=0x7ff00000) return one/(x+x*x);
- if((ix|lx)==0) return -one/zero;
- if(hx<0) return zero/zero;
- if(ix >= 0x40000000) { /* |x| >= 2.0 */
- /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
- * where x0 = x-pi/4
- * Better formula:
- * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
- * = 1/sqrt(2) * (sin(x) + cos(x))
- * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
- * = 1/sqrt(2) * (sin(x) - cos(x))
- * To avoid cancellation, use
- * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
- * to compute the worse one.
- */
- s = fd_sin(x);
- c = fd_cos(x);
- ss = s-c;
- cc = s+c;
- /*
- * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
- * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
- */
- if(ix<0x7fe00000) { /* make sure x+x not overflow */
- z = -fd_cos(x+x);
- if ((s*c)<zero) cc = z/ss;
- else ss = z/cc;
- }
- if(ix>0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x);
- else {
- u = pzero(x); v = qzero(x);
- z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x);
- }
- return z;
- }
- if(ix<=0x3e400000) { /* x < 2**-27 */
- return(u00 + tpi*__ieee754_log(x));
- }
- z = x*x;
- u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
- v = one+z*(v01+z*(v02+z*(v03+z*v04)));
- return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
-}
-
-/* The asymptotic expansions of pzero is
- * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
- * For x >= 2, We approximate pzero by
- * pzero(x) = 1 + (R/S)
- * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
- * S = 1 + pS0*s^2 + ... + pS4*s^10
- * and
- * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
- */
-#ifdef __STDC__
-static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#else
-static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#endif
- 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
- -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
- -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
- -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
- -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
- -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
-};
-#ifdef __STDC__
-static const double pS8[5] = {
-#else
-static double pS8[5] = {
-#endif
- 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
- 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
- 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
- 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
- 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
-};
-
-#ifdef __STDC__
-static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#else
-static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#endif
- -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
- -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
- -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
- -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
- -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
- -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
-};
-#ifdef __STDC__
-static const double pS5[5] = {
-#else
-static double pS5[5] = {
-#endif
- 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
- 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
- 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
- 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
- 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
-};
-
-#ifdef __STDC__
-static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#else
-static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#endif
- -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
- -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
- -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
- -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
- -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
- -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
-};
-#ifdef __STDC__
-static const double pS3[5] = {
-#else
-static double pS3[5] = {
-#endif
- 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
- 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
- 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
- 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
- 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
-};
-
-#ifdef __STDC__
-static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#else
-static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#endif
- -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
- -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
- -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
- -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
- -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
- -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
-};
-#ifdef __STDC__
-static const double pS2[5] = {
-#else
-static double pS2[5] = {
-#endif
- 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
- 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
- 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
- 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
- 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
-};
-
-#ifdef __STDC__
- static double pzero(double x)
-#else
- static double pzero(x)
- double x;
-#endif
-{
-#ifdef __STDC__
- const double *p,*q;
-#else
- double *p,*q;
-#endif
- fd_twoints u;
- double z,r,s;
- int ix;
- u.d = x;
- ix = 0x7fffffff&__HI(u);
- if(ix>=0x40200000) {p = pR8; q= pS8;}
- else if(ix>=0x40122E8B){p = pR5; q= pS5;}
- else if(ix>=0x4006DB6D){p = pR3; q= pS3;}
- else if(ix>=0x40000000){p = pR2; q= pS2;}
- z = one/(x*x);
- r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
- s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
- return one+ r/s;
-}
-
-
-/* For x >= 8, the asymptotic expansions of qzero is
- * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
- * We approximate pzero by
- * qzero(x) = s*(-1.25 + (R/S))
- * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
- * S = 1 + qS0*s^2 + ... + qS5*s^12
- * and
- * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
- */
-#ifdef __STDC__
-static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#else
-static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#endif
- 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
- 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
- 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
- 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
- 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
- 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
-};
-#ifdef __STDC__
-static const double qS8[6] = {
-#else
-static double qS8[6] = {
-#endif
- 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
- 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
- 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
- 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
- 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
- -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
-};
-
-#ifdef __STDC__
-static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#else
-static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#endif
- 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
- 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
- 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
- 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
- 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
- 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
-};
-#ifdef __STDC__
-static const double qS5[6] = {
-#else
-static double qS5[6] = {
-#endif
- 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
- 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
- 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
- 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
- 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
- -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
-};
-
-#ifdef __STDC__
-static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#else
-static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#endif
- 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
- 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
- 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
- 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
- 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
- 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
-};
-#ifdef __STDC__
-static const double qS3[6] = {
-#else
-static double qS3[6] = {
-#endif
- 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
- 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
- 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
- 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
- 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
- -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
-};
-
-#ifdef __STDC__
-static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#else
-static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#endif
- 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
- 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
- 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
- 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
- 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
- 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
-};
-#ifdef __STDC__
-static const double qS2[6] = {
-#else
-static double qS2[6] = {
-#endif
- 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
- 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
- 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
- 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
- 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
- -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
-};
-
-#ifdef __STDC__
- static double qzero(double x)
-#else
- static double qzero(x)
- double x;
-#endif
-{
-#ifdef __STDC__
- const double *p,*q;
-#else
- double *p,*q;
-#endif
- fd_twoints u;
- double s,r,z;
- int ix;
- u.d = x;
- ix = 0x7fffffff&__HI(u);
- if(ix>=0x40200000) {p = qR8; q= qS8;}
- else if(ix>=0x40122E8B){p = qR5; q= qS5;}
- else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
- else if(ix>=0x40000000){p = qR2; q= qS2;}
- z = one/(x*x);
- r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
- s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
- return (-.125 + r/s)/x;
-}
diff --git a/src/extension/script/js/fdlibm/e_j1.c b/src/extension/script/js/fdlibm/e_j1.c
deleted file mode 100644
index 8982ac86a..000000000
--- a/src/extension/script/js/fdlibm/e_j1.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_j1.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_j1(x), __ieee754_y1(x)
- * Bessel function of the first and second kinds of order zero.
- * Method -- j1(x):
- * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
- * 2. Reduce x to |x| since j1(x)=-j1(-x), and
- * for x in (0,2)
- * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
- * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 )
- * for x in (2,inf)
- * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
- * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
- * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
- * as follow:
- * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
- * = 1/sqrt(2) * (sin(x) - cos(x))
- * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
- * = -1/sqrt(2) * (sin(x) + cos(x))
- * (To avoid cancellation, use
- * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
- * to compute the worse one.)
- *
- * 3 Special cases
- * j1(nan)= nan
- * j1(0) = 0
- * j1(inf) = 0
- *
- * Method -- y1(x):
- * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
- * 2. For x<2.
- * Since
- * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
- * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
- * We use the following function to approximate y1,
- * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
- * where for x in [0,2] (abs err less than 2**-65.89)
- * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
- * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5
- * Note: For tiny x, 1/x dominate y1 and hence
- * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
- * 3. For x>=2.
- * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
- * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
- * by method mentioned above.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static double pone(double), qone(double);
-#else
-static double pone(), qone();
-#endif
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-really_big = 1e300,
-one = 1.0,
-invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
-tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
- /* R0/S0 on [0,2] */
-r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
-r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
-r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
-r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
-s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
-s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
-s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
-s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
-s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double __ieee754_j1(double x)
-#else
- double __ieee754_j1(x)
- double x;
-#endif
-{
- fd_twoints un;
- double z, s,c,ss,cc,r,u,v,y;
- int hx,ix;
-
- un.d = x;
- hx = __HI(un);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) return one/x;
- y = fd_fabs(x);
- if(ix >= 0x40000000) { /* |x| >= 2.0 */
- s = fd_sin(y);
- c = fd_cos(y);
- ss = -s-c;
- cc = s-c;
- if(ix<0x7fe00000) { /* make sure y+y not overflow */
- z = fd_cos(y+y);
- if ((s*c)>zero) cc = z/ss;
- else ss = z/cc;
- }
- /*
- * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
- * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
- */
- if(ix>0x48000000) z = (invsqrtpi*cc)/fd_sqrt(y);
- else {
- u = pone(y); v = qone(y);
- z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(y);
- }
- if(hx<0) return -z;
- else return z;
- }
- if(ix<0x3e400000) { /* |x|<2**-27 */
- if(really_big+x>one) return 0.5*x;/* inexact if x!=0 necessary */
- }
- z = x*x;
- r = z*(r00+z*(r01+z*(r02+z*r03)));
- s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
- r *= x;
- return(x*0.5+r/s);
-}
-
-#ifdef __STDC__
-static const double U0[5] = {
-#else
-static double U0[5] = {
-#endif
- -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
- 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
- -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
- 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
- -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
-};
-#ifdef __STDC__
-static const double V0[5] = {
-#else
-static double V0[5] = {
-#endif
- 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
- 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
- 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
- 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
- 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
-};
-
-#ifdef __STDC__
- double __ieee754_y1(double x)
-#else
- double __ieee754_y1(x)
- double x;
-#endif
-{
- fd_twoints un;
- double z, s,c,ss,cc,u,v;
- int hx,ix,lx;
-
- un.d = x;
- hx = __HI(un);
- ix = 0x7fffffff&hx;
- lx = __LO(un);
- /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
- if(ix>=0x7ff00000) return one/(x+x*x);
- if((ix|lx)==0) return -one/zero;
- if(hx<0) return zero/zero;
- if(ix >= 0x40000000) { /* |x| >= 2.0 */
- s = fd_sin(x);
- c = fd_cos(x);
- ss = -s-c;
- cc = s-c;
- if(ix<0x7fe00000) { /* make sure x+x not overflow */
- z = fd_cos(x+x);
- if ((s*c)>zero) cc = z/ss;
- else ss = z/cc;
- }
- /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
- * where x0 = x-3pi/4
- * Better formula:
- * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
- * = 1/sqrt(2) * (sin(x) - cos(x))
- * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
- * = -1/sqrt(2) * (cos(x) + sin(x))
- * To avoid cancellation, use
- * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
- * to compute the worse one.
- */
- if(ix>0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x);
- else {
- u = pone(x); v = qone(x);
- z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x);
- }
- return z;
- }
- if(ix<=0x3c900000) { /* x < 2**-54 */
- return(-tpi/x);
- }
- z = x*x;
- u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
- v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
- return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
-}
-
-/* For x >= 8, the asymptotic expansions of pone is
- * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
- * We approximate pone by
- * pone(x) = 1 + (R/S)
- * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
- * S = 1 + ps0*s^2 + ... + ps4*s^10
- * and
- * | pone(x)-1-R/S | <= 2 ** ( -60.06)
- */
-
-#ifdef __STDC__
-static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#else
-static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#endif
- 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
- 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
- 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
- 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
- 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
- 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
-};
-#ifdef __STDC__
-static const double ps8[5] = {
-#else
-static double ps8[5] = {
-#endif
- 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
- 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
- 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
- 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
- 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
-};
-
-#ifdef __STDC__
-static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#else
-static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#endif
- 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
- 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
- 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
- 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
- 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
- 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
-};
-#ifdef __STDC__
-static const double ps5[5] = {
-#else
-static double ps5[5] = {
-#endif
- 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
- 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
- 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
- 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
- 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
-};
-
-#ifdef __STDC__
-static const double pr3[6] = {
-#else
-static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#endif
- 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
- 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
- 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
- 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
- 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
- 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
-};
-#ifdef __STDC__
-static const double ps3[5] = {
-#else
-static double ps3[5] = {
-#endif
- 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
- 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
- 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
- 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
- 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
-};
-
-#ifdef __STDC__
-static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#else
-static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#endif
- 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
- 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
- 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
- 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
- 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
- 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
-};
-#ifdef __STDC__
-static const double ps2[5] = {
-#else
-static double ps2[5] = {
-#endif
- 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
- 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
- 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
- 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
- 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
-};
-
-#ifdef __STDC__
- static double pone(double x)
-#else
- static double pone(x)
- double x;
-#endif
-{
-#ifdef __STDC__
- const double *p,*q;
-#else
- double *p,*q;
-#endif
- fd_twoints un;
- double z,r,s;
- int ix;
- un.d = x;
- ix = 0x7fffffff&__HI(un);
- if(ix>=0x40200000) {p = pr8; q= ps8;}
- else if(ix>=0x40122E8B){p = pr5; q= ps5;}
- else if(ix>=0x4006DB6D){p = pr3; q= ps3;}
- else if(ix>=0x40000000){p = pr2; q= ps2;}
- z = one/(x*x);
- r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
- s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
- return one+ r/s;
-}
-
-
-/* For x >= 8, the asymptotic expansions of qone is
- * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
- * We approximate pone by
- * qone(x) = s*(0.375 + (R/S))
- * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
- * S = 1 + qs1*s^2 + ... + qs6*s^12
- * and
- * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
- */
-
-#ifdef __STDC__
-static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#else
-static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
-#endif
- 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
- -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
- -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
- -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
- -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
- -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
-};
-#ifdef __STDC__
-static const double qs8[6] = {
-#else
-static double qs8[6] = {
-#endif
- 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
- 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
- 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
- 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
- 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
- -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
-};
-
-#ifdef __STDC__
-static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#else
-static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
-#endif
- -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
- -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
- -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
- -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
- -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
- -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
-};
-#ifdef __STDC__
-static const double qs5[6] = {
-#else
-static double qs5[6] = {
-#endif
- 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
- 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
- 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
- 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
- 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
- -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
-};
-
-#ifdef __STDC__
-static const double qr3[6] = {
-#else
-static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
-#endif
- -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
- -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
- -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
- -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
- -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
- -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
-};
-#ifdef __STDC__
-static const double qs3[6] = {
-#else
-static double qs3[6] = {
-#endif
- 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
- 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
- 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
- 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
- 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
- -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
-};
-
-#ifdef __STDC__
-static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#else
-static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
-#endif
- -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
- -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
- -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
- -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
- -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
- -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
-};
-#ifdef __STDC__
-static const double qs2[6] = {
-#else
-static double qs2[6] = {
-#endif
- 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
- 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
- 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
- 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
- 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
- -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
-};
-
-#ifdef __STDC__
- static double qone(double x)
-#else
- static double qone(x)
- double x;
-#endif
-{
-#ifdef __STDC__
- const double *p,*q;
-#else
- double *p,*q;
-#endif
- fd_twoints un;
- double s,r,z;
- int ix;
- un.d = x;
- ix = 0x7fffffff&__HI(un);
- if(ix>=0x40200000) {p = qr8; q= qs8;}
- else if(ix>=0x40122E8B){p = qr5; q= qs5;}
- else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
- else if(ix>=0x40000000){p = qr2; q= qs2;}
- z = one/(x*x);
- r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
- s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
- return (.375 + r/s)/x;
-}
diff --git a/src/extension/script/js/fdlibm/e_jn.c b/src/extension/script/js/fdlibm/e_jn.c
deleted file mode 100644
index 2b61b4439..000000000
--- a/src/extension/script/js/fdlibm/e_jn.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_jn.c 1.4 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * __ieee754_jn(n, x), __ieee754_yn(n, x)
- * floating point Bessel's function of the 1st and 2nd kind
- * of order n
- *
- * Special cases:
- * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
- * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
- * Note 2. About jn(n,x), yn(n,x)
- * For n=0, j0(x) is called,
- * for n=1, j1(x) is called,
- * for n<x, forward recursion us used starting
- * from values of j0(x) and j1(x).
- * for n>x, a continued fraction approximation to
- * j(n,x)/j(n-1,x) is evaluated and then backward
- * recursion is used starting from a supposed value
- * for j(n,x). The resulting value of j(0,x) is
- * compared with the actual value to correct the
- * supposed value of j(n,x).
- *
- * yn(n,x) is similar in all respects, except
- * that forward recursion is used for all
- * values of n>1.
- *
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
-two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
-one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
-
-static double zero = 0.00000000000000000000e+00;
-
-#ifdef __STDC__
- double __ieee754_jn(int n, double x)
-#else
- double __ieee754_jn(n,x)
- int n; double x;
-#endif
-{
- fd_twoints u;
- int i,hx,ix,lx, sgn;
- double a, b, temp, di;
- double z, w;
-
- /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
- * Thus, J(-n,x) = J(n,-x)
- */
- u.d = x;
- hx = __HI(u);
- ix = 0x7fffffff&hx;
- lx = __LO(u);
- /* if J(n,NaN) is NaN */
- if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
- if(n<0){
- n = -n;
- x = -x;
- hx ^= 0x80000000;
- }
- if(n==0) return(__ieee754_j0(x));
- if(n==1) return(__ieee754_j1(x));
- sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
- x = fd_fabs(x);
- if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */
- b = zero;
- else if((double)n<=x) {
- /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
- if(ix>=0x52D00000) { /* x > 2**302 */
- /* (x >> n**2)
- * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
- * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
- * Let s=sin(x), c=cos(x),
- * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
- *
- * n sin(xn)*sqt2 cos(xn)*sqt2
- * ----------------------------------
- * 0 s-c c+s
- * 1 -s-c -c+s
- * 2 -s+c -c-s
- * 3 s+c c-s
- */
- switch(n&3) {
- case 0: temp = fd_cos(x)+fd_sin(x); break;
- case 1: temp = -fd_cos(x)+fd_sin(x); break;
- case 2: temp = -fd_cos(x)-fd_sin(x); break;
- case 3: temp = fd_cos(x)-fd_sin(x); break;
- }
- b = invsqrtpi*temp/fd_sqrt(x);
- } else {
- a = __ieee754_j0(x);
- b = __ieee754_j1(x);
- for(i=1;i<n;i++){
- temp = b;
- b = b*((double)(i+i)/x) - a; /* avoid underflow */
- a = temp;
- }
- }
- } else {
- if(ix<0x3e100000) { /* x < 2**-29 */
- /* x is tiny, return the first Taylor expansion of J(n,x)
- * J(n,x) = 1/n!*(x/2)^n - ...
- */
- if(n>33) /* underflow */
- b = zero;
- else {
- temp = x*0.5; b = temp;
- for (a=one,i=2;i<=n;i++) {
- a *= (double)i; /* a = n! */
- b *= temp; /* b = (x/2)^n */
- }
- b = b/a;
- }
- } else {
- /* use backward recurrence */
- /* x x^2 x^2
- * J(n,x)/J(n-1,x) = ---- ------ ------ .....
- * 2n - 2(n+1) - 2(n+2)
- *
- * 1 1 1
- * (for large x) = ---- ------ ------ .....
- * 2n 2(n+1) 2(n+2)
- * -- - ------ - ------ -
- * x x x
- *
- * Let w = 2n/x and h=2/x, then the above quotient
- * is equal to the continued fraction:
- * 1
- * = -----------------------
- * 1
- * w - -----------------
- * 1
- * w+h - ---------
- * w+2h - ...
- *
- * To determine how many terms needed, let
- * Q(0) = w, Q(1) = w(w+h) - 1,
- * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
- * When Q(k) > 1e4 good for single
- * When Q(k) > 1e9 good for double
- * When Q(k) > 1e17 good for quadruple
- */
- /* determine k */
- double t,v;
- double q0,q1,h,tmp; int k,m;
- w = (n+n)/(double)x; h = 2.0/(double)x;
- q0 = w; z = w+h; q1 = w*z - 1.0; k=1;
- while(q1<1.0e9) {
- k += 1; z += h;
- tmp = z*q1 - q0;
- q0 = q1;
- q1 = tmp;
- }
- m = n+n;
- for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
- a = t;
- b = one;
- /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
- * Hence, if n*(log(2n/x)) > ...
- * single 8.8722839355e+01
- * double 7.09782712893383973096e+02
- * long double 1.1356523406294143949491931077970765006170e+04
- * then recurrent value may overflow and the result is
- * likely underflow to zero
- */
- tmp = n;
- v = two/x;
- tmp = tmp*__ieee754_log(fd_fabs(v*tmp));
- if(tmp<7.09782712893383973096e+02) {
- for(i=n-1,di=(double)(i+i);i>0;i--){
- temp = b;
- b *= di;
- b = b/x - a;
- a = temp;
- di -= two;
- }
- } else {
- for(i=n-1,di=(double)(i+i);i>0;i--){
- temp = b;
- b *= di;
- b = b/x - a;
- a = temp;
- di -= two;
- /* scale b to avoid spurious overflow */
- if(b>1e100) {
- a /= b;
- t /= b;
- b = one;
- }
- }
- }
- b = (t*__ieee754_j0(x)/b);
- }
- }
- if(sgn==1) return -b; else return b;
-}
-
-#ifdef __STDC__
- double __ieee754_yn(int n, double x)
-#else
- double __ieee754_yn(n,x)
- int n; double x;
-#endif
-{
- fd_twoints u;
- int i,hx,ix,lx;
- int sign;
- double a, b, temp;
-
- u.d = x;
- hx = __HI(u);
- ix = 0x7fffffff&hx;
- lx = __LO(u);
- /* if Y(n,NaN) is NaN */
- if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
- if((ix|lx)==0) return -one/zero;
- if(hx<0) return zero/zero;
- sign = 1;
- if(n<0){
- n = -n;
- sign = 1 - ((n&1)<<1);
- }
- if(n==0) return(__ieee754_y0(x));
- if(n==1) return(sign*__ieee754_y1(x));
- if(ix==0x7ff00000) return zero;
- if(ix>=0x52D00000) { /* x > 2**302 */
- /* (x >> n**2)
- * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
- * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
- * Let s=sin(x), c=cos(x),
- * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
- *
- * n sin(xn)*sqt2 cos(xn)*sqt2
- * ----------------------------------
- * 0 s-c c+s
- * 1 -s-c -c+s
- * 2 -s+c -c-s
- * 3 s+c c-s
- */
- switch(n&3) {
- case 0: temp = fd_sin(x)-fd_cos(x); break;
- case 1: temp = -fd_sin(x)-fd_cos(x); break;
- case 2: temp = -fd_sin(x)+fd_cos(x); break;
- case 3: temp = fd_sin(x)+fd_cos(x); break;
- }
- b = invsqrtpi*temp/fd_sqrt(x);
- } else {
- a = __ieee754_y0(x);
- b = __ieee754_y1(x);
- /* quit if b is -inf */
- u.d = b;
- for(i=1;i<n&&(__HI(u) != 0xfff00000);i++){
- temp = b;
- b = ((double)(i+i)/x)*b - a;
- a = temp;
- }
- }
- if(sign>0) return b; else return -b;
-}
diff --git a/src/extension/script/js/fdlibm/e_lgamma.c b/src/extension/script/js/fdlibm/e_lgamma.c
deleted file mode 100644
index beb3bd932..000000000
--- a/src/extension/script/js/fdlibm/e_lgamma.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_lgamma.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_lgamma(x)
- * Return the logarithm of the Gamma function of x.
- *
- * Method: call __ieee754_lgamma_r
- */
-
-#include "fdlibm.h"
-
-extern int signgam;
-
-#ifdef __STDC__
- double __ieee754_lgamma(double x)
-#else
- double __ieee754_lgamma(x)
- double x;
-#endif
-{
- return __ieee754_lgamma_r(x,&signgam);
-}
diff --git a/src/extension/script/js/fdlibm/e_lgamma_r.c b/src/extension/script/js/fdlibm/e_lgamma_r.c
deleted file mode 100644
index df92e7a26..000000000
--- a/src/extension/script/js/fdlibm/e_lgamma_r.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_lgamma_r.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_lgamma_r(x, signgamp)
- * Reentrant version of the logarithm of the Gamma function
- * with user provide pointer for the sign of Gamma(x).
- *
- * Method:
- * 1. Argument Reduction for 0 < x <= 8
- * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
- * reduce x to a number in [1.5,2.5] by
- * lgamma(1+s) = log(s) + lgamma(s)
- * for example,
- * lgamma(7.3) = log(6.3) + lgamma(6.3)
- * = log(6.3*5.3) + lgamma(5.3)
- * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
- * 2. Polynomial approximation of lgamma around its
- * minimun ymin=1.461632144968362245 to maintain monotonicity.
- * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
- * Let z = x-ymin;
- * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
- * where
- * poly(z) is a 14 degree polynomial.
- * 2. Rational approximation in the primary interval [2,3]
- * We use the following approximation:
- * s = x-2.0;
- * lgamma(x) = 0.5*s + s*P(s)/Q(s)
- * with accuracy
- * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
- * Our algorithms are based on the following observation
- *
- * zeta(2)-1 2 zeta(3)-1 3
- * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
- * 2 3
- *
- * where Euler = 0.5771... is the Euler constant, which is very
- * close to 0.5.
- *
- * 3. For x>=8, we have
- * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
- * (better formula:
- * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
- * Let z = 1/x, then we approximation
- * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
- * by
- * 3 5 11
- * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
- * where
- * |w - f(z)| < 2**-58.74
- *
- * 4. For negative x, since (G is gamma function)
- * -x*G(-x)*G(x) = pi/sin(pi*x),
- * we have
- * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
- * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
- * Hence, for x<0, signgam = sign(sin(pi*x)) and
- * lgamma(x) = log(|Gamma(x)|)
- * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
- * Note: one should avoid compute pi*(-x) directly in the
- * computation of sin(pi*(-x)).
- *
- * 5. Special Cases
- * lgamma(2+s) ~ s*(1-Euler) for tiny s
- * lgamma(1)=lgamma(2)=0
- * lgamma(x) ~ -log(x) for tiny x
- * lgamma(0) = lgamma(inf) = inf
- * lgamma(-integer) = +-inf
- *
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
-half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
-a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
-a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
-a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
-a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
-a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
-a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
-a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
-a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
-a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
-a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
-a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
-a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
-tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
-tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
-/* tt = -(tail of tf) */
-tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
-t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
-t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
-t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
-t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
-t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
-t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
-t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
-t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
-t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
-t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
-t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
-t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
-t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
-t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
-t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
-u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
-u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
-u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
-u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
-u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
-u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
-v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
-v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
-v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
-v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
-v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
-s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
-s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
-s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
-s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
-s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
-s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
-s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
-r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
-r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
-r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
-r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
-r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
-r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
-w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
-w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
-w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
-w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
-w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
-w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
-w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
-
-static double zero= 0.00000000000000000000e+00;
-
-#ifdef __STDC__
- static double sin_pi(double x)
-#else
- static double sin_pi(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y,z;
- int n,ix;
-
- u.d = x;
- ix = 0x7fffffff&__HI(u);
-
- if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0);
- y = -x; /* x is assume negative */
-
- /*
- * argument reduction, make sure inexact flag not raised if input
- * is an integer
- */
- z = fd_floor(y);
- if(z!=y) { /* inexact anyway */
- y *= 0.5;
- y = 2.0*(y - fd_floor(y)); /* y = |x| mod 2.0 */
- n = (int) (y*4.0);
- } else {
- if(ix>=0x43400000) {
- y = zero; n = 0; /* y must be even */
- } else {
- if(ix<0x43300000) z = y+two52; /* exact */
- u.d = z;
- n = __LO(u)&1; /* lower word of z */
- y = n;
- n<<= 2;
- }
- }
- switch (n) {
- case 0: y = __kernel_sin(pi*y,zero,0); break;
- case 1:
- case 2: y = __kernel_cos(pi*(0.5-y),zero); break;
- case 3:
- case 4: y = __kernel_sin(pi*(one-y),zero,0); break;
- case 5:
- case 6: y = -__kernel_cos(pi*(y-1.5),zero); break;
- default: y = __kernel_sin(pi*(y-2.0),zero,0); break;
- }
- return -y;
-}
-
-
-#ifdef __STDC__
- double __ieee754_lgamma_r(double x, int *signgamp)
-#else
- double __ieee754_lgamma_r(x,signgamp)
- double x; int *signgamp;
-#endif
-{
- fd_twoints u;
- double t,y,z,nadj,p,p1,p2,p3,q,r,w;
- int i,hx,lx,ix;
-
- u.d = x;
- hx = __HI(u);
- lx = __LO(u);
-
- /* purge off +-inf, NaN, +-0, and negative arguments */
- *signgamp = 1;
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) return x*x;
- if((ix|lx)==0) return one/zero;
- if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
- if(hx<0) {
- *signgamp = -1;
- return -__ieee754_log(-x);
- } else return -__ieee754_log(x);
- }
- if(hx<0) {
- if(ix>=0x43300000) /* |x|>=2**52, must be -integer */
- return one/zero;
- t = sin_pi(x);
- if(t==zero) return one/zero; /* -integer */
- nadj = __ieee754_log(pi/fd_fabs(t*x));
- if(t<zero) *signgamp = -1;
- x = -x;
- }
-
- /* purge off 1 and 2 */
- if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
- /* for x < 2.0 */
- else if(ix<0x40000000) {
- if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
- r = -__ieee754_log(x);
- if(ix>=0x3FE76944) {y = one-x; i= 0;}
- else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
- else {y = x; i=2;}
- } else {
- r = zero;
- if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
- else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
- else {y=x-one;i=2;}
- }
- switch(i) {
- case 0:
- z = y*y;
- p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
- p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
- p = y*p1+p2;
- r += (p-0.5*y); break;
- case 1:
- z = y*y;
- w = z*y;
- p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
- p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
- p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
- p = z*p1-(tt-w*(p2+y*p3));
- r += (tf + p); break;
- case 2:
- p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
- p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
- r += (-0.5*y + p1/p2);
- }
- }
- else if(ix<0x40200000) { /* x < 8.0 */
- i = (int)x;
- t = zero;
- y = x-(double)i;
- p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
- q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
- r = half*y+p/q;
- z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
- switch(i) {
- case 7: z *= (y+6.0); /* FALLTHRU */
- case 6: z *= (y+5.0); /* FALLTHRU */
- case 5: z *= (y+4.0); /* FALLTHRU */
- case 4: z *= (y+3.0); /* FALLTHRU */
- case 3: z *= (y+2.0); /* FALLTHRU */
- r += __ieee754_log(z); break;
- }
- /* 8.0 <= x < 2**58 */
- } else if (ix < 0x43900000) {
- t = __ieee754_log(x);
- z = one/x;
- y = z*z;
- w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
- r = (x-half)*(t-one)+w;
- } else
- /* 2**58 <= x <= inf */
- r = x*(__ieee754_log(x)-one);
- if(hx<0) r = nadj - r;
- return r;
-}
diff --git a/src/extension/script/js/fdlibm/e_log.c b/src/extension/script/js/fdlibm/e_log.c
deleted file mode 100644
index 8645d6efd..000000000
--- a/src/extension/script/js/fdlibm/e_log.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_log.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_log(x)
- * Return the logrithm of x
- *
- * Method :
- * 1. Argument Reduction: find k and f such that
- * x = 2^k * (1+f),
- * where sqrt(2)/2 < 1+f < sqrt(2) .
- *
- * 2. Approximation of log(1+f).
- * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
- * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
- * = 2s + s*R
- * We use a special Reme algorithm on [0,0.1716] to generate
- * a polynomial of degree 14 to approximate R The maximum error
- * of this polynomial approximation is bounded by 2**-58.45. In
- * other words,
- * 2 4 6 8 10 12 14
- * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
- * (the values of Lg1 to Lg7 are listed in the program)
- * and
- * | 2 14 | -58.45
- * | Lg1*s +...+Lg7*s - R(z) | <= 2
- * | |
- * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
- * In order to guarantee error in log below 1ulp, we compute log
- * by
- * log(1+f) = f - s*(f - R) (if f is not too large)
- * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
- *
- * 3. Finally, log(x) = k*ln2 + log(1+f).
- * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
- * Here ln2 is split into two floating point number:
- * ln2_hi + ln2_lo,
- * where n*ln2_hi is always exact for |n| < 2000.
- *
- * Special cases:
- * log(x) is NaN with signal if x < 0 (including -INF) ;
- * log(+INF) is +INF; log(0) is -INF with signal;
- * log(NaN) is that NaN with no signal.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
-ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
-two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
-Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
-Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
-Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
-Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
-Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
-Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
-Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double __ieee754_log(double x)
-#else
- double __ieee754_log(x)
- double x;
-#endif
-{
- fd_twoints u;
- double hfsq,f,s,z,R,w,t1,t2,dk;
- int k,hx,i,j;
- unsigned lx;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- lx = __LO(u); /* low word of x */
-
- k=0;
- if (hx < 0x00100000) { /* x < 2**-1022 */
- if (((hx&0x7fffffff)|lx)==0)
- return -two54/zero; /* log(+-0)=-inf */
- if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 54; x *= two54; /* subnormal number, scale up x */
- u.d = x;
- hx = __HI(u); /* high word of x */
- }
- if (hx >= 0x7ff00000) return x+x;
- k += (hx>>20)-1023;
- hx &= 0x000fffff;
- i = (hx+0x95f64)&0x100000;
- u.d = x;
- __HI(u) = hx|(i^0x3ff00000); /* normalize x or x/2 */
- x = u.d;
- k += (i>>20);
- f = x-1.0;
- if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
- if(f==zero) {
- if(k==0) return zero; else {dk=(double)k;
- return dk*ln2_hi+dk*ln2_lo;}
- }
- R = f*f*(0.5-0.33333333333333333*f);
- if(k==0) return f-R; else {dk=(double)k;
- return dk*ln2_hi-((R-dk*ln2_lo)-f);}
- }
- s = f/(2.0+f);
- dk = (double)k;
- z = s*s;
- i = hx-0x6147a;
- w = z*z;
- j = 0x6b851-hx;
- t1= w*(Lg2+w*(Lg4+w*Lg6));
- t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
- i |= j;
- R = t2+t1;
- if(i>0) {
- hfsq=0.5*f*f;
- if(k==0) return f-(hfsq-s*(hfsq+R)); else
- return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
- } else {
- if(k==0) return f-s*(f-R); else
- return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
- }
-}
diff --git a/src/extension/script/js/fdlibm/e_log10.c b/src/extension/script/js/fdlibm/e_log10.c
deleted file mode 100644
index 5f88f4b4c..000000000
--- a/src/extension/script/js/fdlibm/e_log10.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_log10.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_log10(x)
- * Return the base 10 logarithm of x
- *
- * Method :
- * Let log10_2hi = leading 40 bits of log10(2) and
- * log10_2lo = log10(2) - log10_2hi,
- * ivln10 = 1/log(10) rounded.
- * Then
- * n = ilogb(x),
- * if(n<0) n = n+1;
- * x = scalbn(x,-n);
- * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
- *
- * Note 1:
- * To guarantee log10(10**n)=n, where 10**n is normal, the rounding
- * mode must set to Round-to-Nearest.
- * Note 2:
- * [1/log(10)] rounded to 53 bits has error .198 ulps;
- * log10 is monotonic at all binary break points.
- *
- * Special cases:
- * log10(x) is NaN with signal if x < 0;
- * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
- * log10(NaN) is that NaN with no signal;
- * log10(10**N) = N for N=0,1,...,22.
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following constants.
- * The decimal values may be used, provided that the compiler will convert
- * from decimal to binary accurately enough to produce the hexadecimal values
- * shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
-log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
-log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double __ieee754_log10(double x)
-#else
- double __ieee754_log10(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y,z;
- int i,k,hx;
- unsigned lx;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- lx = __LO(u); /* low word of x */
-
- k=0;
- if (hx < 0x00100000) { /* x < 2**-1022 */
- if (((hx&0x7fffffff)|lx)==0)
- return -two54/zero; /* log(+-0)=-inf */
- if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 54; x *= two54; /* subnormal number, scale up x */
- u.d = x;
- hx = __HI(u); /* high word of x */
- }
- if (hx >= 0x7ff00000) return x+x;
- k += (hx>>20)-1023;
- i = ((unsigned)k&0x80000000)>>31;
- hx = (hx&0x000fffff)|((0x3ff-i)<<20);
- y = (double)(k+i);
- u.d = x;
- __HI(u) = hx;
- x = u.d;
- z = y*log10_2lo + ivln10*__ieee754_log(x);
- return z+y*log10_2hi;
-}
diff --git a/src/extension/script/js/fdlibm/e_pow.c b/src/extension/script/js/fdlibm/e_pow.c
deleted file mode 100644
index 18c8d0695..000000000
--- a/src/extension/script/js/fdlibm/e_pow.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_pow.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_pow(x,y) return x**y
- *
- * n
- * Method: Let x = 2 * (1+f)
- * 1. Compute and return log2(x) in two pieces:
- * log2(x) = w1 + w2,
- * where w1 has 53-24 = 29 bit trailing zeros.
- * 2. Perform y*log2(x) = n+y' by simulating muti-precision
- * arithmetic, where |y'|<=0.5.
- * 3. Return x**y = 2**n*exp(y'*log2)
- *
- * Special cases:
- * 1. (anything) ** 0 is 1
- * 2. (anything) ** 1 is itself
- * 3. (anything) ** NAN is NAN
- * 4. NAN ** (anything except 0) is NAN
- * 5. +-(|x| > 1) ** +INF is +INF
- * 6. +-(|x| > 1) ** -INF is +0
- * 7. +-(|x| < 1) ** +INF is +0
- * 8. +-(|x| < 1) ** -INF is +INF
- * 9. +-1 ** +-INF is NAN
- * 10. +0 ** (+anything except 0, NAN) is +0
- * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
- * 12. +0 ** (-anything except 0, NAN) is +INF
- * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
- * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
- * 15. +INF ** (+anything except 0,NAN) is +INF
- * 16. +INF ** (-anything except 0,NAN) is +0
- * 17. -INF ** (anything) = -0 ** (-anything)
- * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
- * 19. (-anything except 0 and inf) ** (non-integer) is NAN
- *
- * Accuracy:
- * pow(x,y) returns x**y nearly rounded. In particular
- * pow(integer,integer)
- * always returns the correct integer provided it is
- * representable.
- *
- * Constants :
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#if defined(_MSC_VER)
-/* Microsoft Compiler */
-#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
-#endif
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-bp[] = {1.0, 1.5,},
-dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
-dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
-zero = 0.0,
-one = 1.0,
-two = 2.0,
-two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
-really_big = 1.0e300,
-tiny = 1.0e-300,
- /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
-L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
-L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
-L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
-L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
-L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
-L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
-P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
-P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
-P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
-P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
-P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
-lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
-lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
-lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
-ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
-cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
-cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
-cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
-ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
-ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
-ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
-
-#ifdef __STDC__
- double __ieee754_pow(double x, double y)
-#else
- double __ieee754_pow(x,y)
- double x, y;
-#endif
-{
- fd_twoints ux, uy, uz;
- double y1,t1,p_h,t,z,ax;
- double z_h,z_l,p_l;
- double t2,r,s,u,v,w;
- int i,j,k,yisint,n;
- int hx,hy,ix,iy;
- unsigned lx,ly;
-
- ux.d = x; uy.d = y;
- hx = __HI(ux); lx = __LO(ux);
- hy = __HI(uy); ly = __LO(uy);
- ix = hx&0x7fffffff; iy = hy&0x7fffffff;
-
- /* y==zero: x**0 = 1 */
- if((iy|ly)==0) return one;
-
- /* +-NaN return x+y */
- if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
- iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
- return x+y;
-
- /* determine if y is an odd int when x < 0
- * yisint = 0 ... y is not an integer
- * yisint = 1 ... y is an odd int
- * yisint = 2 ... y is an even int
- */
- yisint = 0;
- if(hx<0) {
- if(iy>=0x43400000) yisint = 2; /* even integer y */
- else if(iy>=0x3ff00000) {
- k = (iy>>20)-0x3ff; /* exponent */
- if(k>20) {
- j = ly>>(52-k);
- if((j<<(52-k))==(int)ly) yisint = 2-(j&1);
- } else if(ly==0) {
- j = iy>>(20-k);
- if((j<<(20-k))==iy) yisint = 2-(j&1);
- }
- }
- }
-
- /* special value of y */
- if(ly==0) {
- if (iy==0x7ff00000) { /* y is +-inf */
- if(((ix-0x3ff00000)|lx)==0)
-#ifdef _WIN32
-/* VC++ optimizer reduces y - y to 0 */
- return y / y;
-#else
- return y - y; /* inf**+-1 is NaN */
-#endif
- else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
- return (hy>=0)? y: zero;
- else /* (|x|<1)**-,+inf = inf,0 */
- return (hy<0)?-y: zero;
- }
- if(iy==0x3ff00000) { /* y is +-1 */
- if(hy<0) return one/x; else return x;
- }
- if(hy==0x40000000) return x*x; /* y is 2 */
- if(hy==0x3fe00000) { /* y is 0.5 */
- if(hx>=0) /* x >= +0 */
- return fd_sqrt(x);
- }
- }
-
- ax = fd_fabs(x);
- /* special value of x */
- if(lx==0) {
- if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
- z = ax; /*x is +-0,+-inf,+-1*/
- if(hy<0) z = one/z; /* z = (1/|x|) */
- if(hx<0) {
- if(((ix-0x3ff00000)|yisint)==0) {
- z = (z-z)/(z-z); /* (-1)**non-int is NaN */
- } else if(yisint==1) {
-#ifdef HPUX
- uz.d = z;
- __HI(uz) ^= 1<<31; /* some HPUXes cannot negate 0.. */
- z = uz.d;
-#else
- z = -z; /* (x<0)**odd = -(|x|**odd) */
-#endif
- }
- }
- return z;
- }
- }
-
- /* (x<0)**(non-int) is NaN */
- if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x);
-
- /* |y| is really_big */
- if(iy>0x41e00000) { /* if |y| > 2**31 */
- if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
- if(ix<=0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny;
- if(ix>=0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny;
- }
- /* over/underflow if x is not close to one */
- if(ix<0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny;
- if(ix>0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny;
- /* now |1-x| is tiny <= 2**-20, suffice to compute
- log(x) by x-x^2/2+x^3/3-x^4/4 */
- t = x-1; /* t has 20 trailing zeros */
- w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
- u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
- v = t*ivln2_l-w*ivln2;
- t1 = u+v;
- uz.d = t1;
- __LO(uz) = 0;
- t1 = uz.d;
- t2 = v-(t1-u);
- } else {
- double s_h,t_h;
- double s2,s_l,t_l;
- n = 0;
- /* take care subnormal number */
- if(ix<0x00100000)
- {ax *= two53; n -= 53; uz.d = ax; ix = __HI(uz); }
- n += ((ix)>>20)-0x3ff;
- j = ix&0x000fffff;
- /* determine interval */
- ix = j|0x3ff00000; /* normalize ix */
- if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
- else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
- else {k=0;n+=1;ix -= 0x00100000;}
- uz.d = ax;
- __HI(uz) = ix;
- ax = uz.d;
-
- /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
- u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
- v = one/(ax+bp[k]);
- s = u*v;
- s_h = s;
- uz.d = s_h;
- __LO(uz) = 0;
- s_h = uz.d;
- /* t_h=ax+bp[k] High */
- t_h = zero;
- uz.d = t_h;
- __HI(uz)=((ix>>1)|0x20000000)+0x00080000+(k<<18);
- t_h = uz.d;
- t_l = ax - (t_h-bp[k]);
- s_l = v*((u-s_h*t_h)-s_h*t_l);
- /* compute log(ax) */
- s2 = s*s;
- r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
- r += s_l*(s_h+s);
- s2 = s_h*s_h;
- t_h = 3.0+s2+r;
- uz.d = t_h;
- __LO(uz) = 0;
- t_h = uz.d;
- t_l = r-((t_h-3.0)-s2);
- /* u+v = s*(1+...) */
- u = s_h*t_h;
- v = s_l*t_h+t_l*s;
- /* 2/(3log2)*(s+...) */
- p_h = u+v;
- uz.d = p_h;
- __LO(uz) = 0;
- p_h = uz.d;
- p_l = v-(p_h-u);
- z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
- z_l = cp_l*p_h+p_l*cp+dp_l[k];
- /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
- t = (double)n;
- t1 = (((z_h+z_l)+dp_h[k])+t);
- uz.d = t1;
- __LO(uz) = 0;
- t1 = uz.d;
- t2 = z_l-(((t1-t)-dp_h[k])-z_h);
- }
-
- s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
- if((((hx>>31)+1)|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
-
- /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
- y1 = y;
- uy.d = y1;
- __LO(uy) = 0;
- y1 = uy.d;
- p_l = (y-y1)*t1+y*t2;
- p_h = y1*t1;
- z = p_l+p_h;
- uz.d = z;
- j = __HI(uz);
- i = __LO(uz);
-
- if (j>=0x40900000) { /* z >= 1024 */
- if(((j-0x40900000)|i)!=0) /* if z > 1024 */
- return s*really_big*really_big; /* overflow */
- else {
- if(p_l+ovt>z-p_h) return s*really_big*really_big; /* overflow */
- }
- } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
- if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
- return s*tiny*tiny; /* underflow */
- else {
- if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
- }
- }
- /*
- * compute 2**(p_h+p_l)
- */
- i = j&0x7fffffff;
- k = (i>>20)-0x3ff;
- n = 0;
- if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
- n = j+(0x00100000>>(k+1));
- k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
- t = zero;
- uz.d = t;
- __HI(uz) = (n&~(0x000fffff>>k));
- t = uz.d;
- n = ((n&0x000fffff)|0x00100000)>>(20-k);
- if(j<0) n = -n;
- p_h -= t;
- }
- t = p_l+p_h;
- uz.d = t;
- __LO(uz) = 0;
- t = uz.d;
- u = t*lg2_h;
- v = (p_l-(t-p_h))*lg2+t*lg2_l;
- z = u+v;
- w = v-(z-u);
- t = z*z;
- t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- r = (z*t1)/(t1-two)-(w+z*w);
- z = one-(r-z);
- uz.d = z;
- j = __HI(uz);
- j += (n<<20);
- if((j>>20)<=0) z = fd_scalbn(z,n); /* subnormal output */
- else { uz.d = z; __HI(uz) += (n<<20); z = uz.d; }
- return s*z;
-}
diff --git a/src/extension/script/js/fdlibm/e_rem_pio2.c b/src/extension/script/js/fdlibm/e_rem_pio2.c
deleted file mode 100644
index 6f9423551..000000000
--- a/src/extension/script/js/fdlibm/e_rem_pio2.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_rem_pio2.c 1.4 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* __ieee754_rem_pio2(x,y)
- *
- * return the remainder of x rem pi/2 in y[0]+y[1]
- * use __kernel_rem_pio2()
- */
-
-#include "fdlibm.h"
-
-/*
- * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
- */
-#ifdef __STDC__
-static const int two_over_pi[] = {
-#else
-static int two_over_pi[] = {
-#endif
-0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
-0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
-0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
-0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
-0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
-0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
-0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
-0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
-0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
-0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
-0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
-};
-
-#ifdef __STDC__
-static const int npio2_hw[] = {
-#else
-static int npio2_hw[] = {
-#endif
-0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
-0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
-0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
-0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
-0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
-0x404858EB, 0x404921FB,
-};
-
-/*
- * invpio2: 53 bits of 2/pi
- * pio2_1: first 33 bit of pi/2
- * pio2_1t: pi/2 - pio2_1
- * pio2_2: second 33 bit of pi/2
- * pio2_2t: pi/2 - (pio2_1+pio2_2)
- * pio2_3: third 33 bit of pi/2
- * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
- */
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
-half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
-invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
-pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
-pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
-pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
-pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
-pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
-pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
-
-#ifdef __STDC__
- int __ieee754_rem_pio2(double x, double *y)
-#else
- int __ieee754_rem_pio2(x,y)
- double x,y[];
-#endif
-{
- fd_twoints u, ux, uz;
- double z,w,t,r,fn;
- double tx[3];
- int e0,i,j,nx,n,ix,hx;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- ix = hx&0x7fffffff;
- if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
- {y[0] = x; y[1] = 0; return 0;}
- if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
- if(hx>0) {
- z = x - pio2_1;
- if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
- y[0] = z - pio2_1t;
- y[1] = (z-y[0])-pio2_1t;
- } else { /* near pi/2, use 33+33+53 bit pi */
- z -= pio2_2;
- y[0] = z - pio2_2t;
- y[1] = (z-y[0])-pio2_2t;
- }
- return 1;
- } else { /* negative x */
- z = x + pio2_1;
- if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
- y[0] = z + pio2_1t;
- y[1] = (z-y[0])+pio2_1t;
- } else { /* near pi/2, use 33+33+53 bit pi */
- z += pio2_2;
- y[0] = z + pio2_2t;
- y[1] = (z-y[0])+pio2_2t;
- }
- return -1;
- }
- }
- if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
- t = fd_fabs(x);
- n = (int) (t*invpio2+half);
- fn = (double)n;
- r = t-fn*pio2_1;
- w = fn*pio2_1t; /* 1st round good to 85 bit */
- if(n<32&&ix!=npio2_hw[n-1]) {
- y[0] = r-w; /* quick check no cancellation */
- } else {
- j = ix>>20;
- y[0] = r-w;
- u.d = y[0];
- i = j-(((__HI(u))>>20)&0x7ff);
- if(i>16) { /* 2nd iteration needed, good to 118 */
- t = r;
- w = fn*pio2_2;
- r = t-w;
- w = fn*pio2_2t-((t-r)-w);
- y[0] = r-w;
- u.d = y[0];
- i = j-(((__HI(u))>>20)&0x7ff);
- if(i>49) { /* 3rd iteration need, 151 bits acc */
- t = r; /* will cover all possible cases */
- w = fn*pio2_3;
- r = t-w;
- w = fn*pio2_3t-((t-r)-w);
- y[0] = r-w;
- }
- }
- }
- y[1] = (r-y[0])-w;
- if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
- else return n;
- }
- /*
- * all other (large) arguments
- */
- if(ix>=0x7ff00000) { /* x is inf or NaN */
- y[0]=y[1]=x-x; return 0;
- }
- /* set z = scalbn(|x|,ilogb(x)-23) */
- ux.d = x; uz.d = z;
- __LO(uz) = __LO(ux);
- z = uz.d;
- e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */
- uz.d = z;
- __HI(uz) = ix - (e0<<20);
- z = uz.d;
- for(i=0;i<2;i++) {
- tx[i] = (double)((int)(z));
- z = (z-tx[i])*two24;
- }
- tx[2] = z;
- nx = 3;
- while(tx[nx-1]==zero) nx--; /* skip zero term */
- n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
- if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
- return n;
-}
diff --git a/src/extension/script/js/fdlibm/e_remainder.c b/src/extension/script/js/fdlibm/e_remainder.c
deleted file mode 100644
index de40f0c2a..000000000
--- a/src/extension/script/js/fdlibm/e_remainder.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_remainder.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_remainder(x,p)
- * Return :
- * returns x REM p = x - [x/p]*p as if in infinite
- * precise arithmetic, where [x/p] is the (infinite bit)
- * integer nearest x/p (in half way case choose the even one).
- * Method :
- * Based on fmod() return x-[x/p]chopped*p exactlp.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double zero = 0.0;
-#else
-static double zero = 0.0;
-#endif
-
-
-#ifdef __STDC__
- double __ieee754_remainder(double x, double p)
-#else
- double __ieee754_remainder(x,p)
- double x,p;
-#endif
-{
- fd_twoints u;
- int hx,hp;
- unsigned sx,lx,lp;
- double p_half;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- lx = __LO(u); /* low word of x */
- u.d = p;
- hp = __HI(u); /* high word of p */
- lp = __LO(u); /* low word of p */
- sx = hx&0x80000000;
- hp &= 0x7fffffff;
- hx &= 0x7fffffff;
-
- /* purge off exception values */
- if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
- if((hx>=0x7ff00000)|| /* x not finite */
- ((hp>=0x7ff00000)&& /* p is NaN */
- (((hp-0x7ff00000)|lp)!=0)))
- return (x*p)/(x*p);
-
-
- if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
- if (((hx-hp)|(lx-lp))==0) return zero*x;
- x = fd_fabs(x);
- p = fd_fabs(p);
- if (hp<0x00200000) {
- if(x+x>p) {
- x-=p;
- if(x+x>=p) x -= p;
- }
- } else {
- p_half = 0.5*p;
- if(x>p_half) {
- x-=p;
- if(x>=p_half) x -= p;
- }
- }
- u.d = x;
- __HI(u) ^= sx;
- x = u.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/e_scalb.c b/src/extension/script/js/fdlibm/e_scalb.c
deleted file mode 100644
index 621704ea0..000000000
--- a/src/extension/script/js/fdlibm/e_scalb.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_scalb.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * __ieee754_scalb(x, fn) is provide for
- * passing various standard test suite. One
- * should use scalbn() instead.
- */
-
-#include "fdlibm.h"
-
-#ifdef _SCALB_INT
-#ifdef __STDC__
- double __ieee754_scalb(double x, int fn)
-#else
- double __ieee754_scalb(x,fn)
- double x; int fn;
-#endif
-#else
-#ifdef __STDC__
- double __ieee754_scalb(double x, double fn)
-#else
- double __ieee754_scalb(x,fn)
- double x, fn;
-#endif
-#endif
-{
-#ifdef _SCALB_INT
- return fd_scalbn(x,fn);
-#else
- if (fd_isnan(x)||fd_isnan(fn)) return x*fn;
- if (!fd_finite(fn)) {
- if(fn>0.0) return x*fn;
- else return x/(-fn);
- }
- if (fd_rint(fn)!=fn) return (fn-fn)/(fn-fn);
- if ( fn > 65000.0) return fd_scalbn(x, 65000);
- if (-fn > 65000.0) return fd_scalbn(x,-65000);
- return fd_scalbn(x,(int)fn);
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/e_sinh.c b/src/extension/script/js/fdlibm/e_sinh.c
deleted file mode 100644
index 98ab9b5a3..000000000
--- a/src/extension/script/js/fdlibm/e_sinh.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)e_sinh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_sinh(x)
- * Method :
- * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
- * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
- * 2.
- * E + E/(E+1)
- * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
- * 2
- *
- * 22 <= x <= lnovft : sinh(x) := exp(x)/2
- * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
- * ln2ovft < x : sinh(x) := x*shuge (overflow)
- *
- * Special cases:
- * sinh(x) is |x| if x is +INF, -INF, or NaN.
- * only sinh(0)=0 is exact for finite x.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double one = 1.0, shuge = 1.0e307;
-#else
-static double one = 1.0, shuge = 1.0e307;
-#endif
-
-#ifdef __STDC__
- double __ieee754_sinh(double x)
-#else
- double __ieee754_sinh(x)
- double x;
-#endif
-{
- fd_twoints u;
- double t,w,h;
- int ix,jx;
- unsigned lx;
-
- /* High word of |x|. */
- u.d = x;
- jx = __HI(u);
- ix = jx&0x7fffffff;
-
- /* x is INF or NaN */
- if(ix>=0x7ff00000) return x+x;
-
- h = 0.5;
- if (jx<0) h = -h;
- /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
- if (ix < 0x40360000) { /* |x|<22 */
- if (ix<0x3e300000) /* |x|<2**-28 */
- if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
- t = fd_expm1(fd_fabs(x));
- if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
- return h*(t+t/(t+one));
- }
-
- /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
- if (ix < 0x40862E42) return h*__ieee754_exp(fd_fabs(x));
-
- /* |x| in [log(maxdouble), overflowthresold] */
- lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
- if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) {
- w = __ieee754_exp(0.5*fd_fabs(x));
- t = h*w;
- return t*w;
- }
-
- /* |x| > overflowthresold, sinh(x) overflow */
- return x*shuge;
-}
diff --git a/src/extension/script/js/fdlibm/e_sqrt.c b/src/extension/script/js/fdlibm/e_sqrt.c
deleted file mode 100644
index 91802839b..000000000
--- a/src/extension/script/js/fdlibm/e_sqrt.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* @(#)e_sqrt.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_sqrt(x)
- * Return correctly rounded sqrt.
- * ------------------------------------------
- * | Use the hardware sqrt if you have one |
- * ------------------------------------------
- * Method:
- * Bit by bit method using integer arithmetic. (Slow, but portable)
- * 1. Normalization
- * Scale x to y in [1,4) with even powers of 2:
- * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
- * sqrt(y) = 2^k * sqrt(x)
- * 2. Bit by bit computation
- * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
- * i 0
- * i+1 2
- * s = 2*q , and y = 2 * ( y - q ). (1)
- * i i i i
- *
- * To compute q from q , one checks whether
- * i+1 i
- *
- * -(i+1) 2
- * (q + 2 ) <= y. (2)
- * i
- * -(i+1)
- * If (2) is false, then q = q ; otherwise q = q + 2 .
- * i+1 i i+1 i
- *
- * With some algebric manipulation, it is not difficult to see
- * that (2) is equivalent to
- * -(i+1)
- * s + 2 <= y (3)
- * i i
- *
- * The advantage of (3) is that s and y can be computed by
- * i i
- * the following recurrence formula:
- * if (3) is false
- *
- * s = s , y = y ; (4)
- * i+1 i i+1 i
- *
- * otherwise,
- * -i -(i+1)
- * s = s + 2 , y = y - s - 2 (5)
- * i+1 i i+1 i i
- *
- * One may easily use induction to prove (4) and (5).
- * Note. Since the left hand side of (3) contain only i+2 bits,
- * it does not necessary to do a full (53-bit) comparison
- * in (3).
- * 3. Final rounding
- * After generating the 53 bits result, we compute one more bit.
- * Together with the remainder, we can decide whether the
- * result is exact, bigger than 1/2ulp, or less than 1/2ulp
- * (it will never equal to 1/2ulp).
- * The rounding mode can be detected by checking whether
- * huge + tiny is equal to huge, and whether huge - tiny is
- * equal to huge for some floating point number "huge" and "tiny".
- *
- * Special cases:
- * sqrt(+-0) = +-0 ... exact
- * sqrt(inf) = inf
- * sqrt(-ve) = NaN ... with invalid signal
- * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
- *
- * Other methods : see the appended file at the end of the program below.
- *---------------
- */
-
-#include "fdlibm.h"
-
-#if defined(_MSC_VER)
-/* Microsoft Compiler */
-#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
-#endif
-
-#ifdef __STDC__
-static const double one = 1.0, tiny=1.0e-300;
-#else
-static double one = 1.0, tiny=1.0e-300;
-#endif
-
-#ifdef __STDC__
- double __ieee754_sqrt(double x)
-#else
- double __ieee754_sqrt(x)
- double x;
-#endif
-{
- fd_twoints u;
- double z;
- int sign = (int)0x80000000;
- unsigned r,t1,s1,ix1,q1;
- int ix0,s0,q,m,t,i;
-
- u.d = x;
- ix0 = __HI(u); /* high word of x */
- ix1 = __LO(u); /* low word of x */
-
- /* take care of Inf and NaN */
- if((ix0&0x7ff00000)==0x7ff00000) {
- return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
- sqrt(-inf)=sNaN */
- }
- /* take care of zero */
- if(ix0<=0) {
- if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
- else if(ix0<0)
- return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
- }
- /* normalize x */
- m = (ix0>>20);
- if(m==0) { /* subnormal x */
- while(ix0==0) {
- m -= 21;
- ix0 |= (ix1>>11); ix1 <<= 21;
- }
- for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
- m -= i-1;
- ix0 |= (ix1>>(32-i));
- ix1 <<= i;
- }
- m -= 1023; /* unbias exponent */
- ix0 = (ix0&0x000fffff)|0x00100000;
- if(m&1){ /* odd m, double x to make it even */
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- }
- m >>= 1; /* m = [m/2] */
-
- /* generate sqrt(x) bit by bit */
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
- r = 0x00200000; /* r = moving bit from right to left */
-
- while(r!=0) {
- t = s0+r;
- if(t<=ix0) {
- s0 = t+r;
- ix0 -= t;
- q += r;
- }
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- r>>=1;
- }
-
- r = sign;
- while(r!=0) {
- t1 = s1+r;
- t = s0;
- if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
- s1 = t1+r;
- if(((int)(t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
- ix0 -= t;
- if (ix1 < t1) ix0 -= 1;
- ix1 -= t1;
- q1 += r;
- }
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- r>>=1;
- }
-
- /* use floating add to find out rounding direction */
- if((ix0|ix1)!=0) {
- z = one-tiny; /* trigger inexact flag */
- if (z>=one) {
- z = one+tiny;
- if (q1==(unsigned)0xffffffff) { q1=0; q += 1;}
- else if (z>one) {
- if (q1==(unsigned)0xfffffffe) q+=1;
- q1+=2;
- } else
- q1 += (q1&1);
- }
- }
- ix0 = (q>>1)+0x3fe00000;
- ix1 = q1>>1;
- if ((q&1)==1) ix1 |= sign;
- ix0 += (m <<20);
- u.d = z;
- __HI(u) = ix0;
- __LO(u) = ix1;
- z = u.d;
- return z;
-}
-
-/*
-Other methods (use floating-point arithmetic)
--------------
-(This is a copy of a drafted paper by Prof W. Kahan
-and K.C. Ng, written in May, 1986)
-
- Two algorithms are given here to implement sqrt(x)
- (IEEE double precision arithmetic) in software.
- Both supply sqrt(x) correctly rounded. The first algorithm (in
- Section A) uses newton iterations and involves four divisions.
- The second one uses reciproot iterations to avoid division, but
- requires more multiplications. Both algorithms need the ability
- to chop results of arithmetic operations instead of round them,
- and the INEXACT flag to indicate when an arithmetic operation
- is executed exactly with no roundoff error, all part of the
- standard (IEEE 754-1985). The ability to perform shift, add,
- subtract and logical AND operations upon 32-bit words is needed
- too, though not part of the standard.
-
-A. sqrt(x) by Newton Iteration
-
- (1) Initial approximation
-
- Let x0 and x1 be the leading and the trailing 32-bit words of
- a floating point number x (in IEEE double format) respectively
-
- 1 11 52 ...widths
- ------------------------------------------------------
- x: |s| e | f |
- ------------------------------------------------------
- msb lsb msb lsb ...order
-
-
- ------------------------ ------------------------
- x0: |s| e | f1 | x1: | f2 |
- ------------------------ ------------------------
-
- By performing shifts and subtracts on x0 and x1 (both regarded
- as integers), we obtain an 8-bit approximation of sqrt(x) as
- follows.
-
- k := (x0>>1) + 0x1ff80000;
- y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
- Here k is a 32-bit integer and T1[] is an integer array containing
- correction terms. Now magically the floating value of y (y's
- leading 32-bit word is y0, the value of its trailing word is 0)
- approximates sqrt(x) to almost 8-bit.
-
- Value of T1:
- static int T1[32]= {
- 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
- 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
- 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
- 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
-
- (2) Iterative refinement
-
- Apply Heron's rule three times to y, we have y approximates
- sqrt(x) to within 1 ulp (Unit in the Last Place):
-
- y := (y+x/y)/2 ... almost 17 sig. bits
- y := (y+x/y)/2 ... almost 35 sig. bits
- y := y-(y-x/y)/2 ... within 1 ulp
-
-
- Remark 1.
- Another way to improve y to within 1 ulp is:
-
- y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
- y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
-
- 2
- (x-y )*y
- y := y + 2* ---------- ...within 1 ulp
- 2
- 3y + x
-
-
- This formula has one division fewer than the one above; however,
- it requires more multiplications and additions. Also x must be
- scaled in advance to avoid spurious overflow in evaluating the
- expression 3y*y+x. Hence it is not recommended uless division
- is slow. If division is very slow, then one should use the
- reciproot algorithm given in section B.
-
- (3) Final adjustment
-
- By twiddling y's last bit it is possible to force y to be
- correctly rounded according to the prevailing rounding mode
- as follows. Let r and i be copies of the rounding mode and
- inexact flag before entering the square root program. Also we
- use the expression y+-ulp for the next representable floating
- numbers (up and down) of y. Note that y+-ulp = either fixed
- point y+-1, or multiply y by nextafter(1,+-inf) in chopped
- mode.
-
- I := FALSE; ... reset INEXACT flag I
- R := RZ; ... set rounding mode to round-toward-zero
- z := x/y; ... chopped quotient, possibly inexact
- If(not I) then { ... if the quotient is exact
- if(z=y) {
- I := i; ... restore inexact flag
- R := r; ... restore rounded mode
- return sqrt(x):=y.
- } else {
- z := z - ulp; ... special rounding
- }
- }
- i := TRUE; ... sqrt(x) is inexact
- If (r=RN) then z=z+ulp ... rounded-to-nearest
- If (r=RP) then { ... round-toward-+inf
- y = y+ulp; z=z+ulp;
- }
- y := y+z; ... chopped sum
- y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
- I := i; ... restore inexact flag
- R := r; ... restore rounded mode
- return sqrt(x):=y.
-
- (4) Special cases
-
- Square root of +inf, +-0, or NaN is itself;
- Square root of a negative number is NaN with invalid signal.
-
-
-B. sqrt(x) by Reciproot Iteration
-
- (1) Initial approximation
-
- Let x0 and x1 be the leading and the trailing 32-bit words of
- a floating point number x (in IEEE double format) respectively
- (see section A). By performing shifs and subtracts on x0 and y0,
- we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
-
- k := 0x5fe80000 - (x0>>1);
- y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
-
- Here k is a 32-bit integer and T2[] is an integer array
- containing correction terms. Now magically the floating
- value of y (y's leading 32-bit word is y0, the value of
- its trailing word y1 is set to zero) approximates 1/sqrt(x)
- to almost 7.8-bit.
-
- Value of T2:
- static int T2[64]= {
- 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
- 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
- 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
- 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
- 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
- 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
- 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
- 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
-
- (2) Iterative refinement
-
- Apply Reciproot iteration three times to y and multiply the
- result by x to get an approximation z that matches sqrt(x)
- to about 1 ulp. To be exact, we will have
- -1ulp < sqrt(x)-z<1.0625ulp.
-
- ... set rounding mode to Round-to-nearest
- y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
- y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
- ... special arrangement for better accuracy
- z := x*y ... 29 bits to sqrt(x), with z*y<1
- z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
-
- Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
- (a) the term z*y in the final iteration is always less than 1;
- (b) the error in the final result is biased upward so that
- -1 ulp < sqrt(x) - z < 1.0625 ulp
- instead of |sqrt(x)-z|<1.03125ulp.
-
- (3) Final adjustment
-
- By twiddling y's last bit it is possible to force y to be
- correctly rounded according to the prevailing rounding mode
- as follows. Let r and i be copies of the rounding mode and
- inexact flag before entering the square root program. Also we
- use the expression y+-ulp for the next representable floating
- numbers (up and down) of y. Note that y+-ulp = either fixed
- point y+-1, or multiply y by nextafter(1,+-inf) in chopped
- mode.
-
- R := RZ; ... set rounding mode to round-toward-zero
- switch(r) {
- case RN: ... round-to-nearest
- if(x<= z*(z-ulp)...chopped) z = z - ulp; else
- if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
- break;
- case RZ:case RM: ... round-to-zero or round-to--inf
- R:=RP; ... reset rounding mod to round-to-+inf
- if(x<z*z ... rounded up) z = z - ulp; else
- if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
- break;
- case RP: ... round-to-+inf
- if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
- if(x>z*z ...chopped) z = z+ulp;
- break;
- }
-
- Remark 3. The above comparisons can be done in fixed point. For
- example, to compare x and w=z*z chopped, it suffices to compare
- x1 and w1 (the trailing parts of x and w), regarding them as
- two's complement integers.
-
- ...Is z an exact square root?
- To determine whether z is an exact square root of x, let z1 be the
- trailing part of z, and also let x0 and x1 be the leading and
- trailing parts of x.
-
- If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
- I := 1; ... Raise Inexact flag: z is not exact
- else {
- j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
- k := z1 >> 26; ... get z's 25-th and 26-th
- fraction bits
- I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
- }
- R:= r ... restore rounded mode
- return sqrt(x):=z.
-
- If multiplication is cheaper then the foregoing red tape, the
- Inexact flag can be evaluated by
-
- I := i;
- I := (z*z!=x) or I.
-
- Note that z*z can overwrite I; this value must be sensed if it is
- True.
-
- Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
- zero.
-
- --------------------
- z1: | f2 |
- --------------------
- bit 31 bit 0
-
- Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
- or even of logb(x) have the following relations:
-
- -------------------------------------------------
- bit 27,26 of z1 bit 1,0 of x1 logb(x)
- -------------------------------------------------
- 00 00 odd and even
- 01 01 even
- 10 10 odd
- 10 00 even
- 11 01 even
- -------------------------------------------------
-
- (4) Special cases (see (4) of Section A).
-
- */
-
diff --git a/src/extension/script/js/fdlibm/fdlibm.h b/src/extension/script/js/fdlibm/fdlibm.h
deleted file mode 100644
index b4063f82f..000000000
--- a/src/extension/script/js/fdlibm/fdlibm.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)fdlibm.h 1.5 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* Modified defines start here.. */
-#undef __LITTLE_ENDIAN
-
-#ifdef _WIN32
-#define huge myhuge
-#define __LITTLE_ENDIAN
-#endif
-
-#ifdef XP_OS2
-#define __LITTLE_ENDIAN
-#endif
-
-#if defined(linux) && defined(__i386__)
-#define __LITTLE_ENDIAN
-#endif
-
-/* End here. The rest is the standard file. */
-
-#ifdef __NEWVALID /* special setup for Sun test regime */
-#if defined(i386) || defined(i486) || \
- defined(intel) || defined(x86) || defined(i86pc)
-#define __LITTLE_ENDIAN
-#endif
-#endif
-
-typedef union {
-#ifdef __LITTLE_ENDIAN
- struct { int lo, hi; } ints;
-#else
- struct { int hi, lo; } ints;
-#endif
- double d;
-} fd_twoints;
-
-#define __HI(x) x.ints.hi
-#define __LO(x) x.ints.lo
-
-#undef __P
-#ifdef __STDC__
-#define __P(p) p
-#else
-#define __P(p) ()
-#endif
-
-/*
- * ANSI/POSIX
- */
-
-extern int signgam;
-
-#define MAXFLOAT ((float)3.40282346638528860e+38)
-
-enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
-
-#define _LIB_VERSION_TYPE enum fdversion
-#define _LIB_VERSION _fdlib_version
-
-/* if global variable _LIB_VERSION is not desirable, one may
- * change the following to be a constant by:
- * #define _LIB_VERSION_TYPE const enum version
- * In that case, after one initializes the value _LIB_VERSION (see
- * s_lib_version.c) during compile time, it cannot be modified
- * in the middle of a program
- */
-extern _LIB_VERSION_TYPE _LIB_VERSION;
-
-#define _IEEE_ fdlibm_ieee
-#define _SVID_ fdlibm_svid
-#define _XOPEN_ fdlibm_xopen
-#define _POSIX_ fdlibm_posix
-
-struct exception {
- int type;
- char *name;
- double arg1;
- double arg2;
- double retval;
-};
-
-#define HUGE MAXFLOAT
-
-/*
- * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
- * (one may replace the following line by "#include <values.h>")
- */
-
-#define X_TLOSS 1.41484755040568800000e+16
-
-#define DOMAIN 1
-#define SING 2
-#define OVERFLOW 3
-#define UNDERFLOW 4
-#define TLOSS 5
-#define PLOSS 6
-
-/*
- * ANSI/POSIX
- */
-
-extern double fd_acos __P((double));
-extern double fd_asin __P((double));
-extern double fd_atan __P((double));
-extern double fd_atan2 __P((double, double));
-extern double fd_cos __P((double));
-extern double fd_sin __P((double));
-extern double fd_tan __P((double));
-
-extern double fd_cosh __P((double));
-extern double fd_sinh __P((double));
-extern double fd_tanh __P((double));
-
-extern double fd_exp __P((double));
-extern double fd_frexp __P((double, int *));
-extern double fd_ldexp __P((double, int));
-extern double fd_log __P((double));
-extern double fd_log10 __P((double));
-extern double fd_modf __P((double, double *));
-
-extern double fd_pow __P((double, double));
-extern double fd_sqrt __P((double));
-
-extern double fd_ceil __P((double));
-extern double fd_fabs __P((double));
-extern double fd_floor __P((double));
-extern double fd_fmod __P((double, double));
-
-extern double fd_erf __P((double));
-extern double fd_erfc __P((double));
-extern double fd_gamma __P((double));
-extern double fd_hypot __P((double, double));
-extern int fd_isnan __P((double));
-extern int fd_finite __P((double));
-extern double fd_j0 __P((double));
-extern double fd_j1 __P((double));
-extern double fd_jn __P((int, double));
-extern double fd_lgamma __P((double));
-extern double fd_y0 __P((double));
-extern double fd_y1 __P((double));
-extern double fd_yn __P((int, double));
-
-extern double fd_acosh __P((double));
-extern double fd_asinh __P((double));
-extern double fd_atanh __P((double));
-extern double fd_cbrt __P((double));
-extern double fd_logb __P((double));
-extern double fd_nextafter __P((double, double));
-extern double fd_remainder __P((double, double));
-#ifdef _SCALB_INT
-extern double fd_scalb __P((double, int));
-#else
-extern double fd_scalb __P((double, double));
-#endif
-
-extern int fd_matherr __P((struct exception *));
-
-/*
- * IEEE Test Vector
- */
-extern double significand __P((double));
-
-/*
- * Functions callable from C, intended to support IEEE arithmetic.
- */
-extern double fd_copysign __P((double, double));
-extern int fd_ilogb __P((double));
-extern double fd_rint __P((double));
-extern double fd_scalbn __P((double, int));
-
-/*
- * BSD math library entry points
- */
-extern double fd_expm1 __P((double));
-extern double fd_log1p __P((double));
-
-/*
- * Reentrant version of gamma & lgamma; passes signgam back by reference
- * as the second argument; user must allocate space for signgam.
- */
-#ifdef _REENTRANT
-extern double gamma_r __P((double, int *));
-extern double lgamma_r __P((double, int *));
-#endif /* _REENTRANT */
-
-/* ieee style elementary functions */
-extern double __ieee754_sqrt __P((double));
-extern double __ieee754_acos __P((double));
-extern double __ieee754_acosh __P((double));
-extern double __ieee754_log __P((double));
-extern double __ieee754_atanh __P((double));
-extern double __ieee754_asin __P((double));
-extern double __ieee754_atan2 __P((double,double));
-extern double __ieee754_exp __P((double));
-extern double __ieee754_cosh __P((double));
-extern double __ieee754_fmod __P((double,double));
-extern double __ieee754_pow __P((double,double));
-extern double __ieee754_lgamma_r __P((double,int *));
-extern double __ieee754_gamma_r __P((double,int *));
-extern double __ieee754_lgamma __P((double));
-extern double __ieee754_gamma __P((double));
-extern double __ieee754_log10 __P((double));
-extern double __ieee754_sinh __P((double));
-extern double __ieee754_hypot __P((double,double));
-extern double __ieee754_j0 __P((double));
-extern double __ieee754_j1 __P((double));
-extern double __ieee754_y0 __P((double));
-extern double __ieee754_y1 __P((double));
-extern double __ieee754_jn __P((int,double));
-extern double __ieee754_yn __P((int,double));
-extern double __ieee754_remainder __P((double,double));
-extern int __ieee754_rem_pio2 __P((double,double*));
-#ifdef _SCALB_INT
-extern double __ieee754_scalb __P((double,int));
-#else
-extern double __ieee754_scalb __P((double,double));
-#endif
-
-/* fdlibm kernel function */
-extern double __kernel_standard __P((double,double,int,int*));
-extern double __kernel_sin __P((double,double,int));
-extern double __kernel_cos __P((double,double));
-extern double __kernel_tan __P((double,double,int));
-extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
diff --git a/src/extension/script/js/fdlibm/k_cos.c b/src/extension/script/js/fdlibm/k_cos.c
deleted file mode 100644
index 17b505d58..000000000
--- a/src/extension/script/js/fdlibm/k_cos.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)k_cos.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * __kernel_cos( x, y )
- * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
- * Input x is assumed to be bounded by ~pi/4 in magnitude.
- * Input y is the tail of x.
- *
- * Algorithm
- * 1. Since cos(-x) = cos(x), we need only to consider positive x.
- * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
- * 3. cos(x) is approximated by a polynomial of degree 14 on
- * [0,pi/4]
- * 4 14
- * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
- * where the remez error is
- *
- * | 2 4 6 8 10 12 14 | -58
- * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
- * | |
- *
- * 4 6 8 10 12 14
- * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
- * cos(x) = 1 - x*x/2 + r
- * since cos(x+y) ~ cos(x) - sin(x)*y
- * ~ cos(x) - x*y,
- * a correction term is necessary in cos(x) and hence
- * cos(x+y) = 1 - (x*x/2 - (r - x*y))
- * For better accuracy when x > 0.3, let qx = |x|/4 with
- * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
- * Then
- * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
- * Note that 1-qx and (x*x/2-qx) is EXACT here, and the
- * magnitude of the latter is at least a quarter of x*x/2,
- * thus, reducing the rounding error in the subtraction.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
-C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
-C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
-C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
-C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
-C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
-
-#ifdef __STDC__
- double __kernel_cos(double x, double y)
-#else
- double __kernel_cos(x, y)
- double x,y;
-#endif
-{
- fd_twoints u;
- double a,hz,z,r,qx;
- int ix;
- u.d = x;
- ix = __HI(u)&0x7fffffff; /* ix = |x|'s high word*/
- if(ix<0x3e400000) { /* if x < 2**27 */
- if(((int)x)==0) return one; /* generate inexact */
- }
- z = x*x;
- r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
- if(ix < 0x3FD33333) /* if |x| < 0.3 */
- return one - (0.5*z - (z*r - x*y));
- else {
- if(ix > 0x3fe90000) { /* x > 0.78125 */
- qx = 0.28125;
- } else {
- u.d = qx;
- __HI(u) = ix-0x00200000; /* x/4 */
- __LO(u) = 0;
- qx = u.d;
- }
- hz = 0.5*z-qx;
- a = one-qx;
- return a - (hz - (z*r-x*y));
- }
-}
diff --git a/src/extension/script/js/fdlibm/k_rem_pio2.c b/src/extension/script/js/fdlibm/k_rem_pio2.c
deleted file mode 100644
index d261e190a..000000000
--- a/src/extension/script/js/fdlibm/k_rem_pio2.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)k_rem_pio2.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
- * double x[],y[]; int e0,nx,prec; int ipio2[];
- *
- * __kernel_rem_pio2 return the last three digits of N with
- * y = x - N*pi/2
- * so that |y| < pi/2.
- *
- * The method is to compute the integer (mod 8) and fraction parts of
- * (2/pi)*x without doing the full multiplication. In general we
- * skip the part of the product that are known to be a huge integer (
- * more accurately, = 0 mod 8 ). Thus the number of operations are
- * independent of the exponent of the input.
- *
- * (2/pi) is represented by an array of 24-bit integers in ipio2[].
- *
- * Input parameters:
- * x[] The input value (must be positive) is broken into nx
- * pieces of 24-bit integers in double precision format.
- * x[i] will be the i-th 24 bit of x. The scaled exponent
- * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
- * match x's up to 24 bits.
- *
- * Example of breaking a double positive z into x[0]+x[1]+x[2]:
- * e0 = ilogb(z)-23
- * z = scalbn(z,-e0)
- * for i = 0,1,2
- * x[i] = floor(z)
- * z = (z-x[i])*2**24
- *
- *
- * y[] ouput result in an array of double precision numbers.
- * The dimension of y[] is:
- * 24-bit precision 1
- * 53-bit precision 2
- * 64-bit precision 2
- * 113-bit precision 3
- * The actual value is the sum of them. Thus for 113-bit
- * precison, one may have to do something like:
- *
- * long double t,w,r_head, r_tail;
- * t = (long double)y[2] + (long double)y[1];
- * w = (long double)y[0];
- * r_head = t+w;
- * r_tail = w - (r_head - t);
- *
- * e0 The exponent of x[0]
- *
- * nx dimension of x[]
- *
- * prec an integer indicating the precision:
- * 0 24 bits (single)
- * 1 53 bits (double)
- * 2 64 bits (extended)
- * 3 113 bits (quad)
- *
- * ipio2[]
- * integer array, contains the (24*i)-th to (24*i+23)-th
- * bit of 2/pi after binary point. The corresponding
- * floating value is
- *
- * ipio2[i] * 2^(-24(i+1)).
- *
- * External function:
- * double scalbn(), floor();
- *
- *
- * Here is the description of some local variables:
- *
- * jk jk+1 is the initial number of terms of ipio2[] needed
- * in the computation. The recommended value is 2,3,4,
- * 6 for single, double, extended,and quad.
- *
- * jz local integer variable indicating the number of
- * terms of ipio2[] used.
- *
- * jx nx - 1
- *
- * jv index for pointing to the suitable ipio2[] for the
- * computation. In general, we want
- * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
- * is an integer. Thus
- * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
- * Hence jv = max(0,(e0-3)/24).
- *
- * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
- *
- * q[] double array with integral value, representing the
- * 24-bits chunk of the product of x and 2/pi.
- *
- * q0 the corresponding exponent of q[0]. Note that the
- * exponent for q[i] would be q0-24*i.
- *
- * PIo2[] double precision array, obtained by cutting pi/2
- * into 24 bits chunks.
- *
- * f[] ipio2[] in floating point
- *
- * iq[] integer array by breaking up q[] in 24-bits chunk.
- *
- * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
- *
- * ih integer. If >0 it indicates q[] is >= 0.5, hence
- * it also indicates the *sign* of the result.
- *
- */
-
-
-/*
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
-#else
-static int init_jk[] = {2,3,4,6};
-#endif
-
-#ifdef __STDC__
-static const double PIo2[] = {
-#else
-static double PIo2[] = {
-#endif
- 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
- 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
- 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
- 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
- 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
- 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
- 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
- 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
-};
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-zero = 0.0,
-one = 1.0,
-two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
-twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
-
-#ifdef __STDC__
- int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
-#else
- int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
- double x[], y[]; int e0,nx,prec; int ipio2[];
-#endif
-{
- int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
- double z,fw,f[20],fq[20],q[20];
-
- /* initialize jk*/
- jk = init_jk[prec];
- jp = jk;
-
- /* determine jx,jv,q0, note that 3>q0 */
- jx = nx-1;
- jv = (e0-3)/24; if(jv<0) jv=0;
- q0 = e0-24*(jv+1);
-
- /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
- j = jv-jx; m = jx+jk;
- for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
-
- /* compute q[0],q[1],...q[jk] */
- for (i=0;i<=jk;i++) {
- for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
- }
-
- jz = jk;
-recompute:
- /* distill q[] into iq[] reversingly */
- for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
- fw = (double)((int)(twon24* z));
- iq[i] = (int)(z-two24*fw);
- z = q[j-1]+fw;
- }
-
- /* compute n */
- z = fd_scalbn(z,q0); /* actual value of z */
- z -= 8.0*fd_floor(z*0.125); /* trim off integer >= 8 */
- n = (int) z;
- z -= (double)n;
- ih = 0;
- if(q0>0) { /* need iq[jz-1] to determine n */
- i = (iq[jz-1]>>(24-q0)); n += i;
- iq[jz-1] -= i<<(24-q0);
- ih = iq[jz-1]>>(23-q0);
- }
- else if(q0==0) ih = iq[jz-1]>>23;
- else if(z>=0.5) ih=2;
-
- if(ih>0) { /* q > 0.5 */
- n += 1; carry = 0;
- for(i=0;i<jz ;i++) { /* compute 1-q */
- j = iq[i];
- if(carry==0) {
- if(j!=0) {
- carry = 1; iq[i] = 0x1000000- j;
- }
- } else iq[i] = 0xffffff - j;
- }
- if(q0>0) { /* rare case: chance is 1 in 12 */
- switch(q0) {
- case 1:
- iq[jz-1] &= 0x7fffff; break;
- case 2:
- iq[jz-1] &= 0x3fffff; break;
- }
- }
- if(ih==2) {
- z = one - z;
- if(carry!=0) z -= fd_scalbn(one,q0);
- }
- }
-
- /* check if recomputation is needed */
- if(z==zero) {
- j = 0;
- for (i=jz-1;i>=jk;i--) j |= iq[i];
- if(j==0) { /* need recomputation */
- for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
-
- for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
- f[jx+i] = (double) ipio2[jv+i];
- for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
- q[i] = fw;
- }
- jz += k;
- goto recompute;
- }
- }
-
- /* chop off zero terms */
- if(z==0.0) {
- jz -= 1; q0 -= 24;
- while(iq[jz]==0) { jz--; q0-=24;}
- } else { /* break z into 24-bit if necessary */
- z = fd_scalbn(z,-q0);
- if(z>=two24) {
- fw = (double)((int)(twon24*z));
- iq[jz] = (int)(z-two24*fw);
- jz += 1; q0 += 24;
- iq[jz] = (int) fw;
- } else iq[jz] = (int) z ;
- }
-
- /* convert integer "bit" chunk to floating-point value */
- fw = fd_scalbn(one,q0);
- for(i=jz;i>=0;i--) {
- q[i] = fw*(double)iq[i]; fw*=twon24;
- }
-
- /* compute PIo2[0,...,jp]*q[jz,...,0] */
- for(i=jz;i>=0;i--) {
- for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
- fq[jz-i] = fw;
- }
-
- /* compress fq[] into y[] */
- switch(prec) {
- case 0:
- fw = 0.0;
- for (i=jz;i>=0;i--) fw += fq[i];
- y[0] = (ih==0)? fw: -fw;
- break;
- case 1:
- case 2:
- fw = 0.0;
- for (i=jz;i>=0;i--) fw += fq[i];
- y[0] = (ih==0)? fw: -fw;
- fw = fq[0]-fw;
- for (i=1;i<=jz;i++) fw += fq[i];
- y[1] = (ih==0)? fw: -fw;
- break;
- case 3: /* painful */
- for (i=jz;i>0;i--) {
- fw = fq[i-1]+fq[i];
- fq[i] += fq[i-1]-fw;
- fq[i-1] = fw;
- }
- for (i=jz;i>1;i--) {
- fw = fq[i-1]+fq[i];
- fq[i] += fq[i-1]-fw;
- fq[i-1] = fw;
- }
- for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
- if(ih==0) {
- y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
- } else {
- y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
- }
- }
- return n&7;
-}
diff --git a/src/extension/script/js/fdlibm/k_sin.c b/src/extension/script/js/fdlibm/k_sin.c
deleted file mode 100644
index d2bdabd6d..000000000
--- a/src/extension/script/js/fdlibm/k_sin.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)k_sin.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __kernel_sin( x, y, iy)
- * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
- * Input x is assumed to be bounded by ~pi/4 in magnitude.
- * Input y is the tail of x.
- * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
- *
- * Algorithm
- * 1. Since sin(-x) = -sin(x), we need only to consider positive x.
- * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
- * 3. sin(x) is approximated by a polynomial of degree 13 on
- * [0,pi/4]
- * 3 13
- * sin(x) ~ x + S1*x + ... + S6*x
- * where
- *
- * |sin(x) 2 4 6 8 10 12 | -58
- * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
- * | x |
- *
- * 4. sin(x+y) = sin(x) + sin'(x')*y
- * ~ sin(x) + (1-x*x/2)*y
- * For better accuracy, let
- * 3 2 2 2 2
- * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
- * then 3 2
- * sin(x) = x + (S1*x + (x *(r-y/2)+y))
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
-S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
-S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
-S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
-S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
-S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
-
-#ifdef __STDC__
- double __kernel_sin(double x, double y, int iy)
-#else
- double __kernel_sin(x, y, iy)
- double x,y; int iy; /* iy=0 if y is zero */
-#endif
-{
- fd_twoints u;
- double z,r,v;
- int ix;
- u.d = x;
- ix = __HI(u)&0x7fffffff; /* high word of x */
- if(ix<0x3e400000) /* |x| < 2**-27 */
- {if((int)x==0) return x;} /* generate inexact */
- z = x*x;
- v = z*x;
- r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
- if(iy==0) return x+v*(S1+z*r);
- else return x-((z*(half*y-v*r)-y)-v*S1);
-}
diff --git a/src/extension/script/js/fdlibm/k_standard.c b/src/extension/script/js/fdlibm/k_standard.c
deleted file mode 100644
index 720109c9d..000000000
--- a/src/extension/script/js/fdlibm/k_standard.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)k_standard.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-#include "fdlibm.h"
-
-/* XXX ugly hack to get msvc to link without error. */
-#if _LIB_VERSION == _IEEE_ && !(defined(DARWIN) || defined(XP_MACOSX))
- int errno;
-# define EDOM 0
-# define ERANGE 0
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef _USE_WRITE
-#include <stdio.h> /* fputs(), stderr */
-#define WRITE2(u,v) fputs(u, stderr)
-#else /* !defined(_USE_WRITE) */
-#include <unistd.h> /* write */
-#define WRITE2(u,v) write(2, u, v)
-#undef fflush
-#endif /* !defined(_USE_WRITE) */
-
-static double zero = 0.0; /* used as const */
-
-/*
- * Standard conformance (non-IEEE) on exception cases.
- * Mapping:
- * 1 -- acos(|x|>1)
- * 2 -- asin(|x|>1)
- * 3 -- atan2(+-0,+-0)
- * 4 -- hypot overflow
- * 5 -- cosh overflow
- * 6 -- exp overflow
- * 7 -- exp underflow
- * 8 -- y0(0)
- * 9 -- y0(-ve)
- * 10-- y1(0)
- * 11-- y1(-ve)
- * 12-- yn(0)
- * 13-- yn(-ve)
- * 14-- lgamma(finite) overflow
- * 15-- lgamma(-integer)
- * 16-- log(0)
- * 17-- log(x<0)
- * 18-- log10(0)
- * 19-- log10(x<0)
- * 20-- pow(0.0,0.0)
- * 21-- pow(x,y) overflow
- * 22-- pow(x,y) underflow
- * 23-- pow(0,negative)
- * 24-- pow(neg,non-integral)
- * 25-- sinh(finite) overflow
- * 26-- sqrt(negative)
- * 27-- fmod(x,0)
- * 28-- remainder(x,0)
- * 29-- acosh(x<1)
- * 30-- atanh(|x|>1)
- * 31-- atanh(|x|=1)
- * 32-- scalb overflow
- * 33-- scalb underflow
- * 34-- j0(|x|>X_TLOSS)
- * 35-- y0(x>X_TLOSS)
- * 36-- j1(|x|>X_TLOSS)
- * 37-- y1(x>X_TLOSS)
- * 38-- jn(|x|>X_TLOSS, n)
- * 39-- yn(x>X_TLOSS, n)
- * 40-- gamma(finite) overflow
- * 41-- gamma(-integer)
- * 42-- pow(NaN,0.0)
- */
-
-
-#ifdef __STDC__
- double __kernel_standard(double x, double y, int type, int *err)
-#else
- double __kernel_standard(x,y,type, err)
- double x,y; int type;int *err;
-#endif
-{
- struct exception exc;
-#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
-#define HUGE_VAL inf
- double inf = 0.0;
- fd_twoints u;
-
- u.d = inf;
- __HI(u) = 0x7ff00000; /* set inf to infinite */
- inf = u.d;
-#endif
-
- *err = 0;
-
-#ifdef _USE_WRITE
- (void) fflush(stdout);
-#endif
- exc.arg1 = x;
- exc.arg2 = y;
- switch(type) {
- case 1:
- /* acos(|x|>1) */
- exc.type = DOMAIN;
- exc.name = "acos";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("acos: DOMAIN error\n", 19);
- }
- *err = EDOM;
- }
- break;
- case 2:
- /* asin(|x|>1) */
- exc.type = DOMAIN;
- exc.name = "asin";
- exc.retval = zero;
- if(_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("asin: DOMAIN error\n", 19);
- }
- *err = EDOM;
- }
- break;
- case 3:
- /* atan2(+-0,+-0) */
- exc.arg1 = y;
- exc.arg2 = x;
- exc.type = DOMAIN;
- exc.name = "atan2";
- exc.retval = zero;
- if(_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("atan2: DOMAIN error\n", 20);
- }
- *err = EDOM;
- }
- break;
- case 4:
- /* hypot(finite,finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "hypot";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 5:
- /* cosh(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "cosh";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 6:
- /* exp(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "exp";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 7:
- /* exp(finite) underflow */
- exc.type = UNDERFLOW;
- exc.name = "exp";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 8:
- /* y0(0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = "y0";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y0: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 9:
- /* y0(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = "y0";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y0: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 10:
- /* y1(0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = "y1";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y1: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 11:
- /* y1(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = "y1";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y1: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 12:
- /* yn(n,0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = "yn";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("yn: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 13:
- /* yn(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = "yn";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("yn: DOMAIN error\n", 17);
- }
- *err = EDOM;
- }
- break;
- case 14:
- /* lgamma(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "lgamma";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 15:
- /* lgamma(-integer) or lgamma(0) */
- exc.type = SING;
- exc.name = "lgamma";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("lgamma: SING error\n", 19);
- }
- *err = EDOM;
- }
- break;
- case 16:
- /* log(0) */
- exc.type = SING;
- exc.name = "log";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log: SING error\n", 16);
- }
- *err = EDOM;
- }
- break;
- case 17:
- /* log(x<0) */
- exc.type = DOMAIN;
- exc.name = "log";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log: DOMAIN error\n", 18);
- }
- *err = EDOM;
- }
- break;
- case 18:
- /* log10(0) */
- exc.type = SING;
- exc.name = "log10";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log10: SING error\n", 18);
- }
- *err = EDOM;
- }
- break;
- case 19:
- /* log10(x<0) */
- exc.type = DOMAIN;
- exc.name = "log10";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log10: DOMAIN error\n", 20);
- }
- *err = EDOM;
- }
- break;
- case 20:
- /* pow(0.0,0.0) */
- /* error only if _LIB_VERSION == _SVID_ */
- exc.type = DOMAIN;
- exc.name = "pow";
- exc.retval = zero;
- if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
- else if (!fd_matherr(&exc)) {
- (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
- *err = EDOM;
- }
- break;
- case 21:
- /* pow(x,y) overflow */
- exc.type = OVERFLOW;
- exc.name = "pow";
- if (_LIB_VERSION == _SVID_) {
- exc.retval = HUGE;
- y *= 0.5;
- if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE;
- } else {
- exc.retval = HUGE_VAL;
- y *= 0.5;
- if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE_VAL;
- }
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 22:
- /* pow(x,y) underflow */
- exc.type = UNDERFLOW;
- exc.name = "pow";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 23:
- /* 0**neg */
- exc.type = DOMAIN;
- exc.name = "pow";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
- }
- *err = EDOM;
- }
- break;
- case 24:
- /* neg**non-integral */
- exc.type = DOMAIN;
- exc.name = "pow";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = zero/zero; /* X/Open allow NaN */
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
- }
- *err = EDOM;
- }
- break;
- case 25:
- /* sinh(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "sinh";
- if (_LIB_VERSION == _SVID_)
- exc.retval = ( (x>zero) ? HUGE : -HUGE);
- else
- exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 26:
- /* sqrt(x<0) */
- exc.type = DOMAIN;
- exc.name = "sqrt";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("sqrt: DOMAIN error\n", 19);
- }
- *err = EDOM;
- }
- break;
- case 27:
- /* fmod(x,0) */
- exc.type = DOMAIN;
- exc.name = "fmod";
- if (_LIB_VERSION == _SVID_)
- exc.retval = x;
- else
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("fmod: DOMAIN error\n", 20);
- }
- *err = EDOM;
- }
- break;
- case 28:
- /* remainder(x,0) */
- exc.type = DOMAIN;
- exc.name = "remainder";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("remainder: DOMAIN error\n", 24);
- }
- *err = EDOM;
- }
- break;
- case 29:
- /* acosh(x<1) */
- exc.type = DOMAIN;
- exc.name = "acosh";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("acosh: DOMAIN error\n", 20);
- }
- *err = EDOM;
- }
- break;
- case 30:
- /* atanh(|x|>1) */
- exc.type = DOMAIN;
- exc.name = "atanh";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("atanh: DOMAIN error\n", 20);
- }
- *err = EDOM;
- }
- break;
- case 31:
- /* atanh(|x|=1) */
- exc.type = SING;
- exc.name = "atanh";
- exc.retval = x/zero; /* sign(x)*inf */
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("atanh: SING error\n", 18);
- }
- *err = EDOM;
- }
- break;
- case 32:
- /* scalb overflow; SVID also returns +-HUGE_VAL */
- exc.type = OVERFLOW;
- exc.name = "scalb";
- exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 33:
- /* scalb underflow */
- exc.type = UNDERFLOW;
- exc.name = "scalb";
- exc.retval = fd_copysign(zero,x);
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 34:
- /* j0(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "j0";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 35:
- /* y0(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "y0";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 36:
- /* j1(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "j1";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 37:
- /* y1(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "y1";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 38:
- /* jn(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "jn";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 39:
- /* yn(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = "yn";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- *err = ERANGE;
- }
- break;
- case 40:
- /* gamma(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = "gamma";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = ERANGE;
- else if (!fd_matherr(&exc)) {
- *err = ERANGE;
- }
- break;
- case 41:
- /* gamma(-integer) or gamma(0) */
- exc.type = SING;
- exc.name = "gamma";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- *err = EDOM;
- else if (!fd_matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("gamma: SING error\n", 18);
- }
- *err = EDOM;
- }
- break;
- case 42:
- /* pow(NaN,0.0) */
- /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
- exc.type = DOMAIN;
- exc.name = "pow";
- exc.retval = x;
- if (_LIB_VERSION == _IEEE_ ||
- _LIB_VERSION == _POSIX_) exc.retval = 1.0;
- else if (!fd_matherr(&exc)) {
- *err = EDOM;
- }
- break;
- }
- return exc.retval;
-}
diff --git a/src/extension/script/js/fdlibm/k_tan.c b/src/extension/script/js/fdlibm/k_tan.c
deleted file mode 100644
index 1e7681b88..000000000
--- a/src/extension/script/js/fdlibm/k_tan.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)k_tan.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* __kernel_tan( x, y, k )
- * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
- * Input x is assumed to be bounded by ~pi/4 in magnitude.
- * Input y is the tail of x.
- * Input k indicates whether tan (if k=1) or
- * -1/tan (if k= -1) is returned.
- *
- * Algorithm
- * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
- * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
- * 3. tan(x) is approximated by a odd polynomial of degree 27 on
- * [0,0.67434]
- * 3 27
- * tan(x) ~ x + T1*x + ... + T13*x
- * where
- *
- * |tan(x) 2 4 26 | -59.2
- * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
- * | x |
- *
- * Note: tan(x+y) = tan(x) + tan'(x)*y
- * ~ tan(x) + (1+x*x)*y
- * Therefore, for better accuracy in computing tan(x+y), let
- * 3 2 2 2 2
- * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
- * then
- * 3 2
- * tan(x+y) = x + (T1*x + (x *(r+y)+y))
- *
- * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
- * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
- * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
- */
-
-#include "fdlibm.h"
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
-pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
-T[] = {
- 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
- 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
- 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
- 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
- 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
- 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
- 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
- 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
- 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
- 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
- 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
- -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
- 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
-};
-
-#ifdef __STDC__
- double __kernel_tan(double x, double y, int iy)
-#else
- double __kernel_tan(x, y, iy)
- double x,y; int iy;
-#endif
-{
- fd_twoints u;
- double z,r,v,w,s;
- int ix,hx;
- u.d = x;
- hx = __HI(u); /* high word of x */
- ix = hx&0x7fffffff; /* high word of |x| */
- if(ix<0x3e300000) /* x < 2**-28 */
- {if((int)x==0) { /* generate inexact */
- u.d =x;
- if(((ix|__LO(u))|(iy+1))==0) return one/fd_fabs(x);
- else return (iy==1)? x: -one/x;
- }
- }
- if(ix>=0x3FE59428) { /* |x|>=0.6744 */
- if(hx<0) {x = -x; y = -y;}
- z = pio4-x;
- w = pio4lo-y;
- x = z+w; y = 0.0;
- }
- z = x*x;
- w = z*z;
- /* Break x^5*(T[1]+x^2*T[2]+...) into
- * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
- * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
- */
- r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
- v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
- s = z*x;
- r = y + z*(s*(r+v)+y);
- r += T[0]*s;
- w = x+r;
- if(ix>=0x3FE59428) {
- v = (double)iy;
- return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
- }
- if(iy==1) return w;
- else { /* if allow error up to 2 ulp,
- simply return -1.0/(x+r) here */
- /* compute -1.0/(x+r) accurately */
- double a,t;
- z = w;
- u.d = z;
- __LO(u) = 0;
- z = u.d;
- v = r-(z - x); /* z+v = r+x */
- t = a = -1.0/w; /* a = -1.0/w */
- u.d = t;
- __LO(u) = 0;
- t = u.d;
- s = 1.0+t*z;
- return t+a*(s+t*v);
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_asinh.c b/src/extension/script/js/fdlibm/s_asinh.c
deleted file mode 100644
index fdf70a91c..000000000
--- a/src/extension/script/js/fdlibm/s_asinh.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_asinh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* asinh(x)
- * Method :
- * Based on
- * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
- * we have
- * asinh(x) := x if 1+x*x=1,
- * := sign(x)*(log(x)+ln2)) for large |x|, else
- * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
- * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
-really_big= 1.00000000000000000000e+300;
-
-#ifdef __STDC__
- double fd_asinh(double x)
-#else
- double fd_asinh(x)
- double x;
-#endif
-{
- fd_twoints u;
- double t,w;
- int hx,ix;
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */
- if(ix< 0x3e300000) { /* |x|<2**-28 */
- if(really_big+x>one) return x; /* return x inexact except 0 */
- }
- if(ix>0x41b00000) { /* |x| > 2**28 */
- w = __ieee754_log(fd_fabs(x))+ln2;
- } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
- t = fd_fabs(x);
- w = __ieee754_log(2.0*t+one/(fd_sqrt(x*x+one)+t));
- } else { /* 2.0 > |x| > 2**-28 */
- t = x*x;
- w =fd_log1p(fd_fabs(x)+t/(one+fd_sqrt(one+t)));
- }
- if(hx>0) return w; else return -w;
-}
diff --git a/src/extension/script/js/fdlibm/s_atan.c b/src/extension/script/js/fdlibm/s_atan.c
deleted file mode 100644
index 99a00c686..000000000
--- a/src/extension/script/js/fdlibm/s_atan.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_atan.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* atan(x)
- * Method
- * 1. Reduce x to positive by atan(x) = -atan(-x).
- * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
- * is further reduced to one of the following intervals and the
- * arctangent of t is evaluated by the corresponding formula:
- *
- * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
- * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
- * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
- * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
- * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double atanhi[] = {
-#else
-static double atanhi[] = {
-#endif
- 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
- 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
- 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
- 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
-};
-
-#ifdef __STDC__
-static const double atanlo[] = {
-#else
-static double atanlo[] = {
-#endif
- 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
- 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
- 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
- 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
-};
-
-#ifdef __STDC__
-static const double aT[] = {
-#else
-static double aT[] = {
-#endif
- 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
- -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
- 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
- -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
- 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
- -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
- 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
- -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
- 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
- -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
- 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
-};
-
-#ifdef __STDC__
- static const double
-#else
- static double
-#endif
-one = 1.0,
-really_big = 1.0e300;
-
-#ifdef __STDC__
- double fd_atan(double x)
-#else
- double fd_atan(x)
- double x;
-#endif
-{
- fd_twoints u;
- double w,s1,s2,z;
- int ix,hx,id;
-
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- if(ix>=0x44100000) { /* if |x| >= 2^66 */
- u.d = x;
- if(ix>0x7ff00000||
- (ix==0x7ff00000&&(__LO(u)!=0)))
- return x+x; /* NaN */
- if(hx>0) return atanhi[3]+atanlo[3];
- else return -atanhi[3]-atanlo[3];
- } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
- if (ix < 0x3e200000) { /* |x| < 2^-29 */
- if(really_big+x>one) return x; /* raise inexact */
- }
- id = -1;
- } else {
- x = fd_fabs(x);
- if (ix < 0x3ff30000) { /* |x| < 1.1875 */
- if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
- id = 0; x = (2.0*x-one)/(2.0+x);
- } else { /* 11/16<=|x|< 19/16 */
- id = 1; x = (x-one)/(x+one);
- }
- } else {
- if (ix < 0x40038000) { /* |x| < 2.4375 */
- id = 2; x = (x-1.5)/(one+1.5*x);
- } else { /* 2.4375 <= |x| < 2^66 */
- id = 3; x = -1.0/x;
- }
- }}
- /* end of argument reduction */
- z = x*x;
- w = z*z;
- /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
- s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
- s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
- if (id<0) return x - x*(s1+s2);
- else {
- z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
- return (hx<0)? -z:z;
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_cbrt.c b/src/extension/script/js/fdlibm/s_cbrt.c
deleted file mode 100644
index 4aed19b1b..000000000
--- a/src/extension/script/js/fdlibm/s_cbrt.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_cbrt.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-#include "fdlibm.h"
-
-/* cbrt(x)
- * Return cube root of x
- */
-#ifdef __STDC__
-static const unsigned
-#else
-static unsigned
-#endif
- B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
- B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
-D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
-E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
-F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
-G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
-
-#ifdef __STDC__
- double fd_cbrt(double x)
-#else
- double fd_cbrt(x)
- double x;
-#endif
-{
- fd_twoints u;
- int hx;
- double r,s,t=0.0,w;
- unsigned sign;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- sign=hx&0x80000000; /* sign= sign(x) */
- hx ^=sign;
- if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
- if((hx|__LO(u))==0) {
- x = u.d;
- return(x); /* cbrt(0) is itself */
- }
- u.d = x;
- __HI(u) = hx; /* x <- |x| */
- x = u.d;
- /* rough cbrt to 5 bits */
- if(hx<0x00100000) /* subnormal number */
- {u.d = t; __HI(u)=0x43500000; t=u.d; /* set t= 2**54 */
- t*=x; __HI(u)=__HI(u)/3+B2;
- }
- else {
- u.d = t; __HI(u)=hx/3+B1; t = u.d;
- }
-
-
- /* new cbrt to 23 bits, may be implemented in single precision */
- r=t*t/x;
- s=C+r*t;
- t*=G+F/(s+E+D/s);
-
- /* chopped to 20 bits and make it larger than cbrt(x) */
- u.d = t;
- __LO(u)=0; __HI(u)+=0x00000001;
- t = u.d;
-
- /* one step newton iteration to 53 bits with error less than 0.667 ulps */
- s=t*t; /* t*t is exact */
- r=x/s;
- w=t+t;
- r=(r-t)/(w+r); /* r-s is exact */
- t=t+t*r;
-
- /* retore the sign bit */
- u.d = t;
- __HI(u) |= sign;
- t = u.d;
- return(t);
-}
diff --git a/src/extension/script/js/fdlibm/s_ceil.c b/src/extension/script/js/fdlibm/s_ceil.c
deleted file mode 100644
index 826bcac6c..000000000
--- a/src/extension/script/js/fdlibm/s_ceil.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_ceil.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * ceil(x)
- * Return x rounded toward -inf to integral value
- * Method:
- * Bit twiddling.
- * Exception:
- * Inexact flag raised if x not equal to ceil(x).
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double really_big = 1.0e300;
-#else
-static double really_big = 1.0e300;
-#endif
-
-#ifdef __STDC__
- double fd_ceil(double x)
-#else
- double fd_ceil(x)
- double x;
-#endif
-{
- fd_twoints u;
- int i0,i1,j0;
- unsigned i,j;
- u.d = x;
- i0 = __HI(u);
- i1 = __LO(u);
- j0 = ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) { /* raise inexact if x != 0 */
- if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */
- if(i0<0) {i0=0x80000000;i1=0;}
- else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
- }
- } else {
- i = (0x000fffff)>>j0;
- if(((i0&i)|i1)==0) return x; /* x is integral */
- if(really_big+x>0.0) { /* raise inexact flag */
- if(i0>0) i0 += (0x00100000)>>j0;
- i0 &= (~i); i1=0;
- }
- }
- } else if (j0>51) {
- if(j0==0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i = ((unsigned)(0xffffffff))>>(j0-20);
- if((i1&i)==0) return x; /* x is integral */
- if(really_big+x>0.0) { /* raise inexact flag */
- if(i0>0) {
- if(j0==20) i0+=1;
- else {
- j = i1 + (1<<(52-j0));
- if((int)j<i1) i0+=1; /* got a carry */
- i1 = j;
- }
- }
- i1 &= (~i);
- }
- }
- u.d = x;
- __HI(u) = i0;
- __LO(u) = i1;
- x = u.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_copysign.c b/src/extension/script/js/fdlibm/s_copysign.c
deleted file mode 100644
index 8869a1233..000000000
--- a/src/extension/script/js/fdlibm/s_copysign.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_copysign.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * copysign(double x, double y)
- * copysign(x,y) returns a value with the magnitude of x and
- * with the sign bit of y.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_copysign(double x, double y)
-#else
- double fd_copysign(x,y)
- double x,y;
-#endif
-{
- fd_twoints ux, uy;
- ux.d = x; uy.d = y;
- __HI(ux) = (__HI(ux)&0x7fffffff)|(__HI(uy)&0x80000000);
- x = ux.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_cos.c b/src/extension/script/js/fdlibm/s_cos.c
deleted file mode 100644
index 3fb0a6b15..000000000
--- a/src/extension/script/js/fdlibm/s_cos.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_cos.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* cos(x)
- * Return cosine function of x.
- *
- * kernel function:
- * __kernel_sin ... sine function on [-pi/4,pi/4]
- * __kernel_cos ... cosine function on [-pi/4,pi/4]
- * __ieee754_rem_pio2 ... argument reduction routine
- *
- * Method.
- * Let S,C and T denote the sin, cos and tan respectively on
- * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
- * in [-pi/4 , +pi/4], and let n = k mod 4.
- * We have
- *
- * n sin(x) cos(x) tan(x)
- * ----------------------------------------------------------
- * 0 S C T
- * 1 C -S -1/T
- * 2 -S -C T
- * 3 -C S -1/T
- * ----------------------------------------------------------
- *
- * Special cases:
- * Let trig be any of sin, cos, or tan.
- * trig(+-INF) is NaN, with signals;
- * trig(NaN) is that NaN;
- *
- * Accuracy:
- * TRIG(x) returns trig(x) nearly rounded
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_cos(double x)
-#else
- double fd_cos(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y[2],z=0.0;
- int n, ix;
-
- /* High word of x. */
- u.d = x;
- ix = __HI(u);
-
- /* |x| ~< pi/4 */
- ix &= 0x7fffffff;
- if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
-
- /* cos(Inf or NaN) is NaN */
- else if (ix>=0x7ff00000) return x-x;
-
- /* argument reduction needed */
- else {
- n = __ieee754_rem_pio2(x,y);
- switch(n&3) {
- case 0: return __kernel_cos(y[0],y[1]);
- case 1: return -__kernel_sin(y[0],y[1],1);
- case 2: return -__kernel_cos(y[0],y[1]);
- default:
- return __kernel_sin(y[0],y[1],1);
- }
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_erf.c b/src/extension/script/js/fdlibm/s_erf.c
deleted file mode 100644
index 6eae8de3b..000000000
--- a/src/extension/script/js/fdlibm/s_erf.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_erf.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* double erf(double x)
- * double erfc(double x)
- * x
- * 2 |\
- * erf(x) = --------- | exp(-t*t)dt
- * sqrt(pi) \|
- * 0
- *
- * erfc(x) = 1-erf(x)
- * Note that
- * erf(-x) = -erf(x)
- * erfc(-x) = 2 - erfc(x)
- *
- * Method:
- * 1. For |x| in [0, 0.84375]
- * erf(x) = x + x*R(x^2)
- * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
- * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
- * where R = P/Q where P is an odd poly of degree 8 and
- * Q is an odd poly of degree 10.
- * -57.90
- * | R - (erf(x)-x)/x | <= 2
- *
- *
- * Remark. The formula is derived by noting
- * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
- * and that
- * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
- * is close to one. The interval is chosen because the fix
- * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
- * near 0.6174), and by some experiment, 0.84375 is chosen to
- * guarantee the error is less than one ulp for erf.
- *
- * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
- * c = 0.84506291151 rounded to single (24 bits)
- * erf(x) = sign(x) * (c + P1(s)/Q1(s))
- * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
- * 1+(c+P1(s)/Q1(s)) if x < 0
- * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
- * Remark: here we use the taylor series expansion at x=1.
- * erf(1+s) = erf(1) + s*Poly(s)
- * = 0.845.. + P1(s)/Q1(s)
- * That is, we use rational approximation to approximate
- * erf(1+s) - (c = (single)0.84506291151)
- * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
- * where
- * P1(s) = degree 6 poly in s
- * Q1(s) = degree 6 poly in s
- *
- * 3. For x in [1.25,1/0.35(~2.857143)],
- * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
- * erf(x) = 1 - erfc(x)
- * where
- * R1(z) = degree 7 poly in z, (z=1/x^2)
- * S1(z) = degree 8 poly in z
- *
- * 4. For x in [1/0.35,28]
- * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
- * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
- * = 2.0 - tiny (if x <= -6)
- * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
- * erf(x) = sign(x)*(1.0 - tiny)
- * where
- * R2(z) = degree 6 poly in z, (z=1/x^2)
- * S2(z) = degree 7 poly in z
- *
- * Note1:
- * To compute exp(-x*x-0.5625+R/S), let s be a single
- * precision number and s := x; then
- * -x*x = -s*s + (s-x)*(s+x)
- * exp(-x*x-0.5626+R/S) =
- * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
- * Note2:
- * Here 4 and 5 make use of the asymptotic series
- * exp(-x*x)
- * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
- * x*sqrt(pi)
- * We use rational approximation to approximate
- * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
- * Here is the error bound for R1/S1 and R2/S2
- * |R1/S1 - f(x)| < 2**(-62.57)
- * |R2/S2 - f(x)| < 2**(-61.52)
- *
- * 5. For inf > x >= 28
- * erf(x) = sign(x) *(1 - tiny) (raise inexact)
- * erfc(x) = tiny*tiny (raise underflow) if x > 0
- * = 2 - tiny if x<0
- *
- * 7. Special case:
- * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
- * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
- * erfc/erf(NaN) is NaN
- */
-
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-tiny = 1e-300,
-half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
- /* c = (float)0.84506291151 */
-erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
-/*
- * Coefficients for approximation to erf on [0,0.84375]
- */
-efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
-efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
-pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
-pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
-pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
-pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
-pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
-qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
-qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
-qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
-qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
-qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
-/*
- * Coefficients for approximation to erf in [0.84375,1.25]
- */
-pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
-pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
-pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
-pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
-pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
-pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
-pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
-qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
-qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
-qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
-qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
-qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
-qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
-/*
- * Coefficients for approximation to erfc in [1.25,1/0.35]
- */
-ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
-ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
-ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
-ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
-ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
-ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
-ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
-ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
-sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
-sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
-sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
-sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
-sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
-sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
-sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
-sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
-/*
- * Coefficients for approximation to erfc in [1/.35,28]
- */
-rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
-rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
-rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
-rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
-rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
-rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
-rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
-sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
-sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
-sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
-sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
-sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
-sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
-sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
-
-#ifdef __STDC__
- double fd_erf(double x)
-#else
- double fd_erf(x)
- double x;
-#endif
-{
- fd_twoints u;
- int hx,ix,i;
- double R,S,P,Q,s,y,z,r;
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) { /* erf(nan)=nan */
- i = ((unsigned)hx>>31)<<1;
- return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
- }
-
- if(ix < 0x3feb0000) { /* |x|<0.84375 */
- if(ix < 0x3e300000) { /* |x|<2**-28 */
- if (ix < 0x00800000)
- return 0.125*(8.0*x+efx8*x); /*avoid underflow */
- return x + efx*x;
- }
- z = x*x;
- r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
- s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
- y = r/s;
- return x + x*y;
- }
- if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
- s = fd_fabs(x)-one;
- P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
- Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
- if(hx>=0) return erx + P/Q; else return -erx - P/Q;
- }
- if (ix >= 0x40180000) { /* inf>|x|>=6 */
- if(hx>=0) return one-tiny; else return tiny-one;
- }
- x = fd_fabs(x);
- s = one/(x*x);
- if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
- R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
- ra5+s*(ra6+s*ra7))))));
- S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
- sa5+s*(sa6+s*(sa7+s*sa8)))))));
- } else { /* |x| >= 1/0.35 */
- R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
- rb5+s*rb6)))));
- S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
- sb5+s*(sb6+s*sb7))))));
- }
- z = x;
- u.d = z;
- __LO(u) = 0;
- z = u.d;
- r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
- if(hx>=0) return one-r/x; else return r/x-one;
-}
-
-#ifdef __STDC__
- double erfc(double x)
-#else
- double erfc(x)
- double x;
-#endif
-{
- fd_twoints u;
- int hx,ix;
- double R,S,P,Q,s,y,z,r;
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) { /* erfc(nan)=nan */
- /* erfc(+-inf)=0,2 */
- return (double)(((unsigned)hx>>31)<<1)+one/x;
- }
-
- if(ix < 0x3feb0000) { /* |x|<0.84375 */
- if(ix < 0x3c700000) /* |x|<2**-56 */
- return one-x;
- z = x*x;
- r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
- s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
- y = r/s;
- if(hx < 0x3fd00000) { /* x<1/4 */
- return one-(x+x*y);
- } else {
- r = x*y;
- r += (x-half);
- return half - r ;
- }
- }
- if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
- s = fd_fabs(x)-one;
- P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
- Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
- if(hx>=0) {
- z = one-erx; return z - P/Q;
- } else {
- z = erx+P/Q; return one+z;
- }
- }
- if (ix < 0x403c0000) { /* |x|<28 */
- x = fd_fabs(x);
- s = one/(x*x);
- if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
- R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
- ra5+s*(ra6+s*ra7))))));
- S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
- sa5+s*(sa6+s*(sa7+s*sa8)))))));
- } else { /* |x| >= 1/.35 ~ 2.857143 */
- if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
- R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
- rb5+s*rb6)))));
- S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
- sb5+s*(sb6+s*sb7))))));
- }
- z = x;
- u.d = z;
- __LO(u) = 0;
- z = u.d;
- r = __ieee754_exp(-z*z-0.5625)*
- __ieee754_exp((z-x)*(z+x)+R/S);
- if(hx>0) return r/x; else return two-r/x;
- } else {
- if(hx>0) return tiny*tiny; else return two-tiny;
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_expm1.c b/src/extension/script/js/fdlibm/s_expm1.c
deleted file mode 100644
index 578d2e144..000000000
--- a/src/extension/script/js/fdlibm/s_expm1.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_expm1.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* expm1(x)
- * Returns exp(x)-1, the exponential of x minus 1.
- *
- * Method
- * 1. Argument reduction:
- * Given x, find r and integer k such that
- *
- * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
- *
- * Here a correction term c will be computed to compensate
- * the error in r when rounded to a floating-point number.
- *
- * 2. Approximating expm1(r) by a special rational function on
- * the interval [0,0.34658]:
- * Since
- * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
- * we define R1(r*r) by
- * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
- * That is,
- * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
- * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
- * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
- * We use a special Reme algorithm on [0,0.347] to generate
- * a polynomial of degree 5 in r*r to approximate R1. The
- * maximum error of this polynomial approximation is bounded
- * by 2**-61. In other words,
- * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
- * where Q1 = -1.6666666666666567384E-2,
- * Q2 = 3.9682539681370365873E-4,
- * Q3 = -9.9206344733435987357E-6,
- * Q4 = 2.5051361420808517002E-7,
- * Q5 = -6.2843505682382617102E-9;
- * (where z=r*r, and the values of Q1 to Q5 are listed below)
- * with error bounded by
- * | 5 | -61
- * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
- * | |
- *
- * expm1(r) = exp(r)-1 is then computed by the following
- * specific way which minimize the accumulation rounding error:
- * 2 3
- * r r [ 3 - (R1 + R1*r/2) ]
- * expm1(r) = r + --- + --- * [--------------------]
- * 2 2 [ 6 - r*(3 - R1*r/2) ]
- *
- * To compensate the error in the argument reduction, we use
- * expm1(r+c) = expm1(r) + c + expm1(r)*c
- * ~ expm1(r) + c + r*c
- * Thus c+r*c will be added in as the correction terms for
- * expm1(r+c). Now rearrange the term to avoid optimization
- * screw up:
- * ( 2 2 )
- * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
- * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
- * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
- * ( )
- *
- * = r - E
- * 3. Scale back to obtain expm1(x):
- * From step 1, we have
- * expm1(x) = either 2^k*[expm1(r)+1] - 1
- * = or 2^k*[expm1(r) + (1-2^-k)]
- * 4. Implementation notes:
- * (A). To save one multiplication, we scale the coefficient Qi
- * to Qi*2^i, and replace z by (x^2)/2.
- * (B). To achieve maximum accuracy, we compute expm1(x) by
- * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
- * (ii) if k=0, return r-E
- * (iii) if k=-1, return 0.5*(r-E)-0.5
- * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
- * else return 1.0+2.0*(r-E);
- * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
- * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
- * (vii) return 2^k(1-((E+2^-k)-r))
- *
- * Special cases:
- * expm1(INF) is INF, expm1(NaN) is NaN;
- * expm1(-INF) is -1, and
- * for finite argument, only expm1(0)=0 is exact.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Misc. info.
- * For IEEE double
- * if x > 7.09782712893383973096e+02 then expm1(x) overflow
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-one = 1.0,
-really_big = 1.0e+300,
-tiny = 1.0e-300,
-o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
-ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
-ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
-invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
- /* scaled coefficients related to expm1 */
-Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
-Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
-Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
-Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
-Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
-
-#ifdef __STDC__
- double fd_expm1(double x)
-#else
- double fd_expm1(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y,hi,lo,c,t,e,hxs,hfx,r1;
- int k,xsb;
- unsigned hx;
-
- u.d = x;
- hx = __HI(u); /* high word of x */
- xsb = hx&0x80000000; /* sign bit of x */
- if(xsb==0) y=x; else y= -x; /* y = |x| */
- hx &= 0x7fffffff; /* high word of |x| */
-
- /* filter out huge and non-finite argument */
- if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
- if(hx >= 0x40862E42) { /* if |x|>=709.78... */
- if(hx>=0x7ff00000) {
- u.d = x;
- if(((hx&0xfffff)|__LO(u))!=0)
- return x+x; /* NaN */
- else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
- }
- if(x > o_threshold) return really_big*really_big; /* overflow */
- }
- if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
- if(x+tiny<0.0) /* raise inexact */
- return tiny-one; /* return -1 */
- }
- }
-
- /* argument reduction */
- if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
- if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
- if(xsb==0)
- {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
- else
- {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
- } else {
- k = (int)(invln2*x+((xsb==0)?0.5:-0.5));
- t = k;
- hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
- lo = t*ln2_lo;
- }
- x = hi - lo;
- c = (hi-x)-lo;
- }
- else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
- t = really_big+x; /* return x with inexact flags when x!=0 */
- return x - (t-(really_big+x));
- }
- else k = 0;
-
- /* x is now in primary range */
- hfx = 0.5*x;
- hxs = x*hfx;
- r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
- t = 3.0-r1*hfx;
- e = hxs*((r1-t)/(6.0 - x*t));
- if(k==0) return x - (x*e-hxs); /* c is 0 */
- else {
- e = (x*(e-c)-c);
- e -= hxs;
- if(k== -1) return 0.5*(x-e)-0.5;
- if(k==1)
- if(x < -0.25) return -2.0*(e-(x+0.5));
- else return one+2.0*(x-e);
- if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
- y = one-(e-x);
- u.d = y;
- __HI(u) += (k<<20); /* add k to y's exponent */
- y = u.d;
- return y-one;
- }
- t = one;
- if(k<20) {
- u.d = t;
- __HI(u) = 0x3ff00000 - (0x200000>>k); /* t=1-2^-k */
- t = u.d;
- y = t-(e-x);
- u.d = y;
- __HI(u) += (k<<20); /* add k to y's exponent */
- y = u.d;
- } else {
- u.d = t;
- __HI(u) = ((0x3ff-k)<<20); /* 2^-k */
- t = u.d;
- y = x-(e+t);
- y += one;
- u.d = y;
- __HI(u) += (k<<20); /* add k to y's exponent */
- y = u.d;
- }
- }
- return y;
-}
diff --git a/src/extension/script/js/fdlibm/s_fabs.c b/src/extension/script/js/fdlibm/s_fabs.c
deleted file mode 100644
index 6b029da10..000000000
--- a/src/extension/script/js/fdlibm/s_fabs.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_fabs.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * fabs(x) returns the absolute value of x.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_fabs(double x)
-#else
- double fd_fabs(x)
- double x;
-#endif
-{
- fd_twoints u;
- u.d = x;
- __HI(u) &= 0x7fffffff;
- x = u.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_finite.c b/src/extension/script/js/fdlibm/s_finite.c
deleted file mode 100644
index 4a0a4d3c6..000000000
--- a/src/extension/script/js/fdlibm/s_finite.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_finite.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * finite(x) returns 1 is x is finite, else 0;
- * no branching!
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- int fd_finite(double x)
-#else
- int fd_finite(x)
- double x;
-#endif
-{
- fd_twoints u;
- int hx;
- u.d = x;
- hx = __HI(u);
- return (unsigned)((hx&0x7fffffff)-0x7ff00000)>>31;
-}
diff --git a/src/extension/script/js/fdlibm/s_floor.c b/src/extension/script/js/fdlibm/s_floor.c
deleted file mode 100644
index 6c23495f0..000000000
--- a/src/extension/script/js/fdlibm/s_floor.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_floor.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * floor(x)
- * Return x rounded toward -inf to integral value
- * Method:
- * Bit twiddling.
- * Exception:
- * Inexact flag raised if x not equal to floor(x).
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double really_big = 1.0e300;
-#else
-static double really_big = 1.0e300;
-#endif
-
-#ifdef __STDC__
- double fd_floor(double x)
-#else
- double fd_floor(x)
- double x;
-#endif
-{
- fd_twoints u;
- int i0,i1,j0;
- unsigned i,j;
- u.d = x;
- i0 = __HI(u);
- i1 = __LO(u);
- j0 = ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) { /* raise inexact if x != 0 */
- if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */
- if(i0>=0) {i0=i1=0;}
- else if(((i0&0x7fffffff)|i1)!=0)
- { i0=0xbff00000;i1=0;}
- }
- } else {
- i = (0x000fffff)>>j0;
- if(((i0&i)|i1)==0) return x; /* x is integral */
- if(really_big+x>0.0) { /* raise inexact flag */
- if(i0<0) i0 += (0x00100000)>>j0;
- i0 &= (~i); i1=0;
- }
- }
- } else if (j0>51) {
- if(j0==0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i = ((unsigned)(0xffffffff))>>(j0-20);
- if((i1&i)==0) return x; /* x is integral */
- if(really_big+x>0.0) { /* raise inexact flag */
- if(i0<0) {
- if(j0==20) i0+=1;
- else {
- j = i1+(1<<(52-j0));
- if((int)j<i1) i0 +=1 ; /* got a carry */
- i1=j;
- }
- }
- i1 &= (~i);
- }
- }
- u.d = x;
- __HI(u) = i0;
- __LO(u) = i1;
- x = u.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_frexp.c b/src/extension/script/js/fdlibm/s_frexp.c
deleted file mode 100644
index bec2ecebc..000000000
--- a/src/extension/script/js/fdlibm/s_frexp.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_frexp.c 1.4 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * for non-zero x
- * x = frexp(arg,&exp);
- * return a double fp quantity x such that 0.5 <= |x| <1.0
- * and the corresponding binary exponent "exp". That is
- * arg = x*2^exp.
- * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
- * with *exp=0.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
-
-#ifdef __STDC__
- double fd_frexp(double x, int *eptr)
-#else
- double fd_frexp(x, eptr)
- double x; int *eptr;
-#endif
-{
- int hx, ix, lx;
- fd_twoints u;
- u.d = x;
- hx = __HI(u);
- ix = 0x7fffffff&hx;
- lx = __LO(u);
- *eptr = 0;
- if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
- if (ix<0x00100000) { /* subnormal */
- x *= two54;
- u.d = x;
- hx = __HI(u);
- ix = hx&0x7fffffff;
- *eptr = -54;
- }
- *eptr += (ix>>20)-1022;
- hx = (hx&0x800fffff)|0x3fe00000;
- u.d = x;
- __HI(u) = hx;
- x = u.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_ilogb.c b/src/extension/script/js/fdlibm/s_ilogb.c
deleted file mode 100644
index f769781a6..000000000
--- a/src/extension/script/js/fdlibm/s_ilogb.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_ilogb.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* ilogb(double x)
- * return the binary exponent of non-zero x
- * ilogb(0) = 0x80000001
- * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- int fd_ilogb(double x)
-#else
- int fd_ilogb(x)
- double x;
-#endif
-{
- int hx,lx,ix;
- fd_twoints u;
- u.d = x;
- hx = (__HI(u))&0x7fffffff; /* high word of x */
- if(hx<0x00100000) {
- lx = __LO(u);
- if((hx|lx)==0)
- return 0x80000001; /* ilogb(0) = 0x80000001 */
- else /* subnormal x */
- if(hx==0) {
- for (ix = -1043; lx>0; lx<<=1) ix -=1;
- } else {
- for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
- }
- return ix;
- }
- else if (hx<0x7ff00000) return (hx>>20)-1023;
- else return 0x7fffffff;
-}
diff --git a/src/extension/script/js/fdlibm/s_isnan.c b/src/extension/script/js/fdlibm/s_isnan.c
deleted file mode 100644
index 52f8759c7..000000000
--- a/src/extension/script/js/fdlibm/s_isnan.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_isnan.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * isnan(x) returns 1 is x is nan, else 0;
- * no branching!
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- int fd_isnan(double x)
-#else
- int fd_isnan(x)
- double x;
-#endif
-{
- fd_twoints u;
- int hx,lx;
- u.d = x;
- hx = (__HI(u)&0x7fffffff);
- lx = __LO(u);
- hx |= (unsigned)(lx|(-lx))>>31;
- hx = 0x7ff00000 - hx;
- return ((unsigned)(hx))>>31;
-}
diff --git a/src/extension/script/js/fdlibm/s_ldexp.c b/src/extension/script/js/fdlibm/s_ldexp.c
deleted file mode 100644
index 9475520d4..000000000
--- a/src/extension/script/js/fdlibm/s_ldexp.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_ldexp.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include "fdlibm.h"
-#include <errno.h>
-
-#ifdef __STDC__
- double fd_ldexp(double value, int exp)
-#else
- double fd_ldexp(value, exp)
- double value; int exp;
-#endif
-{
- if(!fd_finite(value)||value==0.0) return value;
- value = fd_scalbn(value,exp);
- if(!fd_finite(value)||value==0.0) errno = ERANGE;
- return value;
-}
diff --git a/src/extension/script/js/fdlibm/s_lib_version.c b/src/extension/script/js/fdlibm/s_lib_version.c
deleted file mode 100644
index 2ccf67d51..000000000
--- a/src/extension/script/js/fdlibm/s_lib_version.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_lib_version.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * MACRO for standards
- */
-
-#include "fdlibm.h"
-
-/*
- * define and initialize _LIB_VERSION
- */
-#ifdef _POSIX_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_;
-#else
-#ifdef _XOPEN_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_;
-#else
-#ifdef _SVID3_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _SVID_;
-#else /* default _IEEE_MODE */
-_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
-#endif
-#endif
-#endif
diff --git a/src/extension/script/js/fdlibm/s_log1p.c b/src/extension/script/js/fdlibm/s_log1p.c
deleted file mode 100644
index 1840156b1..000000000
--- a/src/extension/script/js/fdlibm/s_log1p.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_log1p.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* double log1p(double x)
- *
- * Method :
- * 1. Argument Reduction: find k and f such that
- * 1+x = 2^k * (1+f),
- * where sqrt(2)/2 < 1+f < sqrt(2) .
- *
- * Note. If k=0, then f=x is exact. However, if k!=0, then f
- * may not be representable exactly. In that case, a correction
- * term is need. Let u=1+x rounded. Let c = (1+x)-u, then
- * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
- * and add back the correction term c/u.
- * (Note: when x > 2**53, one can simply return log(x))
- *
- * 2. Approximation of log1p(f).
- * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
- * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
- * = 2s + s*R
- * We use a special Reme algorithm on [0,0.1716] to generate
- * a polynomial of degree 14 to approximate R The maximum error
- * of this polynomial approximation is bounded by 2**-58.45. In
- * other words,
- * 2 4 6 8 10 12 14
- * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s
- * (the values of Lp1 to Lp7 are listed in the program)
- * and
- * | 2 14 | -58.45
- * | Lp1*s +...+Lp7*s - R(z) | <= 2
- * | |
- * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
- * In order to guarantee error in log below 1ulp, we compute log
- * by
- * log1p(f) = f - (hfsq - s*(hfsq+R)).
- *
- * 3. Finally, log1p(x) = k*ln2 + log1p(f).
- * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
- * Here ln2 is split into two floating point number:
- * ln2_hi + ln2_lo,
- * where n*ln2_hi is always exact for |n| < 2000.
- *
- * Special cases:
- * log1p(x) is NaN with signal if x < -1 (including -INF) ;
- * log1p(+INF) is +INF; log1p(-1) is -INF with signal;
- * log1p(NaN) is that NaN with no signal.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- *
- * Note: Assuming log() return accurate answer, the following
- * algorithm can be used to compute log1p(x) to within a few ULP:
- *
- * u = 1+x;
- * if(u==1.0) return x ; else
- * return log(u)*(x/(u-1.0));
- *
- * See HP-15C Advanced Functions Handbook, p.193.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
-ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
-two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
-Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
-Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
-Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
-Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
-Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
-Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
-Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
-
-static double zero = 0.0;
-
-#ifdef __STDC__
- double fd_log1p(double x)
-#else
- double fd_log1p(x)
- double x;
-#endif
-{
- double hfsq,f,c,s,z,R,u;
- int k,hx,hu,ax;
- fd_twoints un;
-
- un.d = x;
- hx = __HI(un); /* high word of x */
- ax = hx&0x7fffffff;
-
- k = 1;
- if (hx < 0x3FDA827A) { /* x < 0.41422 */
- if(ax>=0x3ff00000) { /* x <= -1.0 */
- if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
- else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
- }
- if(ax<0x3e200000) { /* |x| < 2**-29 */
- if(two54+x>zero /* raise inexact */
- &&ax<0x3c900000) /* |x| < 2**-54 */
- return x;
- else
- return x - x*x*0.5;
- }
- if(hx>0||hx<=((int)0xbfd2bec3)) {
- k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */
- }
- if (hx >= 0x7ff00000) return x+x;
- if(k!=0) {
- if(hx<0x43400000) {
- u = 1.0+x;
- un.d = u;
- hu = __HI(un); /* high word of u */
- k = (hu>>20)-1023;
- c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
- c /= u;
- } else {
- u = x;
- un.d = u;
- hu = __HI(un); /* high word of u */
- k = (hu>>20)-1023;
- c = 0;
- }
- hu &= 0x000fffff;
- if(hu<0x6a09e) {
- un.d = u;
- __HI(un) = hu|0x3ff00000; /* normalize u */
- u = un.d;
- } else {
- k += 1;
- un.d = u;
- __HI(un) = hu|0x3fe00000; /* normalize u/2 */
- u = un.d;
- hu = (0x00100000-hu)>>2;
- }
- f = u-1.0;
- }
- hfsq=0.5*f*f;
- if(hu==0) { /* |f| < 2**-20 */
- if(f==zero) if(k==0) return zero;
- else {c += k*ln2_lo; return k*ln2_hi+c;}
- R = hfsq*(1.0-0.66666666666666666*f);
- if(k==0) return f-R; else
- return k*ln2_hi-((R-(k*ln2_lo+c))-f);
- }
- s = f/(2.0+f);
- z = s*s;
- R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
- if(k==0) return f-(hfsq-s*(hfsq+R)); else
- return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
-}
diff --git a/src/extension/script/js/fdlibm/s_logb.c b/src/extension/script/js/fdlibm/s_logb.c
deleted file mode 100644
index f885c4dc3..000000000
--- a/src/extension/script/js/fdlibm/s_logb.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_logb.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * double logb(x)
- * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
- * Use ilogb instead.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_logb(double x)
-#else
- double fd_logb(x)
- double x;
-#endif
-{
- int lx,ix;
- fd_twoints u;
-
- u.d = x;
- ix = (__HI(u))&0x7fffffff; /* high |x| */
- lx = __LO(u); /* low x */
- if((ix|lx)==0) return -1.0/fd_fabs(x);
- if(ix>=0x7ff00000) return x*x;
- if((ix>>=20)==0) /* IEEE 754 logb */
- return -1022.0;
- else
- return (double) (ix-1023);
-}
diff --git a/src/extension/script/js/fdlibm/s_matherr.c b/src/extension/script/js/fdlibm/s_matherr.c
deleted file mode 100644
index cd99ca88f..000000000
--- a/src/extension/script/js/fdlibm/s_matherr.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_matherr.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- int fd_matherr(struct exception *x)
-#else
- int fd_matherr(x)
- struct exception *x;
-#endif
-{
- int n=0;
- if(x->arg1!=x->arg1) return 0;
- return n;
-}
diff --git a/src/extension/script/js/fdlibm/s_modf.c b/src/extension/script/js/fdlibm/s_modf.c
deleted file mode 100644
index 3b182bd3b..000000000
--- a/src/extension/script/js/fdlibm/s_modf.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_modf.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * modf(double x, double *iptr)
- * return fraction part of x, and return x's integral part in *iptr.
- * Method:
- * Bit twiddling.
- *
- * Exception:
- * No exception.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double one = 1.0;
-#else
-static double one = 1.0;
-#endif
-
-#ifdef __STDC__
- double fd_modf(double x, double *iptr)
-#else
- double fd_modf(x, iptr)
- double x,*iptr;
-#endif
-{
- int i0,i1,j0;
- unsigned i;
- fd_twoints u;
- u.d = x;
- i0 = __HI(u); /* high x */
- i1 = __LO(u); /* low x */
- j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
- if(j0<20) { /* integer part in high x */
- if(j0<0) { /* |x|<1 */
- u.d = *iptr;
- __HI(u) = i0&0x80000000;
- __LO(u) = 0; /* *iptr = +-0 */
- *iptr = u.d;
- return x;
- } else {
- i = (0x000fffff)>>j0;
- if(((i0&i)|i1)==0) { /* x is integral */
- *iptr = x;
- u.d = x;
- __HI(u) &= 0x80000000;
- __LO(u) = 0; /* return +-0 */
- x = u.d;
- return x;
- } else {
- u.d = *iptr;
- __HI(u) = i0&(~i);
- __LO(u) = 0;
- *iptr = u.d;
- return x - *iptr;
- }
- }
- } else if (j0>51) { /* no fraction part */
- *iptr = x*one;
- u.d = x;
- __HI(u) &= 0x80000000;
- __LO(u) = 0; /* return +-0 */
- x = u.d;
- return x;
- } else { /* fraction part in low x */
- i = ((unsigned)(0xffffffff))>>(j0-20);
- if((i1&i)==0) { /* x is integral */
- *iptr = x;
- u.d = x;
- __HI(u) &= 0x80000000;
- __LO(u) = 0; /* return +-0 */
- x = u.d;
- return x;
- } else {
- u.d = *iptr;
- __HI(u) = i0;
- __LO(u) = i1&(~i);
- *iptr = u.d;
- return x - *iptr;
- }
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_nextafter.c b/src/extension/script/js/fdlibm/s_nextafter.c
deleted file mode 100644
index f71c5c835..000000000
--- a/src/extension/script/js/fdlibm/s_nextafter.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_nextafter.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* IEEE functions
- * nextafter(x,y)
- * return the next machine floating-point number of x in the
- * direction toward y.
- * Special cases:
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_nextafter(double x, double y)
-#else
- double fd_nextafter(x,y)
- double x,y;
-#endif
-{
- int hx,hy,ix,iy;
- unsigned lx,ly;
- fd_twoints ux, uy;
-
- ux.d = x; uy.d = y;
- hx = __HI(ux); /* high word of x */
- lx = __LO(ux); /* low word of x */
- hy = __HI(uy); /* high word of y */
- ly = __LO(uy); /* low word of y */
- ix = hx&0x7fffffff; /* |x| */
- iy = hy&0x7fffffff; /* |y| */
-
- if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
- ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
- return x+y;
- if(x==y) return x; /* x=y, return x */
- if((ix|lx)==0) { /* x == 0 */
- ux.d = x;
- __HI(ux) = hy&0x80000000; /* return +-minsubnormal */
- __LO(ux) = 1;
- x = ux.d;
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
- }
- if(hx>=0) { /* x > 0 */
- if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
- if(lx==0) hx -= 1;
- lx -= 1;
- } else { /* x < y, x += ulp */
- lx += 1;
- if(lx==0) hx += 1;
- }
- } else { /* x < 0 */
- if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
- if(lx==0) hx -= 1;
- lx -= 1;
- } else { /* x > y, x += ulp */
- lx += 1;
- if(lx==0) hx += 1;
- }
- }
- hy = hx&0x7ff00000;
- if(hy>=0x7ff00000) return x+x; /* overflow */
- if(hy<0x00100000) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- uy.d = y;
- __HI(uy) = hx; __LO(uy) = lx;
- y = uy.d;
- return y;
- }
- }
- ux.d = x;
- __HI(ux) = hx; __LO(ux) = lx;
- x = ux.d;
- return x;
-}
diff --git a/src/extension/script/js/fdlibm/s_rint.c b/src/extension/script/js/fdlibm/s_rint.c
deleted file mode 100644
index 3c4fab6d9..000000000
--- a/src/extension/script/js/fdlibm/s_rint.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_rint.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * rint(x)
- * Return x rounded to integral value according to the prevailing
- * rounding mode.
- * Method:
- * Using floating addition.
- * Exception:
- * Inexact flag raised if x not equal to rint(x).
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-TWO52[2]={
- 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
-};
-
-#ifdef __STDC__
- double fd_rint(double x)
-#else
- double fd_rint(x)
- double x;
-#endif
-{
- int i0,j0,sx;
- unsigned i,i1;
- double w,t;
- fd_twoints u;
-
- u.d = x;
- i0 = __HI(u);
- sx = (i0>>31)&1;
- i1 = __LO(u);
- j0 = ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) {
- if(((i0&0x7fffffff)|i1)==0) return x;
- i1 |= (i0&0x0fffff);
- i0 &= 0xfffe0000;
- i0 |= ((i1|-(int)i1)>>12)&0x80000;
- u.d = x;
- __HI(u)=i0;
- x = u.d;
- w = TWO52[sx]+x;
- t = w-TWO52[sx];
- u.d = t;
- i0 = __HI(u);
- __HI(u) = (i0&0x7fffffff)|(sx<<31);
- t = u.d;
- return t;
- } else {
- i = (0x000fffff)>>j0;
- if(((i0&i)|i1)==0) return x; /* x is integral */
- i>>=1;
- if(((i0&i)|i1)!=0) {
- if(j0==19) i1 = 0x40000000; else
- i0 = (i0&(~i))|((0x20000)>>j0);
- }
- }
- } else if (j0>51) {
- if(j0==0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i = ((unsigned)(0xffffffff))>>(j0-20);
- if((i1&i)==0) return x; /* x is integral */
- i>>=1;
- if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
- }
- u.d = x;
- __HI(u) = i0;
- __LO(u) = i1;
- x = u.d;
- w = TWO52[sx]+x;
- return w-TWO52[sx];
-}
diff --git a/src/extension/script/js/fdlibm/s_scalbn.c b/src/extension/script/js/fdlibm/s_scalbn.c
deleted file mode 100644
index 3deeaa305..000000000
--- a/src/extension/script/js/fdlibm/s_scalbn.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_scalbn.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * scalbn (double x, int n)
- * scalbn(x,n) returns x* 2**n computed by exponent
- * manipulation rather than by actually performing an
- * exponentiation or a multiplication.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-really_big = 1.0e+300,
-tiny = 1.0e-300;
-
-#ifdef __STDC__
- double fd_scalbn (double x, int n)
-#else
- double fd_scalbn (x,n)
- double x; int n;
-#endif
-{
- fd_twoints u;
- int k,hx,lx;
- u.d = x;
- hx = __HI(u);
- lx = __LO(u);
- k = (hx&0x7ff00000)>>20; /* extract exponent */
- if (k==0) { /* 0 or subnormal x */
- if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
- x *= two54;
- u.d = x;
- hx = __HI(u);
- k = ((hx&0x7ff00000)>>20) - 54;
- if (n< -50000) return tiny*x; /*underflow*/
- }
- if (k==0x7ff) return x+x; /* NaN or Inf */
- k = k+n;
- if (k > 0x7fe) return really_big*fd_copysign(really_big,x); /* overflow */
- if (k > 0) /* normal result */
- {u.d = x; __HI(u) = (hx&0x800fffff)|(k<<20); x = u.d; return x;}
- if (k <= -54) {
- if (n > 50000) /* in case integer overflow in n+k */
- return really_big*fd_copysign(really_big,x); /*overflow*/
- else return tiny*fd_copysign(tiny,x); /*underflow*/
- }
- k += 54; /* subnormal result */
- u.d = x;
- __HI(u) = (hx&0x800fffff)|(k<<20);
- x = u.d;
- return x*twom54;
-}
diff --git a/src/extension/script/js/fdlibm/s_signgam.c b/src/extension/script/js/fdlibm/s_signgam.c
deleted file mode 100644
index 4eb8ce72f..000000000
--- a/src/extension/script/js/fdlibm/s_signgam.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include "fdlibm.h"
-int signgam = 0;
diff --git a/src/extension/script/js/fdlibm/s_significand.c b/src/extension/script/js/fdlibm/s_significand.c
deleted file mode 100644
index 2e1c0b28f..000000000
--- a/src/extension/script/js/fdlibm/s_significand.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_significand.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * significand(x) computes just
- * scalb(x, (double) -ilogb(x)),
- * for exercising the fraction-part(F) IEEE 754-1985 test vector.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_significand(double x)
-#else
- double fd_significand(x)
- double x;
-#endif
-{
- return __ieee754_scalb(x,(double) -fd_ilogb(x));
-}
diff --git a/src/extension/script/js/fdlibm/s_sin.c b/src/extension/script/js/fdlibm/s_sin.c
deleted file mode 100644
index 8bbc5c62d..000000000
--- a/src/extension/script/js/fdlibm/s_sin.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_sin.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* sin(x)
- * Return sine function of x.
- *
- * kernel function:
- * __kernel_sin ... sine function on [-pi/4,pi/4]
- * __kernel_cos ... cose function on [-pi/4,pi/4]
- * __ieee754_rem_pio2 ... argument reduction routine
- *
- * Method.
- * Let S,C and T denote the sin, cos and tan respectively on
- * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
- * in [-pi/4 , +pi/4], and let n = k mod 4.
- * We have
- *
- * n sin(x) cos(x) tan(x)
- * ----------------------------------------------------------
- * 0 S C T
- * 1 C -S -1/T
- * 2 -S -C T
- * 3 -C S -1/T
- * ----------------------------------------------------------
- *
- * Special cases:
- * Let trig be any of sin, cos, or tan.
- * trig(+-INF) is NaN, with signals;
- * trig(NaN) is that NaN;
- *
- * Accuracy:
- * TRIG(x) returns trig(x) nearly rounded
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_sin(double x)
-#else
- double fd_sin(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y[2],z=0.0;
- int n, ix;
-
- /* High word of x. */
- u.d = x;
- ix = __HI(u);
-
- /* |x| ~< pi/4 */
- ix &= 0x7fffffff;
- if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
-
- /* sin(Inf or NaN) is NaN */
- else if (ix>=0x7ff00000) return x-x;
-
- /* argument reduction needed */
- else {
- n = __ieee754_rem_pio2(x,y);
- switch(n&3) {
- case 0: return __kernel_sin(y[0],y[1],1);
- case 1: return __kernel_cos(y[0],y[1]);
- case 2: return -__kernel_sin(y[0],y[1],1);
- default:
- return -__kernel_cos(y[0],y[1]);
- }
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_tan.c b/src/extension/script/js/fdlibm/s_tan.c
deleted file mode 100644
index ded36c1d7..000000000
--- a/src/extension/script/js/fdlibm/s_tan.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_tan.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* tan(x)
- * Return tangent function of x.
- *
- * kernel function:
- * __kernel_tan ... tangent function on [-pi/4,pi/4]
- * __ieee754_rem_pio2 ... argument reduction routine
- *
- * Method.
- * Let S,C and T denote the sin, cos and tan respectively on
- * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
- * in [-pi/4 , +pi/4], and let n = k mod 4.
- * We have
- *
- * n sin(x) cos(x) tan(x)
- * ----------------------------------------------------------
- * 0 S C T
- * 1 C -S -1/T
- * 2 -S -C T
- * 3 -C S -1/T
- * ----------------------------------------------------------
- *
- * Special cases:
- * Let trig be any of sin, cos, or tan.
- * trig(+-INF) is NaN, with signals;
- * trig(NaN) is that NaN;
- *
- * Accuracy:
- * TRIG(x) returns trig(x) nearly rounded
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_tan(double x)
-#else
- double fd_tan(x)
- double x;
-#endif
-{
- fd_twoints u;
- double y[2],z=0.0;
- int n, ix;
-
- /* High word of x. */
- u.d = x;
- ix = __HI(u);
-
- /* |x| ~< pi/4 */
- ix &= 0x7fffffff;
- if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
-
- /* tan(Inf or NaN) is NaN */
- else if (ix>=0x7ff00000) return x-x; /* NaN */
-
- /* argument reduction needed */
- else {
- n = __ieee754_rem_pio2(x,y);
- return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
- -1 -- n odd */
- }
-}
diff --git a/src/extension/script/js/fdlibm/s_tanh.c b/src/extension/script/js/fdlibm/s_tanh.c
deleted file mode 100644
index aa6809f85..000000000
--- a/src/extension/script/js/fdlibm/s_tanh.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)s_tanh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* Tanh(x)
- * Return the Hyperbolic Tangent of x
- *
- * Method :
- * x -x
- * e - e
- * 0. tanh(x) is defined to be -----------
- * x -x
- * e + e
- * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
- * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
- * -t
- * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
- * t + 2
- * 2
- * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
- * t + 2
- * 22.0 < x <= INF : tanh(x) := 1.
- *
- * Special cases:
- * tanh(NaN) is NaN;
- * only tanh(0)=0 is exact for finite argument.
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double one=1.0, two=2.0, tiny = 1.0e-300;
-#else
-static double one=1.0, two=2.0, tiny = 1.0e-300;
-#endif
-
-#ifdef __STDC__
- double fd_tanh(double x)
-#else
- double fd_tanh(x)
- double x;
-#endif
-{
- double t,z;
- int jx,ix;
- fd_twoints u;
-
- /* High word of |x|. */
- u.d = x;
- jx = __HI(u);
- ix = jx&0x7fffffff;
-
- /* x is INF or NaN */
- if(ix>=0x7ff00000) {
- if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
- else return one/x-one; /* tanh(NaN) = NaN */
- }
-
- /* |x| < 22 */
- if (ix < 0x40360000) { /* |x|<22 */
- if (ix<0x3c800000) /* |x|<2**-55 */
- return x*(one+x); /* tanh(small) = small */
- if (ix>=0x3ff00000) { /* |x|>=1 */
- t = fd_expm1(two*fd_fabs(x));
- z = one - two/(t+two);
- } else {
- t = fd_expm1(-two*fd_fabs(x));
- z= -t/(t+two);
- }
- /* |x| > 22, return +-1 */
- } else {
- z = one - tiny; /* raised inexact flag */
- }
- return (jx>=0)? z: -z;
-}
diff --git a/src/extension/script/js/fdlibm/w_acos.c b/src/extension/script/js/fdlibm/w_acos.c
deleted file mode 100644
index 872c81d20..000000000
--- a/src/extension/script/js/fdlibm/w_acos.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_acos.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrap_acos(x)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_acos(double x) /* wrapper acos */
-#else
- double fd_acos(x) /* wrapper acos */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acos(x);
-#else
- double z;
- z = __ieee754_acos(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(fd_fabs(x)>1.0) {
- int err;
- return __kernel_standard(x,x,1,&err); /* acos(|x|>1) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_acosh.c b/src/extension/script/js/fdlibm/w_acosh.c
deleted file mode 100644
index 745d402ea..000000000
--- a/src/extension/script/js/fdlibm/w_acosh.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_acosh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/*
- * wrapper acosh(x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_acosh(double x) /* wrapper acosh */
-#else
- double fd_acosh(x) /* wrapper acosh */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acosh(x);
-#else
- double z;
- z = __ieee754_acosh(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(x<1.0) {
- int err;
- return __kernel_standard(x,x,29,&err); /* acosh(x<1) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_asin.c b/src/extension/script/js/fdlibm/w_asin.c
deleted file mode 100644
index 18aaefde9..000000000
--- a/src/extension/script/js/fdlibm/w_asin.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_asin.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/*
- * wrapper asin(x)
- */
-
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_asin(double x) /* wrapper asin */
-#else
- double fd_asin(x) /* wrapper asin */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_asin(x);
-#else
- double z;
- z = __ieee754_asin(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(fd_fabs(x)>1.0) {
- int err;
- return __kernel_standard(x,x,2,&err); /* asin(|x|>1) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_atan2.c b/src/extension/script/js/fdlibm/w_atan2.c
deleted file mode 100644
index 8cfa4bbbd..000000000
--- a/src/extension/script/js/fdlibm/w_atan2.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_atan2.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/*
- * wrapper atan2(y,x)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_atan2(double y, double x) /* wrapper atan2 */
-#else
- double fd_atan2(y,x) /* wrapper atan2 */
- double y,x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atan2(y,x);
-#else
- double z;
- z = __ieee754_atan2(y,x);
- if(_LIB_VERSION == _IEEE_||fd_isnan(x)||fd_isnan(y)) return z;
- if(x==0.0&&y==0.0) {
- int err;
- return __kernel_standard(y,x,3,&err); /* atan2(+-0,+-0) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_atanh.c b/src/extension/script/js/fdlibm/w_atanh.c
deleted file mode 100644
index 6ba52d1e2..000000000
--- a/src/extension/script/js/fdlibm/w_atanh.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_atanh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-/*
- * wrapper atanh(x)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_atanh(double x) /* wrapper atanh */
-#else
- double fd_atanh(x) /* wrapper atanh */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atanh(x);
-#else
- double z,y;
- z = __ieee754_atanh(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- y = fd_fabs(x);
- if(y>=1.0) {
- int err;
- if(y>1.0)
- return __kernel_standard(x,x,30,&err); /* atanh(|x|>1) */
- else
- return __kernel_standard(x,x,31,&err); /* atanh(|x|==1) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_cosh.c b/src/extension/script/js/fdlibm/w_cosh.c
deleted file mode 100644
index 146449e02..000000000
--- a/src/extension/script/js/fdlibm/w_cosh.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_cosh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper cosh(x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_cosh(double x) /* wrapper cosh */
-#else
- double fd_cosh(x) /* wrapper cosh */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_cosh(x);
-#else
- double z;
- z = __ieee754_cosh(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(fd_fabs(x)>7.10475860073943863426e+02) {
- int err;
- return __kernel_standard(x,x,5,&err); /* cosh overflow */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_exp.c b/src/extension/script/js/fdlibm/w_exp.c
deleted file mode 100644
index f5dea0b01..000000000
--- a/src/extension/script/js/fdlibm/w_exp.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_exp.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper exp(x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-static const double
-#else
-static double
-#endif
-o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
-u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
-
-#ifdef __STDC__
- double fd_exp(double x) /* wrapper exp */
-#else
- double fd_exp(x) /* wrapper exp */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_exp(x);
-#else
- double z;
- z = __ieee754_exp(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(fd_finite(x)) {
- int err;
- if(x>o_threshold)
- return __kernel_standard(x,x,6,&err); /* exp overflow */
- else if(x<u_threshold)
- return __kernel_standard(x,x,7,&err); /* exp underflow */
- }
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_fmod.c b/src/extension/script/js/fdlibm/w_fmod.c
deleted file mode 100644
index 76862096d..000000000
--- a/src/extension/script/js/fdlibm/w_fmod.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_fmod.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper fmod(x,y)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_fmod(double x, double y) /* wrapper fmod */
-#else
- double fd_fmod(x,y) /* wrapper fmod */
- double x,y;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_fmod(x,y);
-#else
- double z;
- z = __ieee754_fmod(x,y);
- if(_LIB_VERSION == _IEEE_ ||fd_isnan(y)||fd_isnan(x)) return z;
- if(y==0.0) {
- int err;
- return __kernel_standard(x,y,27,&err); /* fmod(x,0) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_gamma.c b/src/extension/script/js/fdlibm/w_gamma.c
deleted file mode 100644
index 9eb8e429c..000000000
--- a/src/extension/script/js/fdlibm/w_gamma.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_gamma.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* double gamma(double x)
- * Return the logarithm of the Gamma function of x.
- *
- * Method: call gamma_r
- */
-
-#include "fdlibm.h"
-
-extern int signgam;
-
-#ifdef __STDC__
- double fd_gamma(double x)
-#else
- double fd_gamma(x)
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_gamma_r(x,&signgam);
-#else
- double y;
- y = __ieee754_gamma_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!fd_finite(y)&&fd_finite(x)) {
- int err;
- if(fd_floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,41,&err); /* gamma pole */
- else
- return __kernel_standard(x,x,40,&err); /* gamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_gamma_r.c b/src/extension/script/js/fdlibm/w_gamma_r.c
deleted file mode 100644
index 2669b4f59..000000000
--- a/src/extension/script/js/fdlibm/w_gamma_r.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_gamma_r.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper double gamma_r(double x, int *signgamp)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
-#else
- double fd_gamma_r(x,signgamp) /* wrapper lgamma_r */
- double x; int *signgamp;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_gamma_r(x,signgamp);
-#else
- double y;
- y = __ieee754_gamma_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!fd_finite(y)&&fd_finite(x)) {
- int err;
- if(fd_floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,41,&err); /* gamma pole */
- else
- return __kernel_standard(x,x,40,&err); /* gamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_hypot.c b/src/extension/script/js/fdlibm/w_hypot.c
deleted file mode 100644
index bfaac66c0..000000000
--- a/src/extension/script/js/fdlibm/w_hypot.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_hypot.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper hypot(x,y)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_hypot(double x, double y)/* wrapper hypot */
-#else
- double fd_hypot(x,y) /* wrapper hypot */
- double x,y;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_hypot(x,y);
-#else
- double z;
- z = __ieee754_hypot(x,y);
- if(_LIB_VERSION == _IEEE_) return z;
- if((!fd_finite(z))&&fd_finite(x)&&fd_finite(y)) {
- int err;
- return __kernel_standard(x,y,4,&err); /* hypot overflow */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_j0.c b/src/extension/script/js/fdlibm/w_j0.c
deleted file mode 100644
index 5e676ff60..000000000
--- a/src/extension/script/js/fdlibm/w_j0.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_j0.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper j0(double x), y0(double x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_j0(double x) /* wrapper j0 */
-#else
- double fd_j0(x) /* wrapper j0 */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j0(x);
-#else
- double z = __ieee754_j0(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(fd_fabs(x)>X_TLOSS) {
- int err;
- return __kernel_standard(x,x,34,&err); /* j0(|x|>X_TLOSS) */
- } else
- return z;
-#endif
-}
-
-#ifdef __STDC__
- double y0(double x) /* wrapper y0 */
-#else
- double y0(x) /* wrapper y0 */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y0(x);
-#else
- double z;
- int err;
- z = __ieee754_y0(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard(x,x,8,&err);
- else
- /* d = zero/(x-x); */
- return __kernel_standard(x,x,9,&err);
- }
- if(x>X_TLOSS) {
- return __kernel_standard(x,x,35,&err); /* y0(x>X_TLOSS) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_j1.c b/src/extension/script/js/fdlibm/w_j1.c
deleted file mode 100644
index 86a506bc2..000000000
--- a/src/extension/script/js/fdlibm/w_j1.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_j1.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper of j1,y1
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_j1(double x) /* wrapper j1 */
-#else
- double fd_j1(x) /* wrapper j1 */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j1(x);
-#else
- double z;
- z = __ieee754_j1(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
- if(fd_fabs(x)>X_TLOSS) {
- int err;
- return __kernel_standard(x,x,36,&err); /* j1(|x|>X_TLOSS) */
- } else
- return z;
-#endif
-}
-
-#ifdef __STDC__
- double y1(double x) /* wrapper y1 */
-#else
- double y1(x) /* wrapper y1 */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y1(x);
-#else
- double z;
- int err;
- z = __ieee754_y1(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard(x,x,10,&err);
- else
- /* d = zero/(x-x); */
- return __kernel_standard(x,x,11,&err);
- }
- if(x>X_TLOSS) {
- return __kernel_standard(x,x,37,&err); /* y1(x>X_TLOSS) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_jn.c b/src/extension/script/js/fdlibm/w_jn.c
deleted file mode 100644
index 6926b0da8..000000000
--- a/src/extension/script/js/fdlibm/w_jn.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_jn.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper jn(int n, double x), yn(int n, double x)
- * floating point Bessel's function of the 1st and 2nd kind
- * of order n
- *
- * Special cases:
- * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
- * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
- * Note 2. About jn(n,x), yn(n,x)
- * For n=0, j0(x) is called,
- * for n=1, j1(x) is called,
- * for n<x, forward recursion us used starting
- * from values of j0(x) and j1(x).
- * for n>x, a continued fraction approximation to
- * j(n,x)/j(n-1,x) is evaluated and then backward
- * recursion is used starting from a supposed value
- * for j(n,x). The resulting value of j(0,x) is
- * compared with the actual value to correct the
- * supposed value of j(n,x).
- *
- * yn(n,x) is similar in all respects, except
- * that forward recursion is used for all
- * values of n>1.
- *
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_jn(int n, double x) /* wrapper jn */
-#else
- double fd_jn(n,x) /* wrapper jn */
- double x; int n;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_jn(n,x);
-#else
- double z;
- z = __ieee754_jn(n,x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
- if(fd_fabs(x)>X_TLOSS) {
- int err;
- return __kernel_standard((double)n,x,38,&err); /* jn(|x|>X_TLOSS,n) */
- } else
- return z;
-#endif
-}
-
-#ifdef __STDC__
- double yn(int n, double x) /* wrapper yn */
-#else
- double yn(n,x) /* wrapper yn */
- double x; int n;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_yn(n,x);
-#else
- double z;
- int err;
- z = __ieee754_yn(n,x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard((double)n,x,12,&err);
- else
- /* d = zero/(x-x); */
- return __kernel_standard((double)n,x,13,&err);
- }
- if(x>X_TLOSS) {
- return __kernel_standard((double)n,x,39,&err); /* yn(x>X_TLOSS,n) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_lgamma.c b/src/extension/script/js/fdlibm/w_lgamma.c
deleted file mode 100644
index f7576e892..000000000
--- a/src/extension/script/js/fdlibm/w_lgamma.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_lgamma.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-/* double lgamma(double x)
- * Return the logarithm of the Gamma function of x.
- *
- * Method: call __ieee754_lgamma_r
- */
-
-#include "fdlibm.h"
-
-extern int signgam;
-
-#ifdef __STDC__
- double fd_lgamma(double x)
-#else
- double fd_lgamma(x)
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,&signgam);
-#else
- double y;
- y = __ieee754_lgamma_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!fd_finite(y)&&fd_finite(x)) {
- int err;
- if(fd_floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,15,&err); /* lgamma pole */
- else
- return __kernel_standard(x,x,14,&err); /* lgamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_lgamma_r.c b/src/extension/script/js/fdlibm/w_lgamma_r.c
deleted file mode 100644
index ba2ad5933..000000000
--- a/src/extension/script/js/fdlibm/w_lgamma_r.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_lgamma_r.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper double lgamma_r(double x, int *signgamp)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */
-#else
- double fd_lgamma_r(x,signgamp) /* wrapper lgamma_r */
- double x; int *signgamp;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,signgamp);
-#else
- double y;
- y = __ieee754_lgamma_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!fd_finite(y)&&fd_finite(x)) {
- int err;
- if(fd_floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,15,&err); /* lgamma pole */
- else
- return __kernel_standard(x,x,14,&err); /* lgamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_log.c b/src/extension/script/js/fdlibm/w_log.c
deleted file mode 100644
index 7e358fcf1..000000000
--- a/src/extension/script/js/fdlibm/w_log.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_log.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper log(x)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_log(double x) /* wrapper log */
-#else
- double fd_log(x) /* wrapper log */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_log(x);
-#else
- double z;
- int err;
- z = __ieee754_log(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x) || x > 0.0) return z;
- if(x==0.0)
- return __kernel_standard(x,x,16,&err); /* log(0) */
- else
- return __kernel_standard(x,x,17,&err); /* log(x<0) */
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_log10.c b/src/extension/script/js/fdlibm/w_log10.c
deleted file mode 100644
index 6b298b236..000000000
--- a/src/extension/script/js/fdlibm/w_log10.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_log10.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper log10(X)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_log10(double x) /* wrapper log10 */
-#else
- double fd_log10(x) /* wrapper log10 */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_log10(x);
-#else
- double z;
- z = __ieee754_log10(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(x<=0.0) {
- int err;
- if(x==0.0)
- return __kernel_standard(x,x,18,&err); /* log10(0) */
- else
- return __kernel_standard(x,x,19,&err); /* log10(x<0) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_pow.c b/src/extension/script/js/fdlibm/w_pow.c
deleted file mode 100644
index 3d2c15ad3..000000000
--- a/src/extension/script/js/fdlibm/w_pow.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-/* @(#)w_pow.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper pow(x,y) return x**y
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
- double fd_pow(double x, double y) /* wrapper pow */
-#else
- double fd_pow(x,y) /* wrapper pow */
- double x,y;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_pow(x,y);
-#else
- double z;
- int err;
- z=__ieee754_pow(x,y);
- if(_LIB_VERSION == _IEEE_|| fd_isnan(y)) return z;
- if(fd_isnan(x)) {
- if(y==0.0)
- return __kernel_standard(x,y,42,&err); /* pow(NaN,0.0) */
- else
- return z;
- }
- if(x==0.0){
- if(y==0.0)
- return __kernel_standard(x,y,20,&err); /* pow(0.0,0.0) */
- if(fd_finite(y)&&y<0.0)
- return __kernel_standard(x,y,23,&err); /* pow(0.0,negative) */
- return z;
- }
- if(!fd_finite(z)) {
- if(fd_finite(x)&&fd_finite(y)) {
- if(fd_isnan(z))
- return __kernel_standard(x,y,24,&err); /* pow neg**non-int */
- else
- return __kernel_standard(x,y,21,&err); /* pow overflow */
- }
- }
- if(z==0.0&&fd_finite(x)&&fd_finite(y))
- return __kernel_standard(x,y,22,&err); /* pow underflow */
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_remainder.c b/src/extension/script/js/fdlibm/w_remainder.c
deleted file mode 100644
index 25d1ba171..000000000
--- a/src/extension/script/js/fdlibm/w_remainder.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_remainder.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper remainder(x,p)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_remainder(double x, double y) /* wrapper remainder */
-#else
- double fd_remainder(x,y) /* wrapper remainder */
- double x,y;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_remainder(x,y);
-#else
- double z;
- z = __ieee754_remainder(x,y);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(y)) return z;
- if(y==0.0) {
- int err;
- return __kernel_standard(x,y,28,&err); /* remainder(x,0) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_scalb.c b/src/extension/script/js/fdlibm/w_scalb.c
deleted file mode 100644
index 35c16a500..000000000
--- a/src/extension/script/js/fdlibm/w_scalb.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_scalb.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper scalb(double x, double fn) is provide for
- * passing various standard test suite. One
- * should use scalbn() instead.
- */
-
-#include "fdlibm.h"
-
-#include <errno.h>
-
-#ifdef __STDC__
-#ifdef _SCALB_INT
- double fd_scalb(double x, int fn) /* wrapper scalb */
-#else
- double fd_scalb(double x, double fn) /* wrapper scalb */
-#endif
-#else
- double fd_scalb(x,fn) /* wrapper scalb */
-#ifdef _SCALB_INT
- double x; int fn;
-#else
- double x,fn;
-#endif
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_scalb(x,fn);
-#else
- double z;
- int err;
- z = __ieee754_scalb(x,fn);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!(fd_finite(z)||fd_isnan(z))&&fd_finite(x)) {
- return __kernel_standard(x,(double)fn,32,&err); /* scalb overflow */
- }
- if(z==0.0&&z!=x) {
- return __kernel_standard(x,(double)fn,33,&err); /* scalb underflow */
- }
-#ifndef _SCALB_INT
- if(!fd_finite(fn)) errno = ERANGE;
-#endif
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_sinh.c b/src/extension/script/js/fdlibm/w_sinh.c
deleted file mode 100644
index 8b04ecb7f..000000000
--- a/src/extension/script/js/fdlibm/w_sinh.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_sinh.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper sinh(x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_sinh(double x) /* wrapper sinh */
-#else
- double fd_sinh(x) /* wrapper sinh */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sinh(x);
-#else
- double z;
- z = __ieee754_sinh(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!fd_finite(z)&&fd_finite(x)) {
- int err;
- return __kernel_standard(x,x,25,&err); /* sinh overflow */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/fdlibm/w_sqrt.c b/src/extension/script/js/fdlibm/w_sqrt.c
deleted file mode 100644
index 462d776f8..000000000
--- a/src/extension/script/js/fdlibm/w_sqrt.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* @(#)w_sqrt.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper sqrt(x)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
- double fd_sqrt(double x) /* wrapper sqrt */
-#else
- double fd_sqrt(x) /* wrapper sqrt */
- double x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sqrt(x);
-#else
- double z;
- z = __ieee754_sqrt(x);
- if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
- if(x<0.0) {
- int err;
- return __kernel_standard(x,x,26,&err); /* sqrt(negative) */
- } else
- return z;
-#endif
-}
diff --git a/src/extension/script/js/js.c b/src/extension/script/js/js.c
deleted file mode 100644
index 5bd296223..000000000
--- a/src/extension/script/js/js.c
+++ /dev/null
@@ -1,2333 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS shell.
- */
-#include "jsstddef.h"
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h"
-#include "jsutil.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsdbgapi.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jslock.h"
-#include "jsobj.h"
-#include "jsparse.h"
-#include "jsscope.h"
-#include "jsscript.h"
-
-#ifdef PERLCONNECT
-#include "perlconnect/jsperl.h"
-#endif
-
-#ifdef LIVECONNECT
-#include "jsjava.h"
-#endif
-
-#ifdef JSDEBUGGER
-#include "jsdebug.h"
-#ifdef JSDEBUGGER_JAVA_UI
-#include "jsdjava.h"
-#endif /* JSDEBUGGER_JAVA_UI */
-#ifdef JSDEBUGGER_C_UI
-#include "jsdb.h"
-#endif /* JSDEBUGGER_C_UI */
-#endif /* JSDEBUGGER */
-
-#ifdef XP_UNIX
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#endif
-
-#if defined(XP_WIN) || defined(XP_OS2)
-#include <io.h> /* for isatty() */
-#endif
-
-#define EXITCODE_RUNTIME_ERROR 3
-#define EXITCODE_FILE_NOT_FOUND 4
-
-size_t gStackChunkSize = 8192;
-static size_t gMaxStackSize = 0;
-static jsuword gStackBase;
-int gExitCode = 0;
-JSBool gQuitting = JS_FALSE;
-FILE *gErrFile = NULL;
-FILE *gOutFile = NULL;
-
-#ifdef XP_MAC
-#if defined(MAC_TEST_HACK) || defined(XP_MAC_MPW)
-/* this is the data file that all Print strings will be echoed into */
-FILE *gTestResultFile = NULL;
-#define isatty(f) 0
-#else
-#define isatty(f) 1
-#endif
-
-char *strdup(const char *str)
-{
- char *copy = (char *) malloc(strlen(str)+1);
- if (copy)
- strcpy(copy, str);
- return copy;
-}
-
-#ifdef XP_MAC_MPW
-/* Macintosh MPW replacements for the ANSI routines. These translate LF's to CR's because
- the MPW libraries supplied by Metrowerks don't do that for some reason. */
-static void translateLFtoCR(char *str, int length)
-{
- char *limit = str + length;
- while (str != limit) {
- if (*str == '\n')
- *str = '\r';
- str++;
- }
-}
-
-int fputc(int c, FILE *file)
-{
- char buffer = c;
- if (buffer == '\n')
- buffer = '\r';
- return fwrite(&buffer, 1, 1, file);
-}
-
-int fputs(const char *s, FILE *file)
-{
- char buffer[4096];
- int n = strlen(s);
- int extra = 0;
-
- while (n > sizeof buffer) {
- memcpy(buffer, s, sizeof buffer);
- translateLFtoCR(buffer, sizeof buffer);
- extra += fwrite(buffer, 1, sizeof buffer, file);
- n -= sizeof buffer;
- s += sizeof buffer;
- }
- memcpy(buffer, s, n);
- translateLFtoCR(buffer, n);
- return extra + fwrite(buffer, 1, n, file);
-}
-
-int fprintf(FILE* file, const char *format, ...)
-{
- va_list args;
- char smallBuffer[4096];
- int n;
- int bufferSize = sizeof smallBuffer;
- char *buffer = smallBuffer;
- int result;
-
- va_start(args, format);
- n = vsnprintf(buffer, bufferSize, format, args);
- va_end(args);
- while (n < 0) {
- if (buffer != smallBuffer)
- free(buffer);
- bufferSize <<= 1;
- buffer = malloc(bufferSize);
- if (!buffer) {
- JS_ASSERT(JS_FALSE);
- return 0;
- }
- va_start(args, format);
- n = vsnprintf(buffer, bufferSize, format, args);
- va_end(args);
- }
- translateLFtoCR(buffer, n);
- result = fwrite(buffer, 1, n, file);
- if (buffer != smallBuffer)
- free(buffer);
- return result;
-}
-
-
-#else
-#include <SIOUX.h>
-#include <MacTypes.h>
-
-static char* mac_argv[] = { "js", NULL };
-
-static void initConsole(StringPtr consoleName, const char* startupMessage, int *argc, char** *argv)
-{
- SIOUXSettings.autocloseonquit = true;
- SIOUXSettings.asktosaveonclose = false;
- /* SIOUXSettings.initializeTB = false;
- SIOUXSettings.showstatusline = true;*/
- puts(startupMessage);
- SIOUXSetTitle(consoleName);
-
- /* set up a buffer for stderr (otherwise it's a pig). */
- setvbuf(stderr, (char *) malloc(BUFSIZ), _IOLBF, BUFSIZ);
-
- *argc = 1;
- *argv = mac_argv;
-}
-
-#ifdef LIVECONNECT
-/* Little hack to provide a default CLASSPATH on the Mac. */
-#define getenv(var) mac_getenv(var)
-static char* mac_getenv(const char* var)
-{
- if (strcmp(var, "CLASSPATH") == 0) {
- static char class_path[] = "liveconnect.jar";
- return class_path;
- }
- return NULL;
-}
-#endif /* LIVECONNECT */
-
-#endif
-#endif
-
-#ifdef JSDEBUGGER
-static JSDContext *_jsdc;
-#ifdef JSDEBUGGER_JAVA_UI
-static JSDJContext *_jsdjc;
-#endif /* JSDEBUGGER_JAVA_UI */
-#endif /* JSDEBUGGER */
-
-static JSBool reportWarnings = JS_TRUE;
-
-typedef enum JSShellErrNum {
-#define MSG_DEF(name, number, count, exception, format) \
- name = number,
-#include "jsshell.msg"
-#undef MSG_DEF
- JSShellErr_Limit
-#undef MSGDEF
-} JSShellErrNum;
-
-static const JSErrorFormatString *
-my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
-
-#ifdef EDITLINE
-extern char *readline(const char *prompt);
-extern void add_history(char *line);
-#endif
-
-static JSBool
-GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
-#ifdef EDITLINE
- /*
- * Use readline only if file is stdin, because there's no way to specify
- * another handle. Are other filehandles interactive?
- */
- if (file == stdin) {
- char *linep = readline(prompt);
- if (!linep)
- return JS_FALSE;
- if (linep[0] != '\0')
- add_history(linep);
- strcpy(bufp, linep);
- JS_free(cx, linep);
- bufp += strlen(bufp);
- *bufp++ = '\n';
- *bufp = '\0';
- } else
-#endif
- {
- char line[256];
- fprintf(gOutFile, prompt);
- fflush(gOutFile);
-#ifdef XP_MAC_MPW
- /* Print a CR after the prompt because MPW grabs the entire line when entering an interactive command */
- fputc('\n', gOutFile);
-#endif
- if (!fgets(line, sizeof line, file))
- return JS_FALSE;
- strcpy(bufp, line);
- }
- return JS_TRUE;
-}
-
-static void
-Process(JSContext *cx, JSObject *obj, char *filename)
-{
- JSBool ok, hitEOF;
- JSScript *script;
- jsval result;
- JSString *str;
- char buffer[4096];
- char *bufp;
- int lineno;
- int startline;
- FILE *file;
- jsuword stackLimit;
-
- if (!filename || strcmp(filename, "-") == 0) {
- file = stdin;
- } else {
- file = fopen(filename, "r");
- if (!file) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
- JSSMSG_CANT_OPEN, filename, strerror(errno));
- gExitCode = EXITCODE_FILE_NOT_FOUND;
- return;
- }
- }
-
- if (gMaxStackSize == 0) {
- /*
- * Disable checking for stack overflow if limit is zero.
- */
- stackLimit = 0;
- } else {
-#if JS_STACK_GROWTH_DIRECTION > 0
- stackLimit = gStackBase + gMaxStackSize;
-#else
- stackLimit = gStackBase - gMaxStackSize;
-#endif
- }
- JS_SetThreadStackLimit(cx, stackLimit);
-
- if (!isatty(fileno(file))) {
- /*
- * It's not interactive - just execute it.
- *
- * Support the UNIX #! shell hack; gobble the first line if it starts
- * with '#'. TODO - this isn't quite compatible with sharp variables,
- * as a legal js program (using sharp variables) might start with '#'.
- * But that would require multi-character lookahead.
- */
- int ch = fgetc(file);
- if (ch == '#') {
- while((ch = fgetc(file)) != EOF) {
- if (ch == '\n' || ch == '\r')
- break;
- }
- }
- ungetc(ch, file);
- script = JS_CompileFileHandle(cx, obj, filename, file);
- if (script) {
- (void)JS_ExecuteScript(cx, obj, script, &result);
- JS_DestroyScript(cx, script);
- }
- return;
- }
-
- /* It's an interactive filehandle; drop into read-eval-print loop. */
- lineno = 1;
- hitEOF = JS_FALSE;
- do {
- bufp = buffer;
- *bufp = '\0';
-
- /*
- * Accumulate lines until we get a 'compilable unit' - one that either
- * generates an error (before running out of source) or that compiles
- * cleanly. This should be whenever we get a complete statement that
- * coincides with the end of a line.
- */
- startline = lineno;
- do {
- if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) {
- hitEOF = JS_TRUE;
- break;
- }
- bufp += strlen(bufp);
- lineno++;
- } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
-
- /* Clear any pending exception from previous failed compiles. */
- JS_ClearPendingException(cx);
- script = JS_CompileScript(cx, obj, buffer, strlen(buffer),
-#ifdef JSDEBUGGER
- "typein",
-#else
- NULL,
-#endif
- startline);
- if (script) {
- ok = JS_ExecuteScript(cx, obj, script, &result);
- if (ok && result != JSVAL_VOID) {
- str = JS_ValueToString(cx, result);
- if (str)
- fprintf(gOutFile, "%s\n", JS_GetStringBytes(str));
- else
- ok = JS_FALSE;
- }
- JS_DestroyScript(cx, script);
- }
- } while (!hitEOF && !gQuitting);
- fprintf(gOutFile, "\n");
- return;
-}
-
-static int
-usage(void)
-{
- fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
- fprintf(gErrFile, "usage: js [-PswW] [-b branchlimit] [-c stackchunksize] [-v version] [-f scriptfile] [-S maxstacksize] [scriptfile] [scriptarg...]\n");
- return 2;
-}
-
-static uint32 gBranchCount;
-static uint32 gBranchLimit;
-
-static JSBool
-my_BranchCallback(JSContext *cx, JSScript *script)
-{
- if (++gBranchCount == gBranchLimit) {
- if (script->filename)
- fprintf(gErrFile, "%s:", script->filename);
- fprintf(gErrFile, "%u: script branches too much (%u callbacks)\n",
- script->lineno, gBranchLimit);
- gBranchCount = 0;
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-extern JSClass global_class;
-
-static int
-ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
-{
- int i, j, length;
- JSObject *argsObj;
- char *filename = NULL;
- JSBool isInteractive = JS_TRUE;
-
- /*
- * Scan past all optional arguments so we can create the arguments object
- * before processing any -f options, which must interleave properly with
- * -v and -w options. This requires two passes, and without getopt, we'll
- * have to keep the option logic here and in the second for loop in sync.
- */
- for (i = 0; i < argc; i++) {
- if (argv[i][0] != '-' || argv[i][1] == '\0') {
- ++i;
- break;
- }
- switch (argv[i][1]) {
- case 'b':
- case 'c':
- case 'f':
- case 'v':
- case 'S':
- ++i;
- break;
- }
- }
-
- /*
- * Create arguments early and define it to root it, so it's safe from any
- * GC calls nested below, and so it is available to -f <file> arguments.
- */
- argsObj = JS_NewArrayObject(cx, 0, NULL);
- if (!argsObj)
- return 1;
- if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj),
- NULL, NULL, 0)) {
- return 1;
- }
-
- length = argc - i;
- for (j = 0; j < length; j++) {
- JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
- if (!str)
- return 1;
- if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return 1;
- }
- }
-
- for (i = 0; i < argc; i++) {
- if (argv[i][0] != '-' || argv[i][1] == '\0') {
- filename = argv[i++];
- isInteractive = JS_FALSE;
- break;
- }
-
- switch (argv[i][1]) {
- case 'v':
- if (++i == argc) {
- return usage();
- }
- JS_SetVersion(cx, (JSVersion) atoi(argv[i]));
- break;
-
- case 'w':
- reportWarnings = JS_TRUE;
- break;
-
- case 'W':
- reportWarnings = JS_FALSE;
- break;
-
- case 's':
- JS_ToggleOptions(cx, JSOPTION_STRICT);
- break;
-
- case 'P':
- if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
- JSObject *gobj;
-
- if (!JS_SealObject(cx, obj, JS_TRUE))
- return JS_FALSE;
- gobj = JS_NewObject(cx, &global_class, NULL, NULL);
- if (!gobj)
- return JS_FALSE;
- if (!JS_SetPrototype(cx, gobj, obj))
- return JS_FALSE;
- JS_SetParent(cx, gobj, NULL);
- JS_SetGlobalObject(cx, gobj);
- obj = gobj;
- }
- break;
-
- case 'b':
- gBranchLimit = atoi(argv[++i]);
- JS_SetBranchCallback(cx, my_BranchCallback);
- break;
-
- case 'c':
- /* set stack chunk size */
- gStackChunkSize = atoi(argv[++i]);
- break;
-
- case 'f':
- if (++i == argc) {
- return usage();
- }
- Process(cx, obj, argv[i]);
- /*
- * XXX: js -f foo.js should interpret foo.js and then
- * drop into interactive mode, but that breaks test
- * harness. Just execute foo.js for now.
- */
- isInteractive = JS_FALSE;
- break;
-
- case 'S':
- if (++i == argc) {
- return usage();
- }
- /* Set maximum stack size. */
- gMaxStackSize = atoi(argv[i]);
- break;
-
- default:
- return usage();
- }
- }
-
- if (filename || isInteractive)
- Process(cx, obj, filename);
- return gExitCode;
-}
-
-
-static JSBool
-Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (argc > 0 && JSVAL_IS_INT(argv[0]))
- *rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0])));
- else
- *rval = INT_TO_JSVAL(JS_GetVersion(cx));
- return JS_TRUE;
-}
-
-static struct {
- const char *name;
- uint32 flag;
-} js_options[] = {
- {"strict", JSOPTION_STRICT},
- {"werror", JSOPTION_WERROR},
- {0, 0}
-};
-
-static JSBool
-Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uint32 optset, flag;
- uintN i, j, found;
- JSString *str;
- const char *opt;
- char *names;
-
- optset = 0;
- for (i = 0; i < argc; i++) {
- str = JS_ValueToString(cx, argv[i]);
- if (!str)
- return JS_FALSE;
- opt = JS_GetStringBytes(str);
- for (j = 0; js_options[j].name; j++) {
- if (strcmp(js_options[j].name, opt) == 0) {
- optset |= js_options[j].flag;
- break;
- }
- }
- }
- optset = JS_ToggleOptions(cx, optset);
-
- names = NULL;
- found = 0;
- while (optset != 0) {
- flag = optset;
- optset &= optset - 1;
- flag &= ~optset;
- for (j = 0; js_options[j].name; j++) {
- if (js_options[j].flag == flag) {
- names = JS_sprintf_append(names, "%s%s",
- names ? "," : "", js_options[j].name);
- found++;
- break;
- }
- }
- }
- if (!found)
- names = strdup("");
- if (!names) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- str = JS_NewString(cx, names, strlen(names));
- if (!str) {
- free(names);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static void
-my_LoadErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
-
-static void
-my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
-
-static JSBool
-Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i;
- JSString *str;
- const char *filename;
- JSScript *script;
- JSBool ok;
- jsval result;
- JSErrorReporter older;
-
- for (i = 0; i < argc; i++) {
- str = JS_ValueToString(cx, argv[i]);
- if (!str)
- return JS_FALSE;
- argv[i] = STRING_TO_JSVAL(str);
- filename = JS_GetStringBytes(str);
- errno = 0;
- older = JS_SetErrorReporter(cx, my_LoadErrorReporter);
- script = JS_CompileFile(cx, obj, filename);
- if (!script)
- ok = JS_FALSE;
- else {
- ok = JS_ExecuteScript(cx, obj, script, &result);
- JS_DestroyScript(cx, script);
- }
- JS_SetErrorReporter(cx, older);
- if (!ok)
- return JS_FALSE;
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i, n;
- JSString *str;
-
- for (i = n = 0; i < argc; i++) {
- str = JS_ValueToString(cx, argv[i]);
- if (!str)
- return JS_FALSE;
- fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str));
- }
- n++;
- if (n)
- fputc('\n', gOutFile);
- return JS_TRUE;
-}
-
-static JSBool
-Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
-
-static JSBool
-Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-#ifdef LIVECONNECT
- JSJ_SimpleShutdown();
-#endif
-
- JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode);
-
- gQuitting = JS_TRUE;
- return JS_FALSE;
-}
-
-#ifdef GC_MARK_DEBUG
-extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
-#endif
-
-static JSBool
-GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSRuntime *rt;
- uint32 preBytes;
-
- rt = cx->runtime;
- preBytes = rt->gcBytes;
-#ifdef GC_MARK_DEBUG
- if (argc && JSVAL_IS_STRING(argv[0])) {
- char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
- FILE *file = fopen(name, "w");
- if (!file) {
- fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno));
- return JS_FALSE;
- }
- js_DumpGCHeap = file;
- } else {
- js_DumpGCHeap = stdout;
- }
-#endif
- JS_GC(cx);
-#ifdef GC_MARK_DEBUG
- if (js_DumpGCHeap != stdout)
- fclose(js_DumpGCHeap);
- js_DumpGCHeap = NULL;
-#endif
- fprintf(gOutFile, "before %lu, after %lu, break %08lx\n",
- (unsigned long)preBytes, (unsigned long)rt->gcBytes,
-#ifdef XP_UNIX
- (unsigned long)sbrk(0)
-#else
- 0
-#endif
- );
-#ifdef JS_GCMETER
- js_DumpGCStats(rt, stdout);
-#endif
- return JS_TRUE;
-}
-
-static JSScript *
-ValueToScript(JSContext *cx, jsval v)
-{
- JSScript *script;
- JSFunction *fun;
-
- if (JSVAL_IS_OBJECT(v) &&
- JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass) {
- script = (JSScript *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
- } else {
- fun = JS_ValueToFunction(cx, v);
- if (!fun)
- return NULL;
- script = fun->script;
- }
- return script;
-}
-
-static JSBool
-GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
- int32 *ip)
-{
- uintN intarg;
- JSScript *script;
-
- *scriptp = cx->fp->down->script;
- *ip = 0;
- if (argc != 0) {
- intarg = 0;
- if (JS_TypeOfValue(cx, argv[0]) == JSTYPE_FUNCTION) {
- script = ValueToScript(cx, argv[0]);
- if (!script)
- return JS_FALSE;
- *scriptp = script;
- intarg++;
- }
- if (argc > intarg) {
- if (!JS_ValueToInt32(cx, argv[intarg], ip))
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-static JSTrapStatus
-TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
- void *closure)
-{
- JSString *str;
- JSStackFrame *caller;
-
- str = (JSString *) closure;
- caller = JS_GetScriptedCaller(cx, NULL);
- if (!JS_EvaluateScript(cx, caller->scopeChain,
- JS_GetStringBytes(str), JS_GetStringLength(str),
- caller->script->filename, caller->script->lineno,
- rval)) {
- return JSTRAP_ERROR;
- }
- if (*rval != JSVAL_VOID)
- return JSTRAP_RETURN;
- return JSTRAP_CONTINUE;
-}
-
-static JSBool
-Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- JSScript *script;
- int32 i;
-
- if (argc == 0) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE);
- return JS_FALSE;
- }
- argc--;
- str = JS_ValueToString(cx, argv[argc]);
- if (!str)
- return JS_FALSE;
- argv[argc] = STRING_TO_JSVAL(str);
- if (!GetTrapArgs(cx, argc, argv, &script, &i))
- return JS_FALSE;
- return JS_SetTrap(cx, script, script->code + i, TrapHandler, str);
-}
-
-static JSBool
-Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSScript *script;
- int32 i;
-
- if (!GetTrapArgs(cx, argc, argv, &script, &i))
- return JS_FALSE;
- JS_ClearTrap(cx, script, script->code + i, NULL, NULL);
- return JS_TRUE;
-}
-
-static JSBool
-LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSScript *script;
- int32 i;
- uintN lineno;
- jsbytecode *pc;
-
- if (argc == 0) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE);
- return JS_FALSE;
- }
- script = cx->fp->down->script;
- if (!GetTrapArgs(cx, argc, argv, &script, &i))
- return JS_FALSE;
- lineno = (i == 0) ? script->lineno : (uintN)i;
- pc = JS_LineNumberToPC(cx, script, lineno);
- if (!pc)
- return JS_FALSE;
- *rval = INT_TO_JSVAL(PTRDIFF(pc, script->code, jsbytecode));
- return JS_TRUE;
-}
-
-static JSBool
-PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSScript *script;
- int32 i;
- uintN lineno;
-
- if (!GetTrapArgs(cx, argc, argv, &script, &i))
- return JS_FALSE;
- lineno = JS_PCToLineNumber(cx, script, script->code + i);
- if (!lineno)
- return JS_FALSE;
- *rval = INT_TO_JSVAL(lineno);
- return JS_TRUE;
-}
-
-#ifdef DEBUG
-
-static void
-SrcNotes(JSContext *cx, JSScript *script)
-{
- uintN offset, delta, caseOff;
- jssrcnote *notes, *sn;
- JSSrcNoteType type;
- jsatomid atomIndex;
- JSAtom *atom;
-
- fprintf(gOutFile, "\nSource notes:\n");
- offset = 0;
- notes = SCRIPT_NOTES(script);
- for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
- delta = SN_DELTA(sn);
- offset += delta;
- fprintf(gOutFile, "%3u: %5u [%4u] %-8s",
- PTRDIFF(sn, notes, jssrcnote), offset, delta,
- js_SrcNoteSpec[SN_TYPE(sn)].name);
- type = (JSSrcNoteType) SN_TYPE(sn);
- switch (type) {
- case SRC_SETLINE:
- fprintf(gOutFile, " lineno %u", (uintN) js_GetSrcNoteOffset(sn, 0));
- break;
- case SRC_FOR:
- fprintf(gOutFile, " cond %u update %u tail %u",
- (uintN) js_GetSrcNoteOffset(sn, 0),
- (uintN) js_GetSrcNoteOffset(sn, 1),
- (uintN) js_GetSrcNoteOffset(sn, 2));
- break;
- case SRC_COND:
- case SRC_IF_ELSE:
- case SRC_WHILE:
- case SRC_PCBASE:
- case SRC_PCDELTA:
- fprintf(gOutFile, " offset %u", (uintN) js_GetSrcNoteOffset(sn, 0));
- break;
- case SRC_LABEL:
- case SRC_LABELBRACE:
- case SRC_BREAK2LABEL:
- case SRC_CONT2LABEL:
- case SRC_FUNCDEF: {
- const char *bytes;
- JSFunction *fun;
- JSString *str;
-
- atomIndex = (jsatomid) js_GetSrcNoteOffset(sn, 0);
- atom = js_GetAtom(cx, &script->atomMap, atomIndex);
- if (type != SRC_FUNCDEF) {
- bytes = js_AtomToPrintableString(cx, atom);
- } else {
- fun = (JSFunction *)
- JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
- str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
- bytes = str ? JS_GetStringBytes(str) : "N/A";
- }
- fprintf(gOutFile, " atom %u (%s)", (uintN)atomIndex, bytes);
- break;
- }
- case SRC_SWITCH:
- fprintf(gOutFile, " length %u", (uintN) js_GetSrcNoteOffset(sn, 0));
- caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
- if (caseOff)
- fprintf(gOutFile, " first case offset %u", caseOff);
- break;
- case SRC_CATCH:
- delta = (uintN) js_GetSrcNoteOffset(sn, 0);
- if (delta)
- fprintf(gOutFile, " guard size %u", delta);
- break;
- default:;
- }
- fputc('\n', gOutFile);
- }
-}
-
-static JSBool
-Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i;
- JSScript *script;
-
- for (i = 0; i < argc; i++) {
- script = ValueToScript(cx, argv[i]);
- if (!script)
- continue;
-
- SrcNotes(cx, script);
- }
- return JS_TRUE;
-}
-
-static JSBool
-TryNotes(JSContext *cx, JSScript *script)
-{
- JSTryNote *tn = script->trynotes;
-
- if (!tn)
- return JS_TRUE;
- fprintf(gOutFile, "\nException table:\nstart\tend\tcatch\n");
- while (tn->start && tn->catchStart) {
- fprintf(gOutFile, " %d\t%d\t%d\n",
- tn->start, tn->start + tn->length, tn->catchStart);
- tn++;
- }
- return JS_TRUE;
-}
-
-static JSBool
-Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSBool lines;
- uintN i;
- JSScript *script;
-
- if (argc > 0 &&
- JSVAL_IS_STRING(argv[0]) &&
- !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), "-l")) {
- lines = JS_TRUE;
- argv++, argc--;
- } else {
- lines = JS_FALSE;
- }
- for (i = 0; i < argc; i++) {
- script = ValueToScript(cx, argv[i]);
- if (!script)
- continue;
-
- if (JSVAL_IS_FUNCTION(cx, argv[i])) {
- JSFunction *fun = JS_ValueToFunction(cx, argv[i]);
- if (fun && (fun->flags & JSFUN_FLAGS_MASK)) {
- uint8 flags = fun->flags;
- fputs("flags:", stdout);
-
-#define SHOW_FLAG(flag) if (flags & JSFUN_##flag) fputs(" " #flag, stdout);
-
- SHOW_FLAG(LAMBDA);
- SHOW_FLAG(SETTER);
- SHOW_FLAG(GETTER);
- SHOW_FLAG(BOUND_METHOD);
- SHOW_FLAG(HEAVYWEIGHT);
-
-#undef SHOW_FLAG
- putchar('\n');
- }
- }
-
- js_Disassemble(cx, script, lines, stdout);
- SrcNotes(cx, script);
- TryNotes(cx, script);
- }
- return JS_TRUE;
-}
-
-static JSBool
-DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
-#define LINE_BUF_LEN 512
- uintN i, len, line1, line2, bupline;
- JSScript *script;
- FILE *file;
- char linebuf[LINE_BUF_LEN];
- jsbytecode *pc, *end;
- static char sep[] = ";-------------------------";
-
- for (i = 0; i < argc; i++) {
- script = ValueToScript(cx, argv[i]);
- if (!script)
- continue;
-
- if (!script || !script->filename) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
- JSSMSG_FILE_SCRIPTS_ONLY);
- return JS_FALSE;
- }
-
- file = fopen(script->filename, "r");
- if (!file) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
- JSSMSG_CANT_OPEN,
- script->filename, strerror(errno));
- return JS_FALSE;
- }
-
- pc = script->code;
- end = pc + script->length;
-
- /* burn the leading lines */
- line2 = JS_PCToLineNumber(cx, script, pc);
- for (line1 = 0; line1 < line2 - 1; line1++)
- fgets(linebuf, LINE_BUF_LEN, file);
-
- bupline = 0;
- while (pc < end) {
- line2 = JS_PCToLineNumber(cx, script, pc);
-
- if (line2 < line1) {
- if (bupline != line2) {
- bupline = line2;
- fprintf(gOutFile, "%s %3u: BACKUP\n", sep, line2);
- }
- } else {
- if (bupline && line1 == line2)
- fprintf(gOutFile, "%s %3u: RESTORE\n", sep, line2);
- bupline = 0;
- while (line1 < line2) {
- if (!fgets(linebuf, LINE_BUF_LEN, file)) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
- JSSMSG_UNEXPECTED_EOF,
- script->filename);
- goto bail;
- }
- line1++;
- fprintf(gOutFile, "%s %3u: %s", sep, line1, linebuf);
- }
- }
-
- len = js_Disassemble1(cx, script, pc,
- PTRDIFF(pc, script->code, jsbytecode),
- JS_TRUE, stdout);
- if (!len)
- return JS_FALSE;
- pc += len;
- }
-
- bail:
- fclose(file);
- }
- return JS_TRUE;
-#undef LINE_BUF_LEN
-}
-
-static JSBool
-Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSBool bval;
- JSString *str;
-
- if (argc == 0) {
- *rval = BOOLEAN_TO_JSVAL(cx->tracefp != 0);
- return JS_TRUE;
- }
-
- switch (JS_TypeOfValue(cx, argv[0])) {
- case JSTYPE_NUMBER:
- bval = JSVAL_IS_INT(argv[0])
- ? JSVAL_TO_INT(argv[0])
- : (jsint) *JSVAL_TO_DOUBLE(argv[0]);
- break;
- case JSTYPE_BOOLEAN:
- bval = JSVAL_TO_BOOLEAN(argv[0]);
- break;
- default:
- str = JS_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- fprintf(gErrFile, "tracing: illegal argument %s\n",
- JS_GetStringBytes(str));
- return JS_TRUE;
- }
- cx->tracefp = bval ? stderr : NULL;
- return JS_TRUE;
-}
-
-typedef struct DumpAtomArgs {
- JSContext *cx;
- FILE *fp;
-} DumpAtomArgs;
-
-static int
-DumpAtom(JSHashEntry *he, int i, void *arg)
-{
- DumpAtomArgs *args = (DumpAtomArgs *)arg;
- FILE *fp = args->fp;
- JSAtom *atom = (JSAtom *)he;
-
- fprintf(fp, "%3d %08x %5lu ",
- i, (uintN)he->keyHash, (unsigned long)atom->number);
- if (ATOM_IS_STRING(atom))
- fprintf(fp, "\"%s\"\n", js_AtomToPrintableString(args->cx, atom));
- else if (ATOM_IS_INT(atom))
- fprintf(fp, "%ld\n", (long)ATOM_TO_INT(atom));
- else
- fprintf(fp, "%.16g\n", *ATOM_TO_DOUBLE(atom));
- return HT_ENUMERATE_NEXT;
-}
-
-static void
-DumpScope(JSContext *cx, JSObject *obj, FILE *fp)
-{
- uintN i;
- JSScope *scope;
- JSScopeProperty *sprop;
-
- i = 0;
- scope = OBJ_SCOPE(obj);
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
- continue;
- fprintf(fp, "%3u %p", i, sprop);
- if (JSVAL_IS_INT(sprop->id)) {
- fprintf(fp, " [%ld]", (long)JSVAL_TO_INT(sprop->id));
- } else {
- fprintf(fp, " \"%s\"",
- js_AtomToPrintableString(cx, (JSAtom *)sprop->id));
- }
-
-#define DUMP_ATTR(name) if (sprop->attrs & JSPROP_##name) fputs(" " #name, fp)
- DUMP_ATTR(ENUMERATE);
- DUMP_ATTR(READONLY);
- DUMP_ATTR(PERMANENT);
- DUMP_ATTR(EXPORTED);
- DUMP_ATTR(GETTER);
- DUMP_ATTR(SETTER);
-#undef DUMP_ATTR
-
- fprintf(fp, " slot %lu flags %x shortid %d\n",
- sprop->slot, sprop->flags, sprop->shortid);
- }
-}
-
-static JSBool
-DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i;
- JSString *str;
- const char *bytes;
- JSAtom *atom;
- JSObject *obj2;
- JSProperty *prop;
- jsval value;
-
- for (i = 0; i < argc; i++) {
- str = JS_ValueToString(cx, argv[i]);
- if (!str)
- return JS_FALSE;
- bytes = JS_GetStringBytes(str);
- if (strcmp(bytes, "arena") == 0) {
-#ifdef JS_ARENAMETER
- JS_DumpArenaStats(stdout);
-#endif
- } else if (strcmp(bytes, "atom") == 0) {
- DumpAtomArgs args;
-
- fprintf(gOutFile, "\natom table contents:\n");
- args.cx = cx;
- args.fp = stdout;
- JS_HashTableEnumerateEntries(cx->runtime->atomState.table,
- DumpAtom,
- &args);
-#ifdef HASHMETER
- JS_HashTableDumpMeter(cx->runtime->atomState.table,
- DumpAtom,
- stdout);
-#endif
- } else if (strcmp(bytes, "global") == 0) {
- DumpScope(cx, cx->globalObject, stdout);
- } else {
- atom = js_Atomize(cx, bytes, JS_GetStringLength(str), 0);
- if (!atom)
- return JS_FALSE;
- if (!js_FindProperty(cx, (jsid)atom, &obj, &obj2, &prop))
- return JS_FALSE;
- if (prop) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (!OBJ_GET_PROPERTY(cx, obj, (jsid)atom, &value))
- return JS_FALSE;
- }
- if (!prop || !JSVAL_IS_OBJECT(value)) {
- fprintf(gErrFile, "js: invalid stats argument %s\n",
- bytes);
- continue;
- }
- obj = JSVAL_TO_OBJECT(value);
- if (obj)
- DumpScope(cx, obj, stdout);
- }
- }
- return JS_TRUE;
-}
-
-#endif /* DEBUG */
-
-#ifdef TEST_EXPORT
-static JSBool
-DoExport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSAtom *atom;
- JSObject *obj2;
- JSProperty *prop;
- JSBool ok;
- uintN attrs;
-
- if (argc != 2) {
- JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_DOEXP_USAGE);
- return JS_FALSE;
- }
- if (!JS_ValueToObject(cx, argv[0], &obj))
- return JS_FALSE;
- argv[0] = OBJECT_TO_JSVAL(obj);
- atom = js_ValueToStringAtom(cx, argv[1]);
- if (!atom)
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
- JSPROP_EXPORTED, NULL);
- } else {
- ok = OBJ_GET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs);
- if (ok) {
- attrs |= JSPROP_EXPORTED;
- ok = OBJ_SET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs);
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- }
- return ok;
-}
-#endif
-
-#ifdef TEST_CVTARGS
-#include <ctype.h>
-
-static const char *
-EscapeWideString(jschar *w)
-{
- static char enuf[80];
- static char hex[] = "0123456789abcdef";
- jschar u;
- unsigned char b, c;
- int i, j;
-
- if (!w)
- return "";
- for (i = j = 0; i < sizeof enuf - 1; i++, j++) {
- u = w[j];
- if (u == 0)
- break;
- b = (unsigned char)(u >> 8);
- c = (unsigned char)(u);
- if (b) {
- if (i >= sizeof enuf - 6)
- break;
- enuf[i++] = '\\';
- enuf[i++] = 'u';
- enuf[i++] = hex[b >> 4];
- enuf[i++] = hex[b & 15];
- enuf[i++] = hex[c >> 4];
- enuf[i] = hex[c & 15];
- } else if (!isprint(c)) {
- if (i >= sizeof enuf - 4)
- break;
- enuf[i++] = '\\';
- enuf[i++] = 'x';
- enuf[i++] = hex[c >> 4];
- enuf[i] = hex[c & 15];
- } else {
- enuf[i] = (char)c;
- }
- }
- enuf[i] = 0;
- return enuf;
-}
-
-#include <stdarg.h>
-
-static JSBool
-ZZ_formatter(JSContext *cx, const char *format, JSBool fromJS, jsval **vpp,
- va_list *app)
-{
- jsval *vp;
- va_list ap;
- jsdouble re, im;
-
- printf("entering ZZ_formatter");
- vp = *vpp;
- ap = *app;
- if (fromJS) {
- if (!JS_ValueToNumber(cx, vp[0], &re))
- return JS_FALSE;
- if (!JS_ValueToNumber(cx, vp[1], &im))
- return JS_FALSE;
- *va_arg(ap, jsdouble *) = re;
- *va_arg(ap, jsdouble *) = im;
- } else {
- re = va_arg(ap, jsdouble);
- im = va_arg(ap, jsdouble);
- if (!JS_NewNumberValue(cx, re, &vp[0]))
- return JS_FALSE;
- if (!JS_NewNumberValue(cx, im, &vp[1]))
- return JS_FALSE;
- }
- *vpp = vp + 2;
- *app = ap;
- printf("leaving ZZ_formatter");
- return JS_TRUE;
-}
-
-static JSBool
-ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSBool b = JS_FALSE;
- jschar c = 0;
- int32 i = 0, j = 0;
- uint32 u = 0;
- jsdouble d = 0, I = 0, re = 0, im = 0;
- char *s = NULL;
- JSString *str = NULL;
- jschar *w = NULL;
- JSObject *obj2 = NULL;
- JSFunction *fun = NULL;
- jsval v = JSVAL_VOID;
- JSBool ok;
-
- if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter))
- return JS_FALSE;;
- ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*",
- &b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2,
- &fun, &v, &re, &im);
- JS_RemoveArgumentFormatter(cx, "ZZ");
- if (!ok)
- return JS_FALSE;
- fprintf(gOutFile,
- "b %u, c %x (%c), i %ld, u %lu, j %ld\n",
- b, c, (char)c, i, u, j);
- fprintf(gOutFile,
- "d %g, I %g, s %s, S %s, W %s, obj %s, fun %s\n"
- "v %s, re %g, im %g\n",
- d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w),
- JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj2))),
- fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "",
- JS_GetStringBytes(JS_ValueToString(cx, v)), re, im);
- return JS_TRUE;
-}
-#endif
-
-static JSBool
-BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__);
- return JS_TRUE;
-}
-
-static JSBool
-Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (argc != 0 && !JS_ValueToObject(cx, argv[0], &obj))
- return JS_FALSE;
- JS_ClearScope(cx, obj);
- return JS_TRUE;
-}
-
-static JSBool
-Intern(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
-
- str = JS_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- if (!JS_InternUCStringN(cx, JS_GetStringChars(str),
- JS_GetStringLength(str))) {
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-static JSBool
-Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFunction *fun;
- JSObject *funobj, *parent, *clone;
-
- fun = JS_ValueToFunction(cx, argv[0]);
- if (!fun)
- return JS_FALSE;
- funobj = JS_GetFunctionObject(fun);
- if (argc > 1) {
- if (!JS_ValueToObject(cx, argv[1], &parent))
- return JS_FALSE;
- } else {
- parent = JS_GetParent(cx, funobj);
- }
- clone = JS_CloneFunctionObject(cx, funobj, parent);
- if (!clone)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(clone);
- return JS_TRUE;
-}
-
-static JSBool
-Seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSObject *target;
- JSBool deep = JS_FALSE;
-
- if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
- return JS_FALSE;
- if (!target)
- return JS_TRUE;
- return JS_SealObject(cx, target, deep);
-}
-
-static JSFunctionSpec shell_functions[] = {
- {"version", Version, 0},
- {"options", Options, 0},
- {"load", Load, 1},
- {"print", Print, 0},
- {"help", Help, 0},
- {"quit", Quit, 0},
- {"gc", GC, 0},
- {"trap", Trap, 3},
- {"untrap", Untrap, 2},
- {"line2pc", LineToPC, 0},
- {"pc2line", PCToLine, 0},
-#ifdef DEBUG
- {"dis", Disassemble, 1},
- {"dissrc", DisassWithSrc, 1},
- {"notes", Notes, 1},
- {"tracing", Tracing, 0},
- {"stats", DumpStats, 1},
-#endif
-#ifdef TEST_EXPORT
- {"xport", DoExport, 2},
-#endif
-#ifdef TEST_CVTARGS
- {"cvtargs", ConvertArgs, 0, 0, 12},
-#endif
- {"build", BuildDate, 0},
- {"clear", Clear, 0},
- {"intern", Intern, 1},
- {"clone", Clone, 1},
- {"seal", Seal, 1, 0, 1},
- {0}
-};
-
-/* NOTE: These must be kept in sync with the above. */
-
-static char *shell_help_messages[] = {
- "version([number]) Get or set JavaScript version number",
- "options([option ...]) Get or toggle JavaScript options",
- "load(['foo.js' ...]) Load files named by string arguments",
- "print([exp ...]) Evaluate and print expressions",
- "help([name ...]) Display usage and help messages",
- "quit() Quit the shell",
- "gc() Run the garbage collector",
- "trap([fun, [pc,]] exp) Trap bytecode execution",
- "untrap(fun[, pc]) Remove a trap",
- "line2pc([fun,] line) Map line number to PC",
- "pc2line(fun[, pc]) Map PC to line number",
-#ifdef DEBUG
- "dis([fun]) Disassemble functions into bytecodes",
- "dissrc([fun]) Disassemble functions with source lines",
- "notes([fun]) Show source notes for functions",
- "tracing([toggle]) Turn tracing on or off",
- "stats([string ...]) Dump 'arena', 'atom', 'global' stats",
-#endif
-#ifdef TEST_EXPORT
- "xport(obj, id) Export identified property from object",
-#endif
-#ifdef TEST_CVTARGS
- "cvtargs(b, c, ...) Test JS_ConvertArguments",
-#endif
- "build() Show build date and time",
- "clear([obj]) Clear properties of object",
- "intern(str) Internalize str in the atom table",
- "clone(fun[, scope]) Clone function object",
- "seal(obj[, deep]) Seal object, or object graph if deep",
- 0
-};
-
-static void
-ShowHelpHeader(void)
-{
- fprintf(gOutFile, "%-9s %-22s %s\n", "Command", "Usage", "Description");
- fprintf(gOutFile, "%-9s %-22s %s\n", "=======", "=====", "===========");
-}
-
-static void
-ShowHelpForCommand(uintN n)
-{
- fprintf(gOutFile, "%-9.9s %s\n", shell_functions[n].name, shell_help_messages[n]);
-}
-
-static JSBool
-Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i, j;
- int did_header, did_something;
- JSType type;
- JSFunction *fun;
- JSString *str;
- const char *bytes;
-
- fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());
- if (argc == 0) {
- ShowHelpHeader();
- for (i = 0; shell_functions[i].name; i++)
- ShowHelpForCommand(i);
- } else {
- did_header = 0;
- for (i = 0; i < argc; i++) {
- did_something = 0;
- type = JS_TypeOfValue(cx, argv[i]);
- if (type == JSTYPE_FUNCTION) {
- fun = JS_ValueToFunction(cx, argv[i]);
- str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
- } else if (type == JSTYPE_STRING) {
- str = JSVAL_TO_STRING(argv[i]);
- } else {
- str = NULL;
- }
- if (str) {
- bytes = JS_GetStringBytes(str);
- for (j = 0; shell_functions[j].name; j++) {
- if (!strcmp(bytes, shell_functions[j].name)) {
- if (!did_header) {
- did_header = 1;
- ShowHelpHeader();
- }
- did_something = 1;
- ShowHelpForCommand(j);
- break;
- }
- }
- }
- if (!did_something) {
- str = JS_ValueToString(cx, argv[i]);
- if (!str)
- return JS_FALSE;
- fprintf(gErrFile, "Sorry, no help for %s\n",
- JS_GetStringBytes(str));
- }
- }
- }
- return JS_TRUE;
-}
-
-/*
- * Define a JS object called "it". Give it class operations that printf why
- * they're being called for tutorial purposes.
- */
-enum its_tinyid {
- ITS_COLOR, ITS_HEIGHT, ITS_WIDTH, ITS_FUNNY, ITS_ARRAY, ITS_RDONLY
-};
-
-static JSPropertySpec its_props[] = {
- {"color", ITS_COLOR, JSPROP_ENUMERATE},
- {"height", ITS_HEIGHT, JSPROP_ENUMERATE},
- {"width", ITS_WIDTH, JSPROP_ENUMERATE},
- {"funny", ITS_FUNNY, JSPROP_ENUMERATE},
- {"array", ITS_ARRAY, JSPROP_ENUMERATE},
- {"rdonly", ITS_RDONLY, JSPROP_READONLY},
- {0}
-};
-
-static JSBool
-its_item(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- *rval = OBJECT_TO_JSVAL(obj);
- if (argc != 0)
- JS_SetCallReturnValue2(cx, argv[0]);
- return JS_TRUE;
-}
-
-static JSFunctionSpec its_methods[] = {
- {"item", its_item, 0},
- {0}
-};
-
-#ifdef JSD_LOWLEVEL_SOURCE
-/*
- * This facilitates sending source to JSD (the debugger system) in the shell
- * where the source is loaded using the JSFILE hack in jsscan. The function
- * below is used as a callback for the jsdbgapi JS_SetSourceHandler hook.
- * A more normal embedding (e.g. mozilla) loads source itself and can send
- * source directly to JSD without using this hook scheme.
- */
-static void
-SendSourceToJSDebugger(const char *filename, uintN lineno,
- jschar *str, size_t length,
- void **listenerTSData, JSDContext* jsdc)
-{
- JSDSourceText *jsdsrc = (JSDSourceText *) *listenerTSData;
-
- if (!jsdsrc) {
- if (!filename)
- filename = "typein";
- if (1 == lineno) {
- jsdsrc = JSD_NewSourceText(jsdc, filename);
- } else {
- jsdsrc = JSD_FindSourceForURL(jsdc, filename);
- if (jsdsrc && JSD_SOURCE_PARTIAL !=
- JSD_GetSourceStatus(jsdc, jsdsrc)) {
- jsdsrc = NULL;
- }
- }
- }
- if (jsdsrc) {
- jsdsrc = JSD_AppendUCSourceText(jsdc,jsdsrc, str, length,
- JSD_SOURCE_PARTIAL);
- }
- *listenerTSData = jsdsrc;
-}
-#endif /* JSD_LOWLEVEL_SOURCE */
-
-static JSBool its_noisy; /* whether to be noisy when finalizing it */
-
-static JSBool
-its_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- if (its_noisy) {
- fprintf(gOutFile, "adding its property %s,",
- JS_GetStringBytes(JS_ValueToString(cx, id)));
- fprintf(gOutFile, " initial value %s\n",
- JS_GetStringBytes(JS_ValueToString(cx, *vp)));
- }
- return JS_TRUE;
-}
-
-static JSBool
-its_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- if (its_noisy) {
- fprintf(gOutFile, "deleting its property %s,",
- JS_GetStringBytes(JS_ValueToString(cx, id)));
- fprintf(gOutFile, " current value %s\n",
- JS_GetStringBytes(JS_ValueToString(cx, *vp)));
- }
- return JS_TRUE;
-}
-
-static JSBool
-its_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- if (its_noisy) {
- fprintf(gOutFile, "getting its property %s,",
- JS_GetStringBytes(JS_ValueToString(cx, id)));
- fprintf(gOutFile, " current value %s\n",
- JS_GetStringBytes(JS_ValueToString(cx, *vp)));
- }
- return JS_TRUE;
-}
-
-static JSBool
-its_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- if (its_noisy) {
- fprintf(gOutFile, "setting its property %s,",
- JS_GetStringBytes(JS_ValueToString(cx, id)));
- fprintf(gOutFile, " new value %s\n",
- JS_GetStringBytes(JS_ValueToString(cx, *vp)));
- }
- if (JSVAL_IS_STRING(id) &&
- !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "noisy")) {
- return JS_ValueToBoolean(cx, *vp, &its_noisy);
- }
- return JS_TRUE;
-}
-
-static JSBool
-its_enumerate(JSContext *cx, JSObject *obj)
-{
- if (its_noisy)
- fprintf(gOutFile, "enumerate its properties\n");
- return JS_TRUE;
-}
-
-static JSBool
-its_resolve(JSContext *cx, JSObject *obj, jsval id)
-{
- if (its_noisy) {
- fprintf(gOutFile, "resolving its property %s\n",
- JS_GetStringBytes(JS_ValueToString(cx, id)));
- }
- return JS_TRUE;
-}
-
-static JSBool
-its_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
-{
- if (its_noisy)
- fprintf(gOutFile, "converting it to %s type\n", JS_GetTypeName(cx, type));
- return JS_TRUE;
-}
-
-static void
-its_finalize(JSContext *cx, JSObject *obj)
-{
- if (its_noisy)
- fprintf(gOutFile, "finalizing it\n");
-}
-
-static JSClass its_class = {
- "It", 0,
- its_addProperty, its_delProperty, its_getProperty, its_setProperty,
- its_enumerate, its_resolve, its_convert, its_finalize
-};
-
-JSErrorFormatString jsShell_ErrorFormatString[JSErr_Limit] = {
-#if JS_HAS_DFLT_MSG_STRINGS
-#define MSG_DEF(name, number, count, exception, format) \
- { format, count } ,
-#else
-#define MSG_DEF(name, number, count, exception, format) \
- { NULL, count } ,
-#endif
-#include "jsshell.msg"
-#undef MSG_DEF
-};
-
-static const JSErrorFormatString *
-my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
-{
- if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
- return &jsShell_ErrorFormatString[errorNumber];
- return NULL;
-}
-
-static void
-my_LoadErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
-{
- if (!report) {
- fprintf(gErrFile, "%s\n", message);
- return;
- }
-
- /* Ignore any exceptions */
- if (JSREPORT_IS_EXCEPTION(report->flags))
- return;
-
- /* Otherwise, fall back to the ordinary error reporter. */
- my_ErrorReporter(cx, message, report);
-}
-
-static void
-my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
-{
- int i, j, k, n;
- char *prefix, *tmp;
- const char *ctmp;
-
- if (!report) {
- fprintf(gErrFile, "%s\n", message);
- return;
- }
-
- /* Conditionally ignore reported warnings. */
- if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
- return;
-
- prefix = NULL;
- if (report->filename)
- prefix = JS_smprintf("%s:", report->filename);
- if (report->lineno) {
- tmp = prefix;
- prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
- JS_free(cx, tmp);
- }
- if (JSREPORT_IS_WARNING(report->flags)) {
- tmp = prefix;
- prefix = JS_smprintf("%s%swarning: ",
- tmp ? tmp : "",
- JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
- JS_free(cx, tmp);
- }
-
- /* embedded newlines -- argh! */
- while ((ctmp = strchr(message, '\n')) != 0) {
- ctmp++;
- if (prefix)
- fputs(prefix, gErrFile);
- fwrite(message, 1, ctmp - message, gErrFile);
- message = ctmp;
- }
-
- /* If there were no filename or lineno, the prefix might be empty */
- if (prefix)
- fputs(prefix, gErrFile);
- fputs(message, gErrFile);
-
- if (!report->linebuf) {
- fputc('\n', gErrFile);
- goto out;
- }
-
- /* report->linebuf usually ends with a newline. */
- n = strlen(report->linebuf);
- fprintf(gErrFile, ":\n%s%s%s%s",
- prefix,
- report->linebuf,
- (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n",
- prefix);
- n = PTRDIFF(report->tokenptr, report->linebuf, char);
- for (i = j = 0; i < n; i++) {
- if (report->linebuf[i] == '\t') {
- for (k = (j + 8) & ~7; j < k; j++) {
- fputc('.', gErrFile);
- }
- continue;
- }
- fputc('.', gErrFile);
- j++;
- }
- fputs("^\n", gErrFile);
- out:
- if (!JSREPORT_IS_WARNING(report->flags))
- gExitCode = EXITCODE_RUNTIME_ERROR;
- JS_free(cx, prefix);
-}
-
-#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
-static JSBool
-Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFunction *fun;
- const char *name, **nargv;
- uintN i, nargc;
- JSString *str;
- pid_t pid;
- int status;
-
- fun = JS_ValueToFunction(cx, argv[-2]);
- if (!fun)
- return JS_FALSE;
- if (!fun->atom)
- return JS_TRUE;
- name = JS_GetStringBytes(ATOM_TO_STRING(fun->atom));
- nargc = 1 + argc;
- nargv = JS_malloc(cx, (nargc + 1) * sizeof(char *));
- if (!nargv)
- return JS_FALSE;
- nargv[0] = name;
- for (i = 1; i < nargc; i++) {
- str = JS_ValueToString(cx, argv[i-1]);
- if (!str) {
- JS_free(cx, nargv);
- return JS_FALSE;
- }
- nargv[i] = JS_GetStringBytes(str);
- }
- nargv[nargc] = 0;
- pid = fork();
- switch (pid) {
- case -1:
- perror("js");
- break;
- case 0:
- (void) execvp(name, (char **)nargv);
- perror("js");
- exit(127);
- default:
- while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
- continue;
- break;
- }
- JS_free(cx, nargv);
- return JS_TRUE;
-}
-#endif
-
-#define LAZY_STANDARD_CLASSES
-
-static JSBool
-global_enumerate(JSContext *cx, JSObject *obj)
-{
-#ifdef LAZY_STANDARD_CLASSES
- return JS_EnumerateStandardClasses(cx, obj);
-#else
- return JS_TRUE;
-#endif
-}
-
-static JSBool
-global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
- JSObject **objp)
-{
-#ifdef LAZY_STANDARD_CLASSES
- if ((flags & JSRESOLVE_ASSIGNING) == 0) {
- JSBool resolved;
-
- if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
- return JS_FALSE;
- if (resolved) {
- *objp = obj;
- return JS_TRUE;
- }
- }
-#endif
-
-#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
- if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) {
- /*
- * Do this expensive hack only for unoptimized Unix builds, which are
- * not used for benchmarking.
- */
- char *path, *comp, *full;
- const char *name;
- JSBool ok, found;
- JSFunction *fun;
-
- if (!JSVAL_IS_STRING(id))
- return JS_TRUE;
- path = getenv("PATH");
- if (!path)
- return JS_TRUE;
- path = JS_strdup(cx, path);
- if (!path)
- return JS_FALSE;
- name = JS_GetStringBytes(JSVAL_TO_STRING(id));
- ok = JS_TRUE;
- for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) {
- if (*comp != '\0') {
- full = JS_smprintf("%s/%s", comp, name);
- if (!full) {
- JS_ReportOutOfMemory(cx);
- ok = JS_FALSE;
- break;
- }
- } else {
- full = (char *)name;
- }
- found = (access(full, X_OK) == 0);
- if (*comp != '\0')
- free(full);
- if (found) {
- fun = JS_DefineFunction(cx, obj, name, Exec, 0,
- JSPROP_ENUMERATE);
- ok = (fun != NULL);
- if (ok)
- *objp = obj;
- break;
- }
- }
- JS_free(cx, path);
- return ok;
- }
-#else
- return JS_TRUE;
-#endif
-}
-
-JSClass global_class = {
- "global", JSCLASS_NEW_RESOLVE,
- JS_PropertyStub, JS_PropertyStub,
- JS_PropertyStub, JS_PropertyStub,
- global_enumerate, (JSResolveOp) global_resolve,
- JS_ConvertStub, JS_FinalizeStub
-};
-
-static JSBool
-env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
-/* XXX porting may be easy, but these don't seem to supply setenv by default */
-#if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
- JSString *idstr, *valstr;
- const char *name, *value;
- int rv;
-
- idstr = JS_ValueToString(cx, id);
- valstr = JS_ValueToString(cx, *vp);
- if (!idstr || !valstr)
- return JS_FALSE;
- name = JS_GetStringBytes(idstr);
- value = JS_GetStringBytes(valstr);
-#if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX
- {
- char *waste = JS_smprintf("%s=%s", name, value);
- if (!waste) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- rv = putenv(waste);
-#ifdef XP_WIN
- /*
- * HPUX9 at least still has the bad old non-copying putenv.
- *
- * Per mail from <s.shanmuganathan@digital.com>, OSF1 also has a putenv
- * that will crash if you pass it an auto char array (so it must place
- * its argument directly in the char *environ[] array).
- */
- free(waste);
-#endif
- }
-#else
- rv = setenv(name, value, 1);
-#endif
- if (rv < 0) {
- JS_ReportError(cx, "can't set envariable %s to %s", name, value);
- return JS_FALSE;
- }
- *vp = STRING_TO_JSVAL(valstr);
-#endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */
- return JS_TRUE;
-}
-
-static JSBool
-env_enumerate(JSContext *cx, JSObject *obj)
-{
- static JSBool reflected;
- char **evp, *name, *value;
- JSString *valstr;
- JSBool ok;
-
- if (reflected)
- return JS_TRUE;
-
- for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
- value = strchr(name, '=');
- if (!value)
- continue;
- *value++ = '\0';
- valstr = JS_NewStringCopyZ(cx, value);
- if (!valstr) {
- ok = JS_FALSE;
- } else {
- ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
- NULL, NULL, JSPROP_ENUMERATE);
- }
- value[-1] = '=';
- if (!ok)
- return JS_FALSE;
- }
-
- reflected = JS_TRUE;
- return JS_TRUE;
-}
-
-static JSBool
-env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
- JSObject **objp)
-{
- JSString *idstr, *valstr;
- const char *name, *value;
-
- if (flags & JSRESOLVE_ASSIGNING)
- return JS_TRUE;
-
- idstr = JS_ValueToString(cx, id);
- if (!idstr)
- return JS_FALSE;
- name = JS_GetStringBytes(idstr);
- value = getenv(name);
- if (value) {
- valstr = JS_NewStringCopyZ(cx, value);
- if (!valstr)
- return JS_FALSE;
- if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return JS_FALSE;
- }
- *objp = obj;
- }
- return JS_TRUE;
-}
-
-static JSClass env_class = {
- "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
- JS_PropertyStub, JS_PropertyStub,
- JS_PropertyStub, env_setProperty,
- env_enumerate, (JSResolveOp) env_resolve,
- JS_ConvertStub, JS_FinalizeStub
-};
-
-int
-main(int argc, char **argv, char **envp)
-{
- int stackDummy;
- JSVersion version;
- JSRuntime *rt;
- JSContext *cx;
- JSObject *glob, *it, *envobj;
- int result;
-#ifdef LIVECONNECT
- JavaVM *java_vm = NULL;
-#endif
-#ifdef JSDEBUGGER_JAVA_UI
- JNIEnv *java_env;
-#endif
-
- gStackBase = (jsuword)&stackDummy;
-
-#ifdef XP_OS2
- /* these streams are normally line buffered on OS/2 and need a \n, *
- * so we need to unbuffer then to get a reasonable prompt */
- setbuf(stdout,0);
- setbuf(stderr,0);
-#endif
-
- gErrFile = stderr;
- gOutFile = stdout;
-
-#ifdef XP_MAC
-#ifndef XP_MAC_MPW
- initConsole("\pJavaScript Shell", "Welcome to js shell.", &argc, &argv);
-#endif
-#endif
-
-#ifdef MAC_TEST_HACK
-/*
- Open a file "testArgs.txt" and read each line into argc/argv.
- Re-direct all output to "results.txt"
-*/
- {
- char argText[256];
- FILE *f = fopen("testargs.txt", "r");
- if (f) {
- int maxArgs = 32; /* arbitrary max !!! */
- int argText_strlen;
- argc = 1;
- argv = malloc(sizeof(char *) * maxArgs);
- argv[0] = NULL;
- while (fgets(argText, 255, f)) {
- /* argText includes '\n' */
- argText_strlen = strlen(argText);
- argv[argc] = malloc(argText_strlen);
- strncpy(argv[argc], argText, argText_strlen - 1);
- argv[argc][argText_strlen - 1] = '\0';
- argc++;
- if (argc >= maxArgs)
- break;
- }
- fclose(f);
- }
- gTestResultFile = fopen("results.txt", "w");
- }
-
- gErrFile = gTestResultFile;
- gOutFile = gTestResultFile;
-#endif
-
- version = JSVERSION_DEFAULT;
-
- argc--;
- argv++;
-
- rt = JS_NewRuntime(8L * 1024L * 1024L);
- if (!rt)
- return 1;
-
- cx = JS_NewContext(rt, gStackChunkSize);
- if (!cx)
- return 1;
- JS_SetErrorReporter(cx, my_ErrorReporter);
-
- glob = JS_NewObject(cx, &global_class, NULL, NULL);
- if (!glob)
- return 1;
-#ifdef LAZY_STANDARD_CLASSES
- JS_SetGlobalObject(cx, glob);
-#else
- if (!JS_InitStandardClasses(cx, glob))
- return 1;
-#endif
- if (!JS_DefineFunctions(cx, glob, shell_functions))
- return 1;
-
- /* Set version only after there is a global object. */
- if (version != JSVERSION_DEFAULT)
- JS_SetVersion(cx, version);
-
- it = JS_DefineObject(cx, glob, "it", &its_class, NULL, 0);
- if (!it)
- return 1;
- if (!JS_DefineProperties(cx, it, its_props))
- return 1;
- if (!JS_DefineFunctions(cx, it, its_methods))
- return 1;
-
-#ifdef PERLCONNECT
- if (!JS_InitPerlClass(cx, glob))
- return 1;
-#endif
-
-#ifdef JSDEBUGGER
- /*
- * XXX A command line option to enable debugging (or not) would be good
- */
- _jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
- if (!_jsdc)
- return 1;
- JSD_JSContextInUse(_jsdc, cx);
-#ifdef JSD_LOWLEVEL_SOURCE
- JS_SetSourceHandler(rt, SendSourceToJSDebugger, _jsdc);
-#endif /* JSD_LOWLEVEL_SOURCE */
-#ifdef JSDEBUGGER_JAVA_UI
- _jsdjc = JSDJ_CreateContext();
- if (! _jsdjc)
- return 1;
- JSDJ_SetJSDContext(_jsdjc, _jsdc);
- java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc);
-#ifdef LIVECONNECT
- if (java_env)
- (*java_env)->GetJavaVM(java_env, &java_vm);
-#endif
- /*
- * 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
- * is passed on the cmd line.
- */
-#endif /* JSDEBUGGER_JAVA_UI */
-#ifdef JSDEBUGGER_C_UI
- JSDB_InitDebugger(rt, _jsdc, 0);
-#endif /* JSDEBUGGER_C_UI */
-#endif /* JSDEBUGGER */
-
-#ifdef LIVECONNECT
- if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
- return 1;
-#endif
-
- envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
- if (!envobj || !JS_SetPrivate(cx, envobj, envp))
- return 1;
-
- result = ProcessArgs(cx, glob, argv, argc);
-
-#ifdef JSDEBUGGER
- if (_jsdc)
- JSD_DebuggerOff(_jsdc);
-#endif /* JSDEBUGGER */
-
-#ifdef MAC_TEST_HACK
- fclose(gTestResultFile);
-#endif
-
- JS_DestroyContext(cx);
- JS_DestroyRuntime(rt);
- JS_ShutDown();
- return result;
-}
diff --git a/src/extension/script/js/js.mak b/src/extension/script/js/js.mak
deleted file mode 100644
index 0f8b8f53c..000000000
--- a/src/extension/script/js/js.mak
+++ /dev/null
@@ -1,4025 +0,0 @@
-# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-!IF "$(CFG)" == ""
-CFG=jsshell - Win32 Debug
-!MESSAGE No configuration specified. Defaulting to jsshell - Win32 Debug.
-!ENDIF
-
-!IF "$(CFG)" != "js - Win32 Release" && "$(CFG)" != "js - Win32 Debug" &&\
- "$(CFG)" != "jsshell - Win32 Release" && "$(CFG)" != "jsshell - Win32 Debug" &&\
- "$(CFG)" != "fdlibm - Win32 Release" && "$(CFG)" != "fdlibm - Win32 Debug"
-!MESSAGE Invalid configuration "$(CFG)" specified.
-!MESSAGE You can specify a configuration when running NMAKE on this makefile
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "js.mak" CFG="jsshell - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "js - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "js - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "jsshell - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "jsshell - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "fdlibm - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "fdlibm - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-!ERROR An invalid configuration is specified.
-!ENDIF
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-!ELSE
-NULL=nul
-!ENDIF
-################################################################################
-# Begin Project
-# PROP Target_Last_Scanned "jsshell - Win32 Debug"
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "js___Wi1"
-# PROP BASE Intermediate_Dir "js___Wi1"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-OUTDIR=.\Release
-INTDIR=.\Release
-
-ALL : "fdlibm - Win32 Release" "$(OUTDIR)\js32.dll"
-
-CLEAN :
- -@erase "$(INTDIR)\jsapi.obj"
- -@erase "$(INTDIR)\jsarena.obj"
- -@erase "$(INTDIR)\jsarray.obj"
- -@erase "$(INTDIR)\jsatom.obj"
- -@erase "$(INTDIR)\jsbool.obj"
- -@erase "$(INTDIR)\jscntxt.obj"
- -@erase "$(INTDIR)\jsdate.obj"
- -@erase "$(INTDIR)\jsdbgapi.obj"
- -@erase "$(INTDIR)\jsdhash.obj"
- -@erase "$(INTDIR)\jsdtoa.obj"
- -@erase "$(INTDIR)\jsemit.obj"
- -@erase "$(INTDIR)\jsexn.obj"
- -@erase "$(INTDIR)\jsfun.obj"
- -@erase "$(INTDIR)\jsgc.obj"
- -@erase "$(INTDIR)\jshash.obj"
- -@erase "$(INTDIR)\jsinterp.obj"
- -@erase "$(INTDIR)\jslock.obj"
- -@erase "$(INTDIR)\jslog2.obj"
- -@erase "$(INTDIR)\jslong.obj"
- -@erase "$(INTDIR)\jsmath.obj"
- -@erase "$(INTDIR)\jsnum.obj"
- -@erase "$(INTDIR)\jsobj.obj"
- -@erase "$(INTDIR)\jsopcode.obj"
- -@erase "$(INTDIR)\jsparse.obj"
- -@erase "$(INTDIR)\jsprf.obj"
- -@erase "$(INTDIR)\jsregexp.obj"
- -@erase "$(INTDIR)\jsscan.obj"
- -@erase "$(INTDIR)\jsscope.obj"
- -@erase "$(INTDIR)\jsscript.obj"
- -@erase "$(INTDIR)\jsstr.obj"
- -@erase "$(INTDIR)\jsutil.obj"
- -@erase "$(INTDIR)\jsxdrapi.obj"
- -@erase "$(INTDIR)\prmjtime.obj"
- -@erase "$(OUTDIR)\js32.dll"
- -@erase "$(OUTDIR)\js32.exp"
- -@erase "$(OUTDIR)\js32.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D\
- "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /Fp"$(INTDIR)/js.pch" /YX\
- /Fo"$(INTDIR)/" /c
-CPP_OBJS=.\Release/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-MTL=mktyplib.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /win32
-MTL_PROJ=/nologo /D "NDEBUG" /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/js.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/js32.dll"
-# SUBTRACT LINK32 /nodefaultlib
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
- odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
- /pdb:"$(OUTDIR)/js32.pdb" /machine:I386 /out:"$(OUTDIR)/js32.dll"\
- /implib:"$(OUTDIR)/js32.lib" /opt:ref /opt:noicf
-LINK32_OBJS= \
- "$(INTDIR)\jsapi.obj" \
- "$(INTDIR)\jsarena.obj" \
- "$(INTDIR)\jsarray.obj" \
- "$(INTDIR)\jsatom.obj" \
- "$(INTDIR)\jsbool.obj" \
- "$(INTDIR)\jscntxt.obj" \
- "$(INTDIR)\jsdate.obj" \
- "$(INTDIR)\jsdbgapi.obj" \
- "$(INTDIR)\jsdhash.obj" \
- "$(INTDIR)\jsdtoa.obj" \
- "$(INTDIR)\jsemit.obj" \
- "$(INTDIR)\jsexn.obj" \
- "$(INTDIR)\jsfun.obj" \
- "$(INTDIR)\jsgc.obj" \
- "$(INTDIR)\jshash.obj" \
- "$(INTDIR)\jsinterp.obj" \
- "$(INTDIR)\jslock.obj" \
- "$(INTDIR)\jslog2.obj" \
- "$(INTDIR)\jslong.obj" \
- "$(INTDIR)\jsmath.obj" \
- "$(INTDIR)\jsnum.obj" \
- "$(INTDIR)\jsobj.obj" \
- "$(INTDIR)\jsopcode.obj" \
- "$(INTDIR)\jsparse.obj" \
- "$(INTDIR)\jsprf.obj" \
- "$(INTDIR)\jsregexp.obj" \
- "$(INTDIR)\jsscan.obj" \
- "$(INTDIR)\jsscope.obj" \
- "$(INTDIR)\jsscript.obj" \
- "$(INTDIR)\jsstr.obj" \
- "$(INTDIR)\jsutil.obj" \
- "$(INTDIR)\jsxdrapi.obj" \
- "$(INTDIR)\prmjtime.obj" \
- "$(OUTDIR)\fdlibm.lib"
-
-"$(OUTDIR)\js32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "js___Wi2"
-# PROP BASE Intermediate_Dir "js___Wi2"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-OUTDIR=.\Debug
-INTDIR=.\Debug
-
-ALL : "fdlibm - Win32 Debug" "$(OUTDIR)\js32.dll"
-
-CLEAN :
- -@erase "$(INTDIR)\jsapi.obj"
- -@erase "$(INTDIR)\jsarena.obj"
- -@erase "$(INTDIR)\jsarray.obj"
- -@erase "$(INTDIR)\jsatom.obj"
- -@erase "$(INTDIR)\jsbool.obj"
- -@erase "$(INTDIR)\jscntxt.obj"
- -@erase "$(INTDIR)\jsdate.obj"
- -@erase "$(INTDIR)\jsdbgapi.obj"
- -@erase "$(INTDIR)\jsdhash.obj"
- -@erase "$(INTDIR)\jsdtoa.obj"
- -@erase "$(INTDIR)\jsemit.obj"
- -@erase "$(INTDIR)\jsexn.obj"
- -@erase "$(INTDIR)\jsfun.obj"
- -@erase "$(INTDIR)\jsgc.obj"
- -@erase "$(INTDIR)\jshash.obj"
- -@erase "$(INTDIR)\jsinterp.obj"
- -@erase "$(INTDIR)\jslock.obj"
- -@erase "$(INTDIR)\jslog2.obj"
- -@erase "$(INTDIR)\jslong.obj"
- -@erase "$(INTDIR)\jsmath.obj"
- -@erase "$(INTDIR)\jsnum.obj"
- -@erase "$(INTDIR)\jsobj.obj"
- -@erase "$(INTDIR)\jsopcode.obj"
- -@erase "$(INTDIR)\jsparse.obj"
- -@erase "$(INTDIR)\jsprf.obj"
- -@erase "$(INTDIR)\jsregexp.obj"
- -@erase "$(INTDIR)\jsscan.obj"
- -@erase "$(INTDIR)\jsscope.obj"
- -@erase "$(INTDIR)\jsscript.obj"
- -@erase "$(INTDIR)\jsstr.obj"
- -@erase "$(INTDIR)\jsutil.obj"
- -@erase "$(INTDIR)\jsxdrapi.obj"
- -@erase "$(INTDIR)\prmjtime.obj"
- -@erase "$(INTDIR)\vc40.idb"
- -@erase "$(INTDIR)\vc40.pdb"
- -@erase "$(OUTDIR)\js32.dll"
- -@erase "$(OUTDIR)\js32.exp"
- -@erase "$(OUTDIR)\js32.ilk"
- -@erase "$(OUTDIR)\js32.lib"
- -@erase "$(OUTDIR)\js32.pdb"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "DEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /YX /c
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "DEBUG" /D _X86_=1 /D "_WINDOWS"\
- /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /Fp"$(INTDIR)/js.pch" /YX\
- /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-MTL=mktyplib.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /win32
-# ADD MTL /nologo /D "_DEBUG" /win32
-MTL_PROJ=/nologo /D "_DEBUG" /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/js.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/js32.dll"
-# SUBTRACT LINK32 /nodefaultlib
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
- odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes\
- /pdb:"$(OUTDIR)/js32.pdb" /debug /machine:I386 /out:"$(OUTDIR)/js32.dll"\
- /implib:"$(OUTDIR)/js32.lib"
-LINK32_OBJS= \
- "$(INTDIR)\jsapi.obj" \
- "$(INTDIR)\jsarena.obj" \
- "$(INTDIR)\jsarray.obj" \
- "$(INTDIR)\jsatom.obj" \
- "$(INTDIR)\jsbool.obj" \
- "$(INTDIR)\jscntxt.obj" \
- "$(INTDIR)\jsdate.obj" \
- "$(INTDIR)\jsdbgapi.obj" \
- "$(INTDIR)\jsdhash.obj" \
- "$(INTDIR)\jsdtoa.obj" \
- "$(INTDIR)\jsemit.obj" \
- "$(INTDIR)\jsexn.obj" \
- "$(INTDIR)\jsfun.obj" \
- "$(INTDIR)\jsgc.obj" \
- "$(INTDIR)\jshash.obj" \
- "$(INTDIR)\jsinterp.obj" \
- "$(INTDIR)\jslock.obj" \
- "$(INTDIR)\jslog2.obj" \
- "$(INTDIR)\jslong.obj" \
- "$(INTDIR)\jsmath.obj" \
- "$(INTDIR)\jsnum.obj" \
- "$(INTDIR)\jsobj.obj" \
- "$(INTDIR)\jsopcode.obj" \
- "$(INTDIR)\jsparse.obj" \
- "$(INTDIR)\jsprf.obj" \
- "$(INTDIR)\jsregexp.obj" \
- "$(INTDIR)\jsscan.obj" \
- "$(INTDIR)\jsscope.obj" \
- "$(INTDIR)\jsscript.obj" \
- "$(INTDIR)\jsstr.obj" \
- "$(INTDIR)\jsutil.obj" \
- "$(INTDIR)\jsxdrapi.obj" \
- "$(INTDIR)\prmjtime.obj" \
- "$(OUTDIR)\fdlibm.lib"
-
-"$(OUTDIR)\js32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "jsshell - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "jsshell\Release"
-# PROP BASE Intermediate_Dir "jsshell\Release"
-# PROP BASE Target_Dir "jsshell"
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir "jsshell"
-OUTDIR=.\Release
-INTDIR=.\Release
-
-ALL : "js - Win32 Release" "$(OUTDIR)\jsshell.exe"
-
-CLEAN :
- -@erase "$(INTDIR)\js.obj"
- -@erase "$(OUTDIR)\jsshell.exe"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "XP_WIN" /D "JSFILE" /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D\
- "XP_WIN" /D "JSFILE" /Fp"$(INTDIR)/jsshell.pch" /YX /Fo"$(INTDIR)/" /c
-CPP_OBJS=.\Release/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/jsshell.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
- odbccp32.lib /nologo /subsystem:console /incremental:no\
- /pdb:"$(OUTDIR)/jsshell.pdb" /machine:I386 /out:"$(OUTDIR)/jsshell.exe"
-LINK32_OBJS= \
- "$(INTDIR)\js.obj" \
- "$(OUTDIR)\js32.lib"
-
-"$(OUTDIR)\jsshell.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "jsshell - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "jsshell\jsshell_"
-# PROP BASE Intermediate_Dir "jsshell\jsshell_"
-# PROP BASE Target_Dir "jsshell"
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir "jsshell"
-OUTDIR=.\Debug
-INTDIR=.\Debug
-
-ALL : "js - Win32 Debug" "$(OUTDIR)\jsshell.exe"
-
-CLEAN :
- -@erase "$(INTDIR)\js.obj"
- -@erase "$(INTDIR)\vc40.idb"
- -@erase "$(INTDIR)\vc40.pdb"
- -@erase "$(OUTDIR)\jsshell.exe"
- -@erase "$(OUTDIR)\jsshell.ilk"
- -@erase "$(OUTDIR)\jsshell.pdb"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_CONSOLE" /D "_DEBUG" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "DEBUG" /YX /c
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_CONSOLE" /D "_DEBUG" /D "WIN32"\
- /D "XP_WIN" /D "JSFILE" /D "DEBUG" /Fp"$(INTDIR)/jsshell.pch" /YX\
- /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/jsshell.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
- odbccp32.lib /nologo /subsystem:console /incremental:yes\
- /pdb:"$(OUTDIR)/jsshell.pdb" /debug /machine:I386 /out:"$(OUTDIR)/jsshell.exe"
-LINK32_OBJS= \
- "$(INTDIR)\js.obj" \
- "$(OUTDIR)\js32.lib"
-
-"$(OUTDIR)\jsshell.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "fdlibm\Release"
-# PROP BASE Intermediate_Dir "fdlibm\Release"
-# PROP BASE Target_Dir "fdlibm"
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir "fdlibm"
-OUTDIR=.\Release
-INTDIR=.\Release
-
-ALL : "$(OUTDIR)\fdlibm.lib"
-
-CLEAN :
- -@erase "$(INTDIR)\e_atan2.obj"
- -@erase "$(INTDIR)\e_pow.obj"
- -@erase "$(INTDIR)\e_sqrt.obj"
- -@erase "$(INTDIR)\k_standard.obj"
- -@erase "$(INTDIR)\s_atan.obj"
- -@erase "$(INTDIR)\s_copysign.obj"
- -@erase "$(INTDIR)\s_fabs.obj"
- -@erase "$(INTDIR)\s_finite.obj"
- -@erase "$(INTDIR)\s_isnan.obj"
- -@erase "$(INTDIR)\s_matherr.obj"
- -@erase "$(INTDIR)\s_rint.obj"
- -@erase "$(INTDIR)\s_scalbn.obj"
- -@erase "$(INTDIR)\w_atan2.obj"
- -@erase "$(INTDIR)\w_pow.obj"
- -@erase "$(INTDIR)\w_sqrt.obj"
- -@erase "$(OUTDIR)\fdlibm.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D "_IEEE_LIBM" /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D\
- "_IEEE_LIBM" /D "XP_WIN" /I .\ /Fp"$(INTDIR)/fdlibm.pch" /YX /Fo"$(INTDIR)/" /c
-CPP_OBJS=.\Release/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/fdlibm.bsc"
-BSC32_SBRS= \
-
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-LIB32_FLAGS=/nologo /out:"$(OUTDIR)/fdlibm.lib"
-LIB32_OBJS= \
- "$(INTDIR)\e_atan2.obj" \
- "$(INTDIR)\e_pow.obj" \
- "$(INTDIR)\e_sqrt.obj" \
- "$(INTDIR)\k_standard.obj" \
- "$(INTDIR)\s_atan.obj" \
- "$(INTDIR)\s_copysign.obj" \
- "$(INTDIR)\s_fabs.obj" \
- "$(INTDIR)\s_finite.obj" \
- "$(INTDIR)\s_isnan.obj" \
- "$(INTDIR)\s_matherr.obj" \
- "$(INTDIR)\s_rint.obj" \
- "$(INTDIR)\s_scalbn.obj" \
- "$(INTDIR)\w_atan2.obj" \
- "$(INTDIR)\w_pow.obj" \
- "$(INTDIR)\w_sqrt.obj"
-
-"$(OUTDIR)\fdlibm.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
- $(LIB32) @<<
- $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "fdlibm\Debug"
-# PROP BASE Intermediate_Dir "fdlibm\Debug"
-# PROP BASE Target_Dir "fdlibm"
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir "fdlibm"
-OUTDIR=.\Debug
-INTDIR=.\Debug
-
-ALL : "$(OUTDIR)\fdlibm.lib"
-
-CLEAN :
- -@erase "$(INTDIR)\e_atan2.obj"
- -@erase "$(INTDIR)\e_pow.obj"
- -@erase "$(INTDIR)\e_sqrt.obj"
- -@erase "$(INTDIR)\k_standard.obj"
- -@erase "$(INTDIR)\s_atan.obj"
- -@erase "$(INTDIR)\s_copysign.obj"
- -@erase "$(INTDIR)\s_fabs.obj"
- -@erase "$(INTDIR)\s_finite.obj"
- -@erase "$(INTDIR)\s_isnan.obj"
- -@erase "$(INTDIR)\s_matherr.obj"
- -@erase "$(INTDIR)\s_rint.obj"
- -@erase "$(INTDIR)\s_scalbn.obj"
- -@erase "$(INTDIR)\w_atan2.obj"
- -@erase "$(INTDIR)\w_pow.obj"
- -@erase "$(INTDIR)\w_sqrt.obj"
- -@erase "$(OUTDIR)\fdlibm.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D "_IEEE_LIBM" /YX /c
-CPP_PROJ=/nologo /MDd /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D\
- "_IEEE_LIBM" /D "XP_WIN" -I .\ /Fp"$(INTDIR)/fdlibm.pch" /YX /Fo"$(INTDIR)/" /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=.\.
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/fdlibm.bsc"
-BSC32_SBRS= \
-
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-LIB32_FLAGS=/nologo /out:"$(OUTDIR)/fdlibm.lib"
-LIB32_OBJS= \
- "$(INTDIR)\e_atan2.obj" \
- "$(INTDIR)\e_pow.obj" \
- "$(INTDIR)\e_sqrt.obj" \
- "$(INTDIR)\k_standard.obj" \
- "$(INTDIR)\s_atan.obj" \
- "$(INTDIR)\s_copysign.obj" \
- "$(INTDIR)\s_fabs.obj" \
- "$(INTDIR)\s_finite.obj" \
- "$(INTDIR)\s_isnan.obj" \
- "$(INTDIR)\s_matherr.obj" \
- "$(INTDIR)\s_rint.obj" \
- "$(INTDIR)\s_scalbn.obj" \
- "$(INTDIR)\w_atan2.obj" \
- "$(INTDIR)\w_pow.obj" \
- "$(INTDIR)\w_sqrt.obj"
-
-"$(OUTDIR)\fdlibm.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
- $(LIB32) @<<
- $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
-<<
-
-!ENDIF
-
-################################################################################
-# Begin Target
-
-# Name "js - Win32 Release"
-# Name "js - Win32 Debug"
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-!ENDIF
-
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsapi.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSAPI=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdate.h"\
- ".\jsemit.h"\
- ".\jsexn.h"\
- ".\jsfile.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsmath.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSAPI=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsapi.obj" : $(SOURCE) $(DEP_CPP_JSAPI) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSAPI=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdate.h"\
- ".\jsemit.h"\
- ".\jsexn.h"\
- ".\jsfile.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsmath.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSAPI=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsapi.obj" : $(SOURCE) $(DEP_CPP_JSAPI) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsarena.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSARE=\
- ".\jsarena.h"\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsstddef.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSARE=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsarena.obj" : $(SOURCE) $(DEP_CPP_JSARE) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSARE=\
- ".\jsarena.h"\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsstddef.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSARE=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsarena.obj" : $(SOURCE) $(DEP_CPP_JSARE) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsarray.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSARR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSARR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsarray.obj" : $(SOURCE) $(DEP_CPP_JSARR) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSARR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSARR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsarray.obj" : $(SOURCE) $(DEP_CPP_JSARR) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsatom.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSATO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSATO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsatom.obj" : $(SOURCE) $(DEP_CPP_JSATO) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSATO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSATO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsatom.obj" : $(SOURCE) $(DEP_CPP_JSATO) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsbool.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSBOO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSBOO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsbool.obj" : $(SOURCE) $(DEP_CPP_JSBOO) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSBOO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSBOO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsbool.obj" : $(SOURCE) $(DEP_CPP_JSBOO) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jscntxt.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSCNT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsexn.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSCNT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jscntxt.obj" : $(SOURCE) $(DEP_CPP_JSCNT) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSCNT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsexn.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSCNT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jscntxt.obj" : $(SOURCE) $(DEP_CPP_JSCNT) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsdate.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSDAT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdate.h"\
- ".\jsdtoa.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDAT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdate.obj" : $(SOURCE) $(DEP_CPP_JSDAT) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSDAT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdate.h"\
- ".\jsdtoa.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDAT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdate.obj" : $(SOURCE) $(DEP_CPP_JSDAT) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsdbgapi.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSDBG=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDBG=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdbgapi.obj" : $(SOURCE) $(DEP_CPP_JSDBG) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSDBG=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDBG=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdbgapi.obj" : $(SOURCE) $(DEP_CPP_JSDBG) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsdhash.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSDHA=\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jsdhash.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDHA=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsdhash.obj" : $(SOURCE) $(DEP_CPP_JSDHA) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSDHA=\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jsdhash.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDHA=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsdhash.obj" : $(SOURCE) $(DEP_CPP_JSDHA) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsdtoa.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSDTO=\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsstddef.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDTO=\
- ".\jsautocfg.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdtoa.obj" : $(SOURCE) $(DEP_CPP_JSDTO) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSDTO=\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsstddef.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSDTO=\
- ".\jsautocfg.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsdtoa.obj" : $(SOURCE) $(DEP_CPP_JSDTO) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsemit.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSEMI=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSEMI=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsemit.obj" : $(SOURCE) $(DEP_CPP_JSEMI) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSEMI=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSEMI=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsemit.obj" : $(SOURCE) $(DEP_CPP_JSEMI) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsexn.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSEXN=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsexn.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSEXN=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsexn.obj" : $(SOURCE) $(DEP_CPP_JSEXN) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSEXN=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsexn.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSEXN=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsexn.obj" : $(SOURCE) $(DEP_CPP_JSEXN) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsfun.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSFUN=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSFUN=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsfun.obj" : $(SOURCE) $(DEP_CPP_JSFUN) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSFUN=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSFUN=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsfun.obj" : $(SOURCE) $(DEP_CPP_JSFUN) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsgc.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSGC_=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSGC_=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsgc.obj" : $(SOURCE) $(DEP_CPP_JSGC_) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSGC_=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSGC_=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsgc.obj" : $(SOURCE) $(DEP_CPP_JSGC_) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jshash.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSHAS=\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jshash.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSHAS=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jshash.obj" : $(SOURCE) $(DEP_CPP_JSHAS) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSHAS=\
- ".\jsbit.h"\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jshash.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSHAS=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jshash.obj" : $(SOURCE) $(DEP_CPP_JSHAS) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsinterp.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSINT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSINT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsinterp.obj" : $(SOURCE) $(DEP_CPP_JSINT) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSINT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSINT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsinterp.obj" : $(SOURCE) $(DEP_CPP_JSINT) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jslock.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSLOC=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLOC=\
- ".\jsautocfg.h"\
- ".\pratom.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
- ".\prthread.h"\
-
-
-"$(INTDIR)\jslock.obj" : $(SOURCE) $(DEP_CPP_JSLOC) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSLOC=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLOC=\
- ".\jsautocfg.h"\
- ".\pratom.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
- ".\prthread.h"\
-
-
-"$(INTDIR)\jslock.obj" : $(SOURCE) $(DEP_CPP_JSLOC) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jslog2.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSLOG=\
- ".\jsbit.h"\
- ".\jscpucfg.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLOG=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jslog2.obj" : $(SOURCE) $(DEP_CPP_JSLOG) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSLOG=\
- ".\jsbit.h"\
- ".\jscpucfg.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLOG=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jslog2.obj" : $(SOURCE) $(DEP_CPP_JSLOG) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jslong.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSLON=\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLON=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jslong.obj" : $(SOURCE) $(DEP_CPP_JSLON) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSLON=\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jstypes.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSLON=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jslong.obj" : $(SOURCE) $(DEP_CPP_JSLON) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsmath.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSMAT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslibmath.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsmath.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSMAT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsmath.obj" : $(SOURCE) $(DEP_CPP_JSMAT) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSMAT=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslibmath.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsmath.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSMAT=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsmath.obj" : $(SOURCE) $(DEP_CPP_JSMAT) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsnum.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSNUM=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSNUM=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsnum.obj" : $(SOURCE) $(DEP_CPP_JSNUM) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSNUM=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSNUM=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsnum.obj" : $(SOURCE) $(DEP_CPP_JSNUM) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsobj.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSOBJ=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSOBJ=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsobj.obj" : $(SOURCE) $(DEP_CPP_JSOBJ) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSOBJ=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSOBJ=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsobj.obj" : $(SOURCE) $(DEP_CPP_JSOBJ) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsopcode.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSOPC=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsdtoa.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSOPC=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsopcode.obj" : $(SOURCE) $(DEP_CPP_JSOPC) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSOPC=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsdtoa.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSOPC=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsopcode.obj" : $(SOURCE) $(DEP_CPP_JSOPC) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsparse.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSPAR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSPAR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsparse.obj" : $(SOURCE) $(DEP_CPP_JSPAR) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSPAR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSPAR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsparse.obj" : $(SOURCE) $(DEP_CPP_JSPAR) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsprf.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSPRF=\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSPRF=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsprf.obj" : $(SOURCE) $(DEP_CPP_JSPRF) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSPRF=\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSPRF=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsprf.obj" : $(SOURCE) $(DEP_CPP_JSPRF) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsregexp.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSREG=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSREG=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsregexp.obj" : $(SOURCE) $(DEP_CPP_JSREG) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSREG=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSREG=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsregexp.obj" : $(SOURCE) $(DEP_CPP_JSREG) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsscan.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSSCA=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jsexn.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCA=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscan.obj" : $(SOURCE) $(DEP_CPP_JSSCA) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSSCA=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdtoa.h"\
- ".\jsexn.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCA=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscan.obj" : $(SOURCE) $(DEP_CPP_JSSCA) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsscope.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSSCO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscope.obj" : $(SOURCE) $(DEP_CPP_JSSCO) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSSCO=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCO=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscope.obj" : $(SOURCE) $(DEP_CPP_JSSCO) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsscript.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSSCR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscript.obj" : $(SOURCE) $(DEP_CPP_JSSCR) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSSCR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSCR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsscript.obj" : $(SOURCE) $(DEP_CPP_JSSCR) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsstr.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSSTR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSTR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsstr.obj" : $(SOURCE) $(DEP_CPP_JSSTR) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSSTR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsarray.h"\
- ".\jsatom.h"\
- ".\jsbool.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsnum.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSSTR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsstr.obj" : $(SOURCE) $(DEP_CPP_JSSTR) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsutil.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSUTI=\
- ".\jscpucfg.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSUTI=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsutil.obj" : $(SOURCE) $(DEP_CPP_JSUTI) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSUTI=\
- ".\jscpucfg.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSUTI=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\jsutil.obj" : $(SOURCE) $(DEP_CPP_JSUTI) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\jsxdrapi.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_JSXDR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSXDR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsxdrapi.obj" : $(SOURCE) $(DEP_CPP_JSXDR) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_JSXDR=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscope.h"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- ".\jsxdrapi.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JSXDR=\
- ".\jsautocfg.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\jsxdrapi.obj" : $(SOURCE) $(DEP_CPP_JSXDR) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\prmjtime.c
-
-!IF "$(CFG)" == "js - Win32 Release"
-
-DEP_CPP_PRMJT=\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\TIMEB.H"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_PRMJT=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\prmjtime.obj" : $(SOURCE) $(DEP_CPP_PRMJT) "$(INTDIR)"
-
-
-!ELSEIF "$(CFG)" == "js - Win32 Debug"
-
-DEP_CPP_PRMJT=\
- ".\jscompat.h"\
- ".\jscpucfg.h"\
- ".\jslong.h"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsprf.h"\
- ".\jstypes.h"\
- ".\prmjtime.h"\
- {$(INCLUDE)}"\sys\TIMEB.H"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_PRMJT=\
- ".\jsautocfg.h"\
-
-
-"$(INTDIR)\prmjtime.obj" : $(SOURCE) $(DEP_CPP_PRMJT) "$(INTDIR)"
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Project Dependency
-
-# Project_Dep_Name "fdlibm"
-
-!IF "$(CFG)" == "js - Win32 Debug"
-
-"fdlibm - Win32 Debug" :
- $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="fdlibm - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "js - Win32 Release"
-
-"fdlibm - Win32 Release" :
- $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="fdlibm - Win32 Release"
-
-!ENDIF
-
-# End Project Dependency
-# End Target
-################################################################################
-# Begin Target
-
-# Name "jsshell - Win32 Release"
-# Name "jsshell - Win32 Debug"
-
-!IF "$(CFG)" == "jsshell - Win32 Release"
-
-!ELSEIF "$(CFG)" == "jsshell - Win32 Debug"
-
-!ENDIF
-
-################################################################################
-# Begin Source File
-
-SOURCE=.\js.c
-DEP_CPP_JS_C42=\
- ".\js.msg"\
- ".\jsapi.h"\
- ".\jsarena.h"\
- ".\jsatom.h"\
- ".\jsclist.h"\
- ".\jscntxt.h"\
- ".\jscompat.h"\
- ".\jsconfig.h"\
- ".\jscpucfg.h"\
- ".\jsdbgapi.h"\
- ".\jsemit.h"\
- ".\jsfun.h"\
- ".\jsgc.h"\
- ".\jshash.h"\
- ".\jsinterp.h"\
- ".\jslock.h"\
- ".\jslong.h"\
- ".\jsobj.h"\
- ".\jsopcode.h"\
- ".\jsopcode.tbl"\
- ".\jsosdep.h"\
- ".\jsotypes.h"\
- ".\jsparse.h"\
- ".\jsprf.h"\
- ".\jsprvtd.h"\
- ".\jspubtd.h"\
- ".\jsregexp.h"\
- ".\jsscan.h"\
- ".\jsscope.h"\
- ".\jsscript.h"\
- ".\jsshell.msg"\
- ".\jsstddef.h"\
- ".\jsstr.h"\
- ".\jstypes.h"\
- ".\jsutil.h"\
- {$(INCLUDE)}"\sys\types.h"\
-
-NODEP_CPP_JS_C42=\
- ".\jsautocfg.h"\
- ".\jsdb.h"\
- ".\jsdebug.h"\
- ".\jsdjava.h"\
- ".\jsjava.h"\
- ".\jsperl.h"\
- ".\prcvar.h"\
- ".\prlock.h"\
-
-
-"$(INTDIR)\js.obj" : $(SOURCE) $(DEP_CPP_JS_C42) "$(INTDIR)"
-
-
-# End Source File
-################################################################################
-# Begin Project Dependency
-
-# Project_Dep_Name "js"
-
-!IF "$(CFG)" == "jsshell - Win32 Release"
-
-"js - Win32 Release" :
- $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="js - Win32 Release"
-
-!ELSEIF "$(CFG)" == "jsshell - Win32 Debug"
-
-"js - Win32 Debug" :
- $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="js - Win32 Debug"
-
-!ENDIF
-
-# End Project Dependency
-# End Target
-################################################################################
-# Begin Target
-
-# Name "fdlibm - Win32 Release"
-# Name "fdlibm - Win32 Debug"
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-!ENDIF
-
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\w_atan2.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_W_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_atan2.obj" : $(SOURCE) $(DEP_CPP_W_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_W_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_atan2.obj" : $(SOURCE) $(DEP_CPP_W_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_copysign.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_COP=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_copysign.obj" : $(SOURCE) $(DEP_CPP_S_COP) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_COP=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_copysign.obj" : $(SOURCE) $(DEP_CPP_S_COP) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\w_pow.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_W_POW=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_pow.obj" : $(SOURCE) $(DEP_CPP_W_POW) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_W_POW=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_pow.obj" : $(SOURCE) $(DEP_CPP_W_POW) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\e_pow.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_E_POW=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_pow.obj" : $(SOURCE) $(DEP_CPP_E_POW) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_E_POW=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_pow.obj" : $(SOURCE) $(DEP_CPP_E_POW) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\k_standard.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_K_STA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\k_standard.obj" : $(SOURCE) $(DEP_CPP_K_STA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_K_STA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\k_standard.obj" : $(SOURCE) $(DEP_CPP_K_STA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\e_atan2.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_E_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_atan2.obj" : $(SOURCE) $(DEP_CPP_E_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_E_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_atan2.obj" : $(SOURCE) $(DEP_CPP_E_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_isnan.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_ISN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_isnan.obj" : $(SOURCE) $(DEP_CPP_S_ISN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_ISN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_isnan.obj" : $(SOURCE) $(DEP_CPP_S_ISN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_fabs.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_FAB=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_fabs.obj" : $(SOURCE) $(DEP_CPP_S_FAB) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_FAB=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_fabs.obj" : $(SOURCE) $(DEP_CPP_S_FAB) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\w_sqrt.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_W_SQR=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_sqrt.obj" : $(SOURCE) $(DEP_CPP_W_SQR) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_W_SQR=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\w_sqrt.obj" : $(SOURCE) $(DEP_CPP_W_SQR) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_scalbn.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_SCA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_scalbn.obj" : $(SOURCE) $(DEP_CPP_S_SCA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_SCA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_scalbn.obj" : $(SOURCE) $(DEP_CPP_S_SCA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\e_sqrt.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_E_SQR=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_sqrt.obj" : $(SOURCE) $(DEP_CPP_E_SQR) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_E_SQR=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\e_sqrt.obj" : $(SOURCE) $(DEP_CPP_E_SQR) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_rint.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_RIN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_rint.obj" : $(SOURCE) $(DEP_CPP_S_RIN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_RIN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_rint.obj" : $(SOURCE) $(DEP_CPP_S_RIN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_atan.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_atan.obj" : $(SOURCE) $(DEP_CPP_S_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_ATA=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_atan.obj" : $(SOURCE) $(DEP_CPP_S_ATA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_finite.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_FIN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_finite.obj" : $(SOURCE) $(DEP_CPP_S_FIN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_FIN=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_finite.obj" : $(SOURCE) $(DEP_CPP_S_FIN) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-################################################################################
-# Begin Source File
-
-SOURCE=.\fdlibm\s_matherr.c
-
-!IF "$(CFG)" == "fdlibm - Win32 Release"
-
-DEP_CPP_S_MAT=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_matherr.obj" : $(SOURCE) $(DEP_CPP_S_MAT) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug"
-
-DEP_CPP_S_MAT=\
- ".\fdlibm\fdlibm.h"\
-
-
-"$(INTDIR)\s_matherr.obj" : $(SOURCE) $(DEP_CPP_S_MAT) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-# End Source File
-# End Target
-# End Project
-################################################################################
diff --git a/src/extension/script/js/js.msg b/src/extension/script/js/js.msg
deleted file mode 100644
index dbc571fdf..000000000
--- a/src/extension/script/js/js.msg
+++ /dev/null
@@ -1,251 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * 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"
- *
- * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED<n> free
- * index placeholders in the middle of the list.
- */
-
-MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
-MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined")
-MSG_DEF(JSMSG_NO_REG_EXPS, 2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported")
-MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
-MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_NONE, "invalid format character {0}")
-MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_NONE, "unknown type {0}")
-MSG_DEF(JSMSG_CANT_LOCK, 6, 0, JSEXN_NONE, "can't lock memory")
-MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_NONE, "can't unlock memory")
-MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
-MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_NONE, "{0} has no constructor")
-MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
-MSG_DEF(JSMSG_UNUSED11, 11, 0, JSEXN_NONE, "<Error #11 is currently unused>")
-MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument")
-MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
-MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals")
-MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
-MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
-MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_INTERNALERR, "{0} too large")
-MSG_DEF(JSMSG_UNUSED18, 18, 0, JSEXN_NONE, "<Error #18 is currently unused>")
-MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
-MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
-MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}")
-MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_TYPEERR, "{0} is not a function")
-MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_TYPEERR, "{0} is not a constructor")
-MSG_DEF(JSMSG_STACK_OVERFLOW, 24, 1, JSEXN_INTERNALERR, "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_INTERNALERR, "too much recursion")
-MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
-MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_NONE, "invalid new expression result {0}")
-MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
-MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
-MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
-MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
-MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
-MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number")
-MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_NONE, "can't convert {0} to an integer")
-MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_ERR, "cyclic {0} value")
-MSG_DEF(JSMSG_PERMANENT, 37, 1, JSEXN_ERR, "{0} is permanent")
-MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_TYPEERR, "can't convert {0} to {1}")
-MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TYPEERR, "{0} has no properties")
-MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_NONE, "can't find class id {0}")
-MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_NONE, "can't XDR class {0}")
-MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
-MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
-MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
-MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments")
-MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
-MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
-MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
-MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
-MSG_DEF(JSMSG_ZERO_QUANTIFIER, 50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}")
-MSG_DEF(JSMSG_UNTERM_QUANTIFIER, 51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}")
-MSG_DEF(JSMSG_EMPTY_BEFORE_STAR, 52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty")
-MSG_DEF(JSMSG_EMPTY_BEFORE_PLUS, 53, 0, JSEXN_SYNTAXERR, "regular expression before + could be empty")
-MSG_DEF(JSMSG_MISSING_PAREN, 54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical")
-MSG_DEF(JSMSG_UNTERM_CLASS, 55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}")
-MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression")
-MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class")
-MSG_DEF(JSMSG_BAD_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
-MSG_DEF(JSMSG_NO_INPUT, 59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}")
-MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_NONE, "can't open {0}: {1}")
-MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
-MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
-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_SCRIPT_MAGIC, 68, 0, JSEXN_NONE, "bad script XDR magic number")
-MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
-MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
-MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
-MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before function body")
-MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body")
-MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition")
-MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition")
-MSG_DEF(JSMSG_NO_IMPORT_NAME, 76, 0, JSEXN_SYNTAXERR, "missing name in import statement")
-MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator")
-MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression")
-MSG_DEF(JSMSG_NO_EXPORT_NAME, 79, 0, JSEXN_SYNTAXERR, "missing name in export statement")
-MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression")
-MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
-MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body")
-MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label")
-MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body")
-MSG_DEF(JSMSG_PAREN_AFTER_FOR, 85, 0, JSEXN_SYNTAXERR, "missing ( after for")
-MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
-MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
-MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
-MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 89, 0, JSEXN_SYNTAXERR, "missing { before try block")
-MSG_DEF(JSMSG_CURLY_AFTER_TRY, 90, 0, JSEXN_SYNTAXERR, "missing } after try block")
-MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 91, 0, JSEXN_SYNTAXERR, "missing ( before catch")
-MSG_DEF(JSMSG_CATCH_IDENTIFIER, 92, 0, JSEXN_SYNTAXERR, "missing identifier in catch")
-MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 93, 0, JSEXN_SYNTAXERR, "missing ) after catch")
-MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 94, 0, JSEXN_SYNTAXERR, "missing { before catch block")
-MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 95, 0, JSEXN_SYNTAXERR, "missing } after catch block")
-MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 96, 0, JSEXN_SYNTAXERR, "missing { before finally block")
-MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 97, 0, JSEXN_SYNTAXERR, "missing } after finally block")
-MSG_DEF(JSMSG_CATCH_OR_FINALLY, 98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try")
-MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
-MSG_DEF(JSMSG_PAREN_AFTER_WITH, 100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
-MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 101, 0, JSEXN_SYNTAXERR, "missing } in compound statement")
-MSG_DEF(JSMSG_NO_VARIABLE_NAME, 102, 0, JSEXN_SYNTAXERR, "missing variable name")
-MSG_DEF(JSMSG_COLON_IN_COND, 103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression")
-MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 104, 0, JSEXN_SYNTAXERR, "missing ) after argument list")
-MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 105, 0, JSEXN_SYNTAXERR, "missing ] after element list")
-MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after property id")
-MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list")
-MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
-MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement")
-MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 1, JSEXN_TYPEERR, "function {0} does not always return a value")
-MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_TYPEERR, "duplicate formal argument {0}")
-MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
-MSG_DEF(JSMSG_BAD_IMPORT, 113, 0, JSEXN_SYNTAXERR, "invalid import expression")
-MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default")
-MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases")
-MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement")
-MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
-MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_SYNTAXERR, "catch after unconditional catch")
-MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try")
-MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try")
-MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found")
-MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "invalid break")
-MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "invalid continue")
-MSG_DEF(JSMSG_BAD_RETURN, 124, 0, JSEXN_SYNTAXERR, "invalid return")
-MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label")
-MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label")
-MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_TYPEERR, "variable {0} hides argument")
-MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
-MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side")
-MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
-MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id")
-MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
-MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error")
-MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
-MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object")
-MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent")
-MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory")
-MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
-MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
-MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment")
-MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
-MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression")
-MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number")
-MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character")
-MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 octal constant")
-MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name.")
-MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_NONE, "uncaught exception: {0}")
-MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
-MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
-MSG_DEF(JSMSG_PRECISION_RANGE, 150, 1, JSEXN_RANGEERR, "precision {0} out of range")
-MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 151, 1, JSEXN_SYNTAXERR, "invalid {0} usage")
-MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 152, 0, JSEXN_RANGEERR, "invalid array length")
-MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS, 153, 1, JSEXN_NONE, "can't describe non-native properties of class {0}")
-MSG_DEF(JSMSG_BAD_APPLY_ARGS, 154, 0, JSEXN_TYPEERR, "second argument to Function.prototype.apply must be an array")
-MSG_DEF(JSMSG_REDECLARED_VAR, 155, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}")
-MSG_DEF(JSMSG_UNDECLARED_VAR, 156, 1, JSEXN_TYPEERR, "assignment to undeclared variable {0}")
-MSG_DEF(JSMSG_ANON_NO_RETURN_VALUE, 157, 0, JSEXN_TYPEERR, "anonymous function does not always return a value")
-MSG_DEF(JSMSG_DEPRECATED_USAGE, 158, 1, JSEXN_REFERENCEERR, "deprecated {0} usage")
-MSG_DEF(JSMSG_BAD_URI, 159, 0, JSEXN_URIERR, "malformed URI sequence")
-MSG_DEF(JSMSG_GETTER_ONLY, 160, 0, JSEXN_TYPEERR, "setting a property that has only a getter")
-MSG_DEF(JSMSG_TRAILING_COMMA, 161, 0, JSEXN_SYNTAXERR, "trailing comma is not legal in ECMA-262 object initializers")
-MSG_DEF(JSMSG_UNDEFINED_PROP, 162, 1, JSEXN_TYPEERR, "reference to undefined property {0}")
-MSG_DEF(JSMSG_USELESS_EXPR, 163, 0, JSEXN_TYPEERR, "useless expression")
-MSG_DEF(JSMSG_REDECLARED_PARAM, 164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
-MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
-MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot index out of range")
-MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals")
-MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects")
-MSG_DEF(JSMSG_CANT_UNSEAL_OBJECT, 169, 1, JSEXN_ERR, "can't unseal {0} objects")
diff --git a/src/extension/script/js/jsapi.c b/src/extension/script/js/jsapi.c
deleted file mode 100644
index faf02d983..000000000
--- a/src/extension/script/js/jsapi.c
+++ /dev/null
@@ -1,4187 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JavaScript API.
- */
-#include "jsstddef.h"
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsclist.h"
-#include "jsdhash.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jsbool.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdate.h"
-#include "jsdtoa.h"
-#include "jsemit.h"
-#include "jsexn.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsmath.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsparse.h"
-#include "jsregexp.h"
-#include "jsscan.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-#include "prmjtime.h"
-
-#if JS_HAS_FILE_OBJECT
-#include "jsfile.h"
-#endif
-
-#ifdef HAVE_VA_LIST_AS_ARRAY
-#define JS_ADDRESSOF_VA_LIST(ap) (ap)
-#else
-#define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
-#endif
-
-#if defined(JS_PARANOID_REQUEST) && defined(JS_THREADSAFE)
-#define CHECK_REQUEST(cx) JS_ASSERT(cx->requestDepth)
-#else
-#define CHECK_REQUEST(cx) ((void)0)
-#endif
-
-JS_PUBLIC_API(int64)
-JS_Now()
-{
- return PRMJ_Now();
-}
-
-JS_PUBLIC_API(jsval)
-JS_GetNaNValue(JSContext *cx)
-{
- return DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
-}
-
-JS_PUBLIC_API(jsval)
-JS_GetNegativeInfinityValue(JSContext *cx)
-{
- return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
-}
-
-JS_PUBLIC_API(jsval)
-JS_GetPositiveInfinityValue(JSContext *cx)
-{
- return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
-}
-
-JS_PUBLIC_API(jsval)
-JS_GetEmptyStringValue(JSContext *cx)
-{
- return STRING_TO_JSVAL(cx->runtime->emptyString);
-}
-
-static JSBool
-TryArgumentFormatter(JSContext *cx, const char **formatp, JSBool fromJS,
- jsval **vpp, va_list *app)
-{
- const char *format;
- JSArgumentFormatMap *map;
-
- format = *formatp;
- for (map = cx->argumentFormatMap; map; map = map->next) {
- if (!strncmp(format, map->format, map->length)) {
- *formatp = format + map->length;
- return map->formatter(cx, format, fromJS, vpp, app);
- }
- }
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR, format);
- return JS_FALSE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
- ...)
-{
- va_list ap;
- JSBool ok;
-
- va_start(ap, format);
- ok = JS_ConvertArgumentsVA(cx, argc, argv, format, ap);
- va_end(ap);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
- const char *format, va_list ap)
-{
- jsval *sp;
- JSBool required;
- char c;
- JSFunction *fun;
- jsdouble d;
- JSString *str;
- JSObject *obj;
-
- CHECK_REQUEST(cx);
- sp = argv;
- required = JS_TRUE;
- while ((c = *format++) != '\0') {
- if (isspace(c))
- continue;
- if (c == '/') {
- required = JS_FALSE;
- continue;
- }
- if (sp == argv + argc) {
- if (required) {
- fun = js_ValueToFunction(cx, &argv[-2], 0);
- if (fun) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%u", argc);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_MORE_ARGS_NEEDED,
- JS_GetFunctionName(fun), numBuf,
- (argc == 1) ? "" : "s");
- }
- return JS_FALSE;
- }
- break;
- }
- switch (c) {
- case 'b':
- if (!js_ValueToBoolean(cx, *sp, va_arg(ap, JSBool *)))
- return JS_FALSE;
- break;
- case 'c':
- if (!js_ValueToUint16(cx, *sp, va_arg(ap, uint16 *)))
- return JS_FALSE;
- break;
- case 'i':
- if (!js_ValueToECMAInt32(cx, *sp, va_arg(ap, int32 *)))
- return JS_FALSE;
- break;
- case 'u':
- if (!js_ValueToECMAUint32(cx, *sp, va_arg(ap, uint32 *)))
- return JS_FALSE;
- break;
- case 'j':
- if (!js_ValueToInt32(cx, *sp, va_arg(ap, int32 *)))
- return JS_FALSE;
- break;
- case 'd':
- if (!js_ValueToNumber(cx, *sp, va_arg(ap, jsdouble *)))
- return JS_FALSE;
- break;
- case 'I':
- if (!js_ValueToNumber(cx, *sp, &d))
- return JS_FALSE;
- *va_arg(ap, jsdouble *) = js_DoubleToInteger(d);
- break;
- case 's':
- case 'S':
- case 'W':
- str = js_ValueToString(cx, *sp);
- if (!str)
- return JS_FALSE;
- *sp = STRING_TO_JSVAL(str);
- if (c == 's')
- *va_arg(ap, char **) = JS_GetStringBytes(str);
- else if (c == 'W')
- *va_arg(ap, jschar **) = JS_GetStringChars(str);
- else
- *va_arg(ap, JSString **) = str;
- break;
- case 'o':
- if (!js_ValueToObject(cx, *sp, &obj))
- return JS_FALSE;
- *sp = OBJECT_TO_JSVAL(obj);
- *va_arg(ap, JSObject **) = obj;
- break;
- case 'f':
- fun = js_ValueToFunction(cx, sp, 0);
- if (!fun)
- return JS_FALSE;
- *sp = OBJECT_TO_JSVAL(fun->object);
- *va_arg(ap, JSFunction **) = fun;
- break;
- case 'v':
- *va_arg(ap, jsval *) = *sp;
- break;
- case '*':
- break;
- default:
- format--;
- if (!TryArgumentFormatter(cx, &format, JS_TRUE, &sp,
- JS_ADDRESSOF_VA_LIST(ap))) {
- return JS_FALSE;
- }
- /* NB: the formatter already updated sp, so we continue here. */
- continue;
- }
- sp++;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(jsval *)
-JS_PushArguments(JSContext *cx, void **markp, const char *format, ...)
-{
- va_list ap;
- jsval *argv;
-
- va_start(ap, format);
- argv = JS_PushArgumentsVA(cx, markp, format, ap);
- va_end(ap);
- return argv;
-}
-
-JS_PUBLIC_API(jsval *)
-JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap)
-{
- uintN argc;
- jsval *argv, *sp;
- char c;
- const char *cp;
- JSString *str;
- JSFunction *fun;
- JSStackHeader *sh;
-
- CHECK_REQUEST(cx);
- *markp = NULL;
- argc = 0;
- for (cp = format; (c = *cp) != '\0'; cp++) {
- /*
- * Count non-space non-star characters as individual jsval arguments.
- * This may over-allocate stack, but we'll fix below.
- */
- if (isspace(c) || c == '*')
- continue;
- argc++;
- }
- sp = js_AllocStack(cx, argc, markp);
- if (!sp)
- return NULL;
- argv = sp;
- while ((c = *format++) != '\0') {
- if (isspace(c) || c == '*')
- continue;
- switch (c) {
- case 'b':
- *sp = BOOLEAN_TO_JSVAL((JSBool) va_arg(ap, int));
- break;
- case 'c':
- *sp = INT_TO_JSVAL((uint16) va_arg(ap, unsigned int));
- break;
- case 'i':
- case 'j':
- if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, int32), sp))
- goto bad;
- break;
- case 'u':
- if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, uint32), sp))
- goto bad;
- break;
- case 'd':
- case 'I':
- if (!js_NewDoubleValue(cx, va_arg(ap, jsdouble), sp))
- goto bad;
- break;
- case 's':
- str = JS_NewStringCopyZ(cx, va_arg(ap, char *));
- if (!str)
- goto bad;
- *sp = STRING_TO_JSVAL(str);
- break;
- case 'W':
- str = JS_NewUCStringCopyZ(cx, va_arg(ap, jschar *));
- if (!str)
- goto bad;
- *sp = STRING_TO_JSVAL(str);
- break;
- case 'S':
- str = va_arg(ap, JSString *);
- *sp = STRING_TO_JSVAL(str);
- break;
- case 'o':
- *sp = OBJECT_TO_JSVAL(va_arg(ap, JSObject *));
- break;
- case 'f':
- fun = va_arg(ap, JSFunction *);
- *sp = fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL;
- break;
- case 'v':
- *sp = va_arg(ap, jsval);
- break;
- default:
- format--;
- if (!TryArgumentFormatter(cx, &format, JS_FALSE, &sp,
- JS_ADDRESSOF_VA_LIST(ap))) {
- goto bad;
- }
- /* NB: the formatter already updated sp, so we continue here. */
- continue;
- }
- sp++;
- }
-
- /*
- * We may have overallocated stack due to a multi-character format code
- * handled by a JSArgumentFormatter. Give back that stack space!
- */
- JS_ASSERT(sp <= argv + argc);
- if (sp < argv + argc) {
- /* Return slots not pushed to the current stack arena. */
- cx->stackPool.current->avail = (jsuword)sp;
-
- /* Reduce the count of slots the GC will scan in this stack segment. */
- sh = cx->stackHeaders;
- JS_ASSERT(JS_STACK_SEGMENT(sh) + sh->nslots == argv + argc);
- sh->nslots -= argc - (sp - argv);
- }
- return argv;
-
-bad:
- js_FreeStack(cx, *markp);
- return NULL;
-}
-
-JS_PUBLIC_API(void)
-JS_PopArguments(JSContext *cx, void *mark)
-{
- CHECK_REQUEST(cx);
- js_FreeStack(cx, mark);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_AddArgumentFormatter(JSContext *cx, const char *format,
- JSArgumentFormatter formatter)
-{
- size_t length;
- JSArgumentFormatMap **mpp, *map;
-
- length = strlen(format);
- mpp = &cx->argumentFormatMap;
- while ((map = *mpp) != NULL) {
- /* Insert before any shorter string to match before prefixes. */
- if (map->length < length)
- break;
- if (map->length == length && !strcmp(map->format, format))
- goto out;
- mpp = &map->next;
- }
- map = (JSArgumentFormatMap *) JS_malloc(cx, sizeof *map);
- if (!map)
- return JS_FALSE;
- map->format = format;
- map->length = length;
- map->next = *mpp;
- *mpp = map;
-out:
- map->formatter = formatter;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(void)
-JS_RemoveArgumentFormatter(JSContext *cx, const char *format)
-{
- size_t length;
- JSArgumentFormatMap **mpp, *map;
-
- length = strlen(format);
- mpp = &cx->argumentFormatMap;
- while ((map = *mpp) != NULL) {
- if (map->length == length && !strcmp(map->format, format)) {
- *mpp = map->next;
- JS_free(cx, map);
- return;
- }
- mpp = &map->next;
- }
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
-{
- JSBool ok, b;
- JSObject *obj;
- JSFunction *fun;
- JSString *str;
- jsdouble d, *dp;
-
- CHECK_REQUEST(cx);
- switch (type) {
- case JSTYPE_VOID:
- *vp = JSVAL_VOID;
- ok = JS_TRUE;
- break;
- case JSTYPE_OBJECT:
- ok = js_ValueToObject(cx, v, &obj);
- if (ok)
- *vp = OBJECT_TO_JSVAL(obj);
- break;
- case JSTYPE_FUNCTION:
- fun = js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
- ok = (fun != NULL);
- if (ok)
- *vp = OBJECT_TO_JSVAL(fun->object);
- break;
- case JSTYPE_STRING:
- str = js_ValueToString(cx, v);
- ok = (str != NULL);
- if (ok)
- *vp = STRING_TO_JSVAL(str);
- break;
- case JSTYPE_NUMBER:
- ok = js_ValueToNumber(cx, v, &d);
- if (ok) {
- dp = js_NewDouble(cx, d);
- ok = (dp != NULL);
- if (ok)
- *vp = DOUBLE_TO_JSVAL(dp);
- }
- break;
- case JSTYPE_BOOLEAN:
- ok = js_ValueToBoolean(cx, v, &b);
- if (ok)
- *vp = BOOLEAN_TO_JSVAL(b);
- break;
- default: {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%d", (int)type);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_TYPE,
- numBuf);
- ok = JS_FALSE;
- break;
- }
- }
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
-{
- CHECK_REQUEST(cx);
- return js_ValueToObject(cx, v, objp);
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_ValueToFunction(JSContext *cx, jsval v)
-{
- CHECK_REQUEST(cx);
- return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_ValueToConstructor(JSContext *cx, jsval v)
-{
- CHECK_REQUEST(cx);
- return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_ValueToString(JSContext *cx, jsval v)
-{
- CHECK_REQUEST(cx);
- return js_ValueToString(cx, v);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
-{
- CHECK_REQUEST(cx);
- return js_ValueToNumber(cx, v, dp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
-{
- CHECK_REQUEST(cx);
- return js_ValueToECMAInt32(cx, v, ip);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
-{
- CHECK_REQUEST(cx);
- return js_ValueToECMAUint32(cx, v, ip);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
-{
- CHECK_REQUEST(cx);
- return js_ValueToInt32(cx, v, ip);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
-{
- CHECK_REQUEST(cx);
- return js_ValueToUint16(cx, v, ip);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
-{
- CHECK_REQUEST(cx);
- return js_ValueToBoolean(cx, v, bp);
-}
-
-JS_PUBLIC_API(JSType)
-JS_TypeOfValue(JSContext *cx, jsval v)
-{
- JSType type;
- JSObject *obj;
- JSObjectOps *ops;
- JSClass *clasp;
-
- CHECK_REQUEST(cx);
- if (JSVAL_IS_OBJECT(v)) {
- /* XXX JSVAL_IS_OBJECT(v) is true for null too! Can we change ECMA? */
- obj = JSVAL_TO_OBJECT(v);
- if (obj &&
- (ops = obj->map->ops,
- ops == &js_ObjectOps
- ? (clasp = OBJ_GET_CLASS(cx, obj),
- clasp->call || clasp == &js_FunctionClass)
- : ops->call != 0)) {
- type = JSTYPE_FUNCTION;
- } else {
- type = JSTYPE_OBJECT;
- }
- } else if (JSVAL_IS_NUMBER(v)) {
- type = JSTYPE_NUMBER;
- } else if (JSVAL_IS_STRING(v)) {
- type = JSTYPE_STRING;
- } else if (JSVAL_IS_BOOLEAN(v)) {
- type = JSTYPE_BOOLEAN;
- } else {
- type = JSTYPE_VOID;
- }
- return type;
-}
-
-JS_PUBLIC_API(const char *)
-JS_GetTypeName(JSContext *cx, JSType type)
-{
- if ((uintN)type >= (uintN)JSTYPE_LIMIT)
- return NULL;
- return js_type_str[type];
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(JSRuntime *)
-JS_NewRuntime(uint32 maxbytes)
-{
- JSRuntime *rt;
-
-#ifdef DEBUG
- JS_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) \
- JS_ASSERT(name == errorNumber++);
-#include "js.msg"
-#undef MSG_DEF
- JS_END_MACRO;
-#endif /* DEBUG */
-
- if (!js_InitScriptGlobals())
- return NULL;
- if (!js_InitStringGlobals())
- return NULL;
- rt = (JSRuntime *) malloc(sizeof(JSRuntime));
- if (!rt)
- return NULL;
-
- /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
- memset(rt, 0, sizeof(JSRuntime));
- JS_INIT_CLIST(&rt->contextList);
- JS_INIT_CLIST(&rt->trapList);
- JS_INIT_CLIST(&rt->watchPointList);
-
- if (!js_InitGC(rt, maxbytes))
- goto bad;
-#ifdef JS_THREADSAFE
- rt->gcLock = JS_NEW_LOCK();
- if (!rt->gcLock)
- goto bad;
- rt->gcDone = JS_NEW_CONDVAR(rt->gcLock);
- if (!rt->gcDone)
- goto bad;
- rt->requestDone = JS_NEW_CONDVAR(rt->gcLock);
- if (!rt->requestDone)
- goto bad;
- js_SetupLocks(8, 16); /* this is asymmetric with JS_ShutDown. */
- rt->rtLock = JS_NEW_LOCK();
- if (!rt->rtLock)
- goto bad;
- rt->stateChange = JS_NEW_CONDVAR(rt->gcLock);
- if (!rt->stateChange)
- goto bad;
- rt->setSlotLock = JS_NEW_LOCK();
- if (!rt->setSlotLock)
- goto bad;
- rt->setSlotDone = JS_NEW_CONDVAR(rt->setSlotLock);
- if (!rt->setSlotDone)
- goto bad;
- rt->scopeSharingDone = JS_NEW_CONDVAR(rt->gcLock);
- if (!rt->scopeSharingDone)
- goto bad;
- rt->scopeSharingTodo = NO_SCOPE_SHARING_TODO;
-#endif
- rt->propertyCache.empty = JS_TRUE;
- if (!js_InitPropertyTree(rt))
- goto bad;
- return rt;
-
-bad:
- JS_DestroyRuntime(rt);
- return NULL;
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyRuntime(JSRuntime *rt)
-{
-#ifdef DEBUG
- /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
- if (!JS_CLIST_IS_EMPTY(&rt->contextList)) {
- JSContext *cx, *iter = NULL;
- uintN cxcount = 0;
- while ((cx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL)
- cxcount++;
- fprintf(stderr,
-"JS API usage error: %u contexts left in runtime upon JS_DestroyRuntime.\n",
- cxcount);
- }
-#endif
-
- js_FinishAtomState(&rt->atomState);
- js_FinishGC(rt);
-#ifdef JS_THREADSAFE
- if (rt->gcLock)
- JS_DESTROY_LOCK(rt->gcLock);
- if (rt->gcDone)
- JS_DESTROY_CONDVAR(rt->gcDone);
- if (rt->requestDone)
- JS_DESTROY_CONDVAR(rt->requestDone);
- if (rt->rtLock)
- JS_DESTROY_LOCK(rt->rtLock);
- if (rt->stateChange)
- JS_DESTROY_CONDVAR(rt->stateChange);
- if (rt->setSlotLock)
- JS_DESTROY_LOCK(rt->setSlotLock);
- if (rt->setSlotDone)
- JS_DESTROY_CONDVAR(rt->setSlotDone);
- if (rt->scopeSharingDone)
- JS_DESTROY_CONDVAR(rt->scopeSharingDone);
-#endif
- js_FinishPropertyTree(rt);
- free(rt);
-}
-
-JS_PUBLIC_API(void)
-JS_ShutDown(void)
-{
- JS_ArenaShutDown();
- js_FinishDtoa();
- js_FreeScriptGlobals();
- js_FreeStringGlobals();
-#ifdef JS_THREADSAFE
- js_CleanupLocks();
-#endif
-}
-
-JS_PUBLIC_API(void *)
-JS_GetRuntimePrivate(JSRuntime *rt)
-{
- return rt->data;
-}
-
-JS_PUBLIC_API(void)
-JS_SetRuntimePrivate(JSRuntime *rt, void *data)
-{
- rt->data = data;
-}
-
-#ifdef JS_THREADSAFE
-
-JS_PUBLIC_API(void)
-JS_BeginRequest(JSContext *cx)
-{
- JSRuntime *rt;
-
- JS_ASSERT(cx->thread);
- if (!cx->requestDepth) {
- /* Wait until the GC is finished. */
- rt = cx->runtime;
- JS_LOCK_GC(rt);
-
- /* NB: we use cx->thread here, not js_CurrentThreadId(). */
- if (rt->gcThread != cx->thread) {
- while (rt->gcLevel > 0)
- JS_AWAIT_GC_DONE(rt);
- }
-
- /* Indicate that a request is running. */
- rt->requestCount++;
- cx->requestDepth = 1;
- JS_UNLOCK_GC(rt);
- return;
- }
- cx->requestDepth++;
-}
-
-JS_PUBLIC_API(void)
-JS_EndRequest(JSContext *cx)
-{
- JSRuntime *rt;
- JSScope *scope, **todop;
- uintN nshares;
-
- CHECK_REQUEST(cx);
- JS_ASSERT(cx->requestDepth > 0);
- if (cx->requestDepth == 1) {
- /* Lock before clearing to interlock with ClaimScope, in jslock.c. */
- rt = cx->runtime;
- JS_LOCK_GC(rt);
- cx->requestDepth = 0;
-
- /* See whether cx has any single-threaded scopes to start sharing. */
- todop = &rt->scopeSharingTodo;
- nshares = 0;
- while ((scope = *todop) != NO_SCOPE_SHARING_TODO) {
- if (scope->ownercx != cx) {
- todop = &scope->u.link;
- continue;
- }
- *todop = scope->u.link;
- scope->u.link = NULL; /* null u.link for sanity ASAP */
-
- /*
- * If js_DropObjectMap returns null, we held the last ref to scope.
- * The waiting thread(s) must have been killed, after which the GC
- * collected the object that held this scope. Unlikely, because it
- * requires that the GC ran (e.g., from a branch callback) during
- * this request, but possible.
- */
- if (js_DropObjectMap(cx, &scope->map, NULL)) {
- js_InitLock(&scope->lock);
- scope->u.count = 0; /* NULL may not pun as 0 */
- js_FinishSharingScope(rt, scope); /* set ownercx = NULL */
- nshares++;
- }
- }
- if (nshares)
- JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone);
-
- /* Give the GC a chance to run if this was the last request running. */
- JS_ASSERT(rt->requestCount > 0);
- rt->requestCount--;
- if (rt->requestCount == 0)
- JS_NOTIFY_REQUEST_DONE(rt);
-
- JS_UNLOCK_GC(rt);
- return;
- }
-
- cx->requestDepth--;
-}
-
-/* Yield to pending GC operations, regardless of request depth */
-JS_PUBLIC_API(void)
-JS_YieldRequest(JSContext *cx)
-{
- JSRuntime *rt;
-
- JS_ASSERT(cx->thread);
- CHECK_REQUEST(cx);
-
- rt = cx->runtime;
- JS_LOCK_GC(rt);
- JS_ASSERT(rt->requestCount > 0);
- rt->requestCount--;
- if (rt->requestCount == 0)
- JS_NOTIFY_REQUEST_DONE(rt);
- JS_UNLOCK_GC(rt);
- /* XXXbe give the GC or another request calling it a chance to run here?
- Assumes FIFO scheduling */
- JS_LOCK_GC(rt);
- rt->requestCount++;
- JS_UNLOCK_GC(rt);
-}
-
-JS_PUBLIC_API(jsrefcount)
-JS_SuspendRequest(JSContext *cx)
-{
- jsrefcount saveDepth = cx->requestDepth;
-
- while (cx->requestDepth)
- JS_EndRequest(cx);
- return saveDepth;
-}
-
-JS_PUBLIC_API(void)
-JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth)
-{
- JS_ASSERT(!cx->requestDepth);
- while (--saveDepth >= 0)
- JS_BeginRequest(cx);
-}
-
-#endif /* JS_THREADSAFE */
-
-JS_PUBLIC_API(void)
-JS_Lock(JSRuntime *rt)
-{
- JS_LOCK_RUNTIME(rt);
-}
-
-JS_PUBLIC_API(void)
-JS_Unlock(JSRuntime *rt)
-{
- JS_UNLOCK_RUNTIME(rt);
-}
-
-JS_PUBLIC_API(JSContext *)
-JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
-{
- return js_NewContext(rt, stackChunkSize);
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyContext(JSContext *cx)
-{
- js_DestroyContext(cx, JS_FORCE_GC);
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyContextNoGC(JSContext *cx)
-{
- js_DestroyContext(cx, JS_NO_GC);
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyContextMaybeGC(JSContext *cx)
-{
- js_DestroyContext(cx, JS_MAYBE_GC);
-}
-
-JS_PUBLIC_API(void *)
-JS_GetContextPrivate(JSContext *cx)
-{
- return cx->data;
-}
-
-JS_PUBLIC_API(void)
-JS_SetContextPrivate(JSContext *cx, void *data)
-{
- cx->data = data;
-}
-
-JS_PUBLIC_API(JSRuntime *)
-JS_GetRuntime(JSContext *cx)
-{
- return cx->runtime;
-}
-
-JS_PUBLIC_API(JSContext *)
-JS_ContextIterator(JSRuntime *rt, JSContext **iterp)
-{
- return js_ContextIterator(rt, JS_TRUE, iterp);
-}
-
-JS_PUBLIC_API(JSVersion)
-JS_GetVersion(JSContext *cx)
-{
- return cx->version;
-}
-
-JS_PUBLIC_API(JSVersion)
-JS_SetVersion(JSContext *cx, JSVersion version)
-{
- JSVersion oldVersion;
-
- oldVersion = cx->version;
- if (version == oldVersion)
- return oldVersion;
-
- cx->version = version;
-
-#if !JS_BUG_FALLIBLE_EQOPS
- if (cx->version == JSVERSION_1_2) {
- cx->jsop_eq = JSOP_NEW_EQ;
- cx->jsop_ne = JSOP_NEW_NE;
- } else {
- cx->jsop_eq = JSOP_EQ;
- cx->jsop_ne = JSOP_NE;
- }
-#endif /* !JS_BUG_FALLIBLE_EQOPS */
-
- return oldVersion;
-}
-
-static struct v2smap {
- JSVersion version;
- const char *string;
-} v2smap[] = {
- {JSVERSION_1_0, "1.0"},
- {JSVERSION_1_1, "1.1"},
- {JSVERSION_1_2, "1.2"},
- {JSVERSION_1_3, "1.3"},
- {JSVERSION_1_4, "1.4"},
- {JSVERSION_ECMA_3, "ECMAv3"},
- {JSVERSION_1_5, "1.5"},
- {JSVERSION_DEFAULT, "default"},
- {JSVERSION_UNKNOWN, NULL}, /* must be last, NULL is sentinel */
-};
-
-JS_PUBLIC_API(const char *)
-JS_VersionToString(JSVersion version)
-{
- int i;
-
- for (i = 0; v2smap[i].string; i++)
- if (v2smap[i].version == version)
- return v2smap[i].string;
- return "unknown";
-}
-
-JS_PUBLIC_API(JSVersion)
-JS_StringToVersion(const char *string)
-{
- int i;
-
- for (i = 0; v2smap[i].string; i++)
- if (strcmp(v2smap[i].string, string) == 0)
- return v2smap[i].version;
- return JSVERSION_UNKNOWN;
-}
-
-JS_PUBLIC_API(uint32)
-JS_GetOptions(JSContext *cx)
-{
- return cx->options;
-}
-
-JS_PUBLIC_API(uint32)
-JS_SetOptions(JSContext *cx, uint32 options)
-{
- uint32 oldopts = cx->options;
- cx->options = options;
- return oldopts;
-}
-
-JS_PUBLIC_API(uint32)
-JS_ToggleOptions(JSContext *cx, uint32 options)
-{
- uint32 oldopts = cx->options;
- cx->options ^= options;
- return oldopts;
-}
-
-JS_PUBLIC_API(const char *)
-JS_GetImplementationVersion(void)
-{
- return "JavaScript-C 1.5 pre-release 6 2004-01-27";
-}
-
-
-JS_PUBLIC_API(JSObject *)
-JS_GetGlobalObject(JSContext *cx)
-{
- return cx->globalObject;
-}
-
-JS_PUBLIC_API(void)
-JS_SetGlobalObject(JSContext *cx, JSObject *obj)
-{
- cx->globalObject = obj;
-}
-
-static JSObject *
-InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj)
-{
- JSDHashTable *table;
- JSBool resolving;
- JSRuntime *rt;
- JSResolvingKey key;
- JSResolvingEntry *entry;
- JSObject *fun_proto, *obj_proto;
-
- /* If cx has no global object, use obj so prototypes can be found. */
- if (!cx->globalObject)
- cx->globalObject = obj;
-
- /* Record Function and Object in cx->resolvingTable, if we are resolving. */
- table = cx->resolvingTable;
- resolving = (table && table->entryCount);
- if (resolving) {
- rt = cx->runtime;
- key.obj = obj;
- key.id = (jsid) rt->atomState.FunctionAtom;
- entry = (JSResolvingEntry *)
- JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
- if (entry && entry->key.obj && (entry->flags & JSRESFLAG_LOOKUP)) {
- /* Already resolving Function, record Object too. */
- JS_ASSERT(entry->key.obj == obj);
- key.id = (jsid) rt->atomState.ObjectAtom;
- entry = (JSResolvingEntry *)
- JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
- }
- if (!entry) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- JS_ASSERT(!entry->key.obj && entry->flags == 0);
- entry->key = key;
- entry->flags = JSRESFLAG_LOOKUP;
- }
-
- /* Initialize the function class first so constructors can be made. */
- fun_proto = js_InitFunctionClass(cx, obj);
- if (!fun_proto)
- goto out;
-
- /* Initialize the object class next so Object.prototype works. */
- obj_proto = js_InitObjectClass(cx, obj);
- if (!obj_proto) {
- fun_proto = NULL;
- goto out;
- }
-
- /* Function.prototype and the global object delegate to Object.prototype. */
- OBJ_SET_PROTO(cx, fun_proto, obj_proto);
- if (!OBJ_GET_PROTO(cx, obj))
- OBJ_SET_PROTO(cx, obj, obj_proto);
-
-out:
- /* If resolving, remove the other entry (Object or Function) from table. */
- if (resolving)
- JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE);
- return fun_proto;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_InitStandardClasses(JSContext *cx, JSObject *obj)
-{
- CHECK_REQUEST(cx);
-
-#if JS_HAS_UNDEFINED
-{
- /* Define a top-level property 'undefined' with the undefined value. */
- JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
- if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
- JSPROP_PERMANENT, NULL)) {
- return JS_FALSE;
- }
-}
-#endif
-
- /* Function and Object require cooperative bootstrapping magic. */
- if (!InitFunctionAndObjectClasses(cx, obj))
- return JS_FALSE;
-
- /* Initialize the rest of the standard objects and functions. */
- return js_InitArrayClass(cx, obj) &&
- js_InitBooleanClass(cx, obj) &&
- js_InitMathClass(cx, obj) &&
- js_InitNumberClass(cx, obj) &&
- js_InitStringClass(cx, obj) &&
-#if JS_HAS_CALL_OBJECT
- js_InitCallClass(cx, obj) &&
-#endif
-#if JS_HAS_REGEXPS
- js_InitRegExpClass(cx, obj) &&
-#endif
-#if JS_HAS_SCRIPT_OBJECT
- js_InitScriptClass(cx, obj) &&
-#endif
-#if JS_HAS_ERROR_EXCEPTIONS
- js_InitExceptionClasses(cx, obj) &&
-#endif
-#if JS_HAS_FILE_OBJECT
- js_InitFileClass(cx, obj, JS_TRUE) &&
-#endif
- js_InitDateClass(cx, obj);
-}
-
-#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
-#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
-
-/*
- * Table of class initializers and their atom offsets in rt->atomState.
- * If you add a "standard" class, remember to update this table.
- */
-static struct {
- JSObjectOp init;
- size_t atomOffset;
-} standard_class_atoms[] = {
- {InitFunctionAndObjectClasses, ATOM_OFFSET(Function)},
- {InitFunctionAndObjectClasses, ATOM_OFFSET(Object)},
- {js_InitArrayClass, ATOM_OFFSET(Array)},
- {js_InitBooleanClass, ATOM_OFFSET(Boolean)},
- {js_InitDateClass, ATOM_OFFSET(Date)},
- {js_InitMathClass, ATOM_OFFSET(Math)},
- {js_InitNumberClass, ATOM_OFFSET(Number)},
- {js_InitStringClass, ATOM_OFFSET(String)},
-#if JS_HAS_CALL_OBJECT
- {js_InitCallClass, ATOM_OFFSET(Call)},
-#endif
-#if JS_HAS_ERROR_EXCEPTIONS
- {js_InitExceptionClasses, ATOM_OFFSET(Error)},
-#endif
-#if JS_HAS_REGEXPS
- {js_InitRegExpClass, ATOM_OFFSET(RegExp)},
-#endif
-#if JS_HAS_SCRIPT_OBJECT
- {js_InitScriptClass, ATOM_OFFSET(Script)},
-#endif
- {NULL, 0}
-};
-
-/*
- * Table of top-level function and constant names and their init functions.
- * If you add a "standard" global function or property, remember to update
- * this table.
- */
-typedef struct JSStdName {
- JSObjectOp init;
- size_t atomOffset; /* offset of atom pointer in JSAtomState */
- const char *name; /* null if atom is pre-pinned, else name */
-} JSStdName;
-
-static JSAtom *
-StdNameToAtom(JSContext *cx, JSStdName *stdn)
-{
- size_t offset;
- JSAtom *atom;
- const char *name;
-
- offset = stdn->atomOffset;
- atom = OFFSET_TO_ATOM(cx->runtime, offset);
- if (!atom) {
- name = stdn->name;
- if (name) {
- atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED);
- OFFSET_TO_ATOM(cx->runtime, offset) = atom;
- }
- }
- return atom;
-}
-
-#define EAGERLY_PINNED_ATOM(name) ATOM_OFFSET(name), NULL
-#define LAZILY_PINNED_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_str
-
-static JSStdName standard_class_names[] = {
- /* ECMA requires that eval be a direct property of the global object. */
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(eval)},
-
- /* Global properties and functions defined by the Number class. */
- {js_InitNumberClass, LAZILY_PINNED_ATOM(NaN)},
- {js_InitNumberClass, LAZILY_PINNED_ATOM(Infinity)},
- {js_InitNumberClass, LAZILY_PINNED_ATOM(isNaN)},
- {js_InitNumberClass, LAZILY_PINNED_ATOM(isFinite)},
- {js_InitNumberClass, LAZILY_PINNED_ATOM(parseFloat)},
- {js_InitNumberClass, LAZILY_PINNED_ATOM(parseInt)},
-
- /* String global functions. */
- {js_InitStringClass, LAZILY_PINNED_ATOM(escape)},
- {js_InitStringClass, LAZILY_PINNED_ATOM(unescape)},
- {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURI)},
- {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURI)},
- {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURIComponent)},
- {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURIComponent)},
-#if JS_HAS_UNEVAL
- {js_InitStringClass, LAZILY_PINNED_ATOM(uneval)},
-#endif
-
- /* Exception constructors. */
-#if JS_HAS_ERROR_EXCEPTIONS
- {js_InitExceptionClasses, EAGERLY_PINNED_ATOM(Error)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(InternalError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(EvalError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(RangeError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(ReferenceError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(SyntaxError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(TypeError)},
- {js_InitExceptionClasses, LAZILY_PINNED_ATOM(URIError)},
-#endif
-
- {NULL, 0, NULL}
-};
-
-static JSStdName object_prototype_names[] = {
- /* Object.prototype properties (global delegates to Object.prototype). */
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(proto)},
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(parent)},
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(count)},
-#if JS_HAS_TOSOURCE
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(toSource)},
-#endif
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(toString)},
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(toLocaleString)},
- {js_InitObjectClass, EAGERLY_PINNED_ATOM(valueOf)},
-#if JS_HAS_OBJ_WATCHPOINT
- {js_InitObjectClass, LAZILY_PINNED_ATOM(watch)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(unwatch)},
-#endif
-#if JS_HAS_NEW_OBJ_METHODS
- {js_InitObjectClass, LAZILY_PINNED_ATOM(hasOwnProperty)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(isPrototypeOf)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(propertyIsEnumerable)},
-#endif
-#if JS_HAS_GETTER_SETTER
- {js_InitObjectClass, LAZILY_PINNED_ATOM(defineGetter)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(defineSetter)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupGetter)},
- {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupSetter)},
-#endif
-
- {NULL, 0, NULL}
-};
-
-#undef EAGERLY_PINNED_ATOM
-#undef LAZILY_PINNED_ATOM
-
-JS_PUBLIC_API(JSBool)
-JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
- JSBool *resolved)
-{
- JSString *idstr;
- JSRuntime *rt;
- JSAtom *atom;
- JSObjectOp init;
- uintN i;
-
- CHECK_REQUEST(cx);
- *resolved = JS_FALSE;
-
- if (!JSVAL_IS_STRING(id))
- return JS_TRUE;
- idstr = JSVAL_TO_STRING(id);
- rt = cx->runtime;
-
-#if JS_HAS_UNDEFINED
- /* See if we're resolving 'undefined', and define it if so. */
- atom = rt->atomState.typeAtoms[JSTYPE_VOID];
- if (idstr == ATOM_TO_STRING(atom)) {
- *resolved = JS_TRUE;
- return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
- JSPROP_PERMANENT, NULL);
- }
-#endif
-
- /* Try for class constructors/prototypes named by well-known atoms. */
- init = NULL;
- for (i = 0; standard_class_atoms[i].init; i++) {
- atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
- if (idstr == ATOM_TO_STRING(atom)) {
- init = standard_class_atoms[i].init;
- break;
- }
- }
-
- if (!init) {
- /* Try less frequently used top-level functions and constants. */
- for (i = 0; standard_class_names[i].init; i++) {
- atom = StdNameToAtom(cx, &standard_class_names[i]);
- if (!atom)
- return JS_FALSE;
- if (idstr == ATOM_TO_STRING(atom)) {
- init = standard_class_names[i].init;
- break;
- }
- }
-
- if (!init && !OBJ_GET_PROTO(cx, obj)) {
- /*
- * Try even less frequently used names delegated from the global
- * object to Object.prototype, but only if the Object class hasn't
- * yet been initialized.
- */
- for (i = 0; object_prototype_names[i].init; i++) {
- atom = StdNameToAtom(cx, &object_prototype_names[i]);
- if (!atom)
- return JS_FALSE;
- if (idstr == ATOM_TO_STRING(atom)) {
- init = standard_class_names[i].init;
- break;
- }
- }
- }
- }
-
- if (init) {
- if (!init(cx, obj))
- return JS_FALSE;
- *resolved = JS_TRUE;
- }
- return JS_TRUE;
-}
-
-static JSBool
-HasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom, JSBool *ownp)
-{
- JSObject *pobj;
- JSProperty *prop;
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop))
- return JS_FALSE;
- if (prop)
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- *ownp = (pobj == obj && prop);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
-{
- JSRuntime *rt;
- JSAtom *atom;
- JSBool found;
- uintN i;
-
- CHECK_REQUEST(cx);
- rt = cx->runtime;
-
-#if JS_HAS_UNDEFINED
- /* See if we need to bind 'undefined' and define it if so. */
- atom = rt->atomState.typeAtoms[JSTYPE_VOID];
- if (!HasOwnProperty(cx, obj, atom, &found))
- return JS_FALSE;
- if (!found &&
- !OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
- JSPROP_PERMANENT, NULL)) {
- return JS_FALSE;
- }
-#endif
-
- /* Initialize any classes that have not been resolved yet. */
- for (i = 0; standard_class_atoms[i].init; i++) {
- atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
- if (!HasOwnProperty(cx, obj, atom, &found))
- return JS_FALSE;
- if (!found && !standard_class_atoms[i].init(cx, obj))
- return JS_FALSE;
- }
-
- return JS_TRUE;
-}
-
-#undef ATOM_OFFSET
-#undef OFFSET_TO_ATOM
-
-JS_PUBLIC_API(JSObject *)
-JS_GetScopeChain(JSContext *cx)
-{
- return cx->fp ? cx->fp->scopeChain : NULL;
-}
-
-JS_PUBLIC_API(void *)
-JS_malloc(JSContext *cx, size_t nbytes)
-{
- void *p;
-
- JS_ASSERT(nbytes != 0);
- if (nbytes == 0)
- nbytes = 1;
- cx->runtime->gcMallocBytes += nbytes;
- p = malloc(nbytes);
- if (!p)
- JS_ReportOutOfMemory(cx);
- return p;
-}
-
-JS_PUBLIC_API(void *)
-JS_realloc(JSContext *cx, void *p, size_t nbytes)
-{
- p = realloc(p, nbytes);
- if (!p)
- JS_ReportOutOfMemory(cx);
- return p;
-}
-
-JS_PUBLIC_API(void)
-JS_free(JSContext *cx, void *p)
-{
- if (p)
- free(p);
-}
-
-JS_PUBLIC_API(char *)
-JS_strdup(JSContext *cx, const char *s)
-{
- size_t n;
- void *p;
-
- n = strlen(s) + 1;
- p = JS_malloc(cx, n);
- if (!p)
- return NULL;
- return (char *)memcpy(p, s, n);
-}
-
-JS_PUBLIC_API(jsdouble *)
-JS_NewDouble(JSContext *cx, jsdouble d)
-{
- CHECK_REQUEST(cx);
- return js_NewDouble(cx, d);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
-{
- CHECK_REQUEST(cx);
- return js_NewDoubleValue(cx, d, rval);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
-{
- CHECK_REQUEST(cx);
- return js_NewNumberValue(cx, d, rval);
-}
-
-#undef JS_AddRoot
-JS_PUBLIC_API(JSBool)
-JS_AddRoot(JSContext *cx, void *rp)
-{
- CHECK_REQUEST(cx);
- return js_AddRoot(cx, rp, NULL);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name)
-{
- return js_AddRootRT(rt, rp, name);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_RemoveRoot(JSContext *cx, void *rp)
-{
- CHECK_REQUEST(cx);
- return js_RemoveRoot(cx->runtime, rp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_RemoveRootRT(JSRuntime *rt, void *rp)
-{
- return js_RemoveRoot(rt, rp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_AddNamedRoot(JSContext *cx, void *rp, const char *name)
-{
- CHECK_REQUEST(cx);
- return js_AddRoot(cx, rp, name);
-}
-
-JS_PUBLIC_API(void)
-JS_ClearNewbornRoots(JSContext *cx)
-{
- uintN i;
-
- for (i = 0; i < GCX_NTYPES; i++)
- cx->newborn[i] = NULL;
- cx->lastAtom = NULL;
-}
-
-#include "jshash.h" /* Added by JSIFY */
-
-#ifdef DEBUG
-
-typedef struct NamedRootDumpArgs {
- void (*dump)(const char *name, void *rp, void *data);
- void *data;
-} NamedRootDumpArgs;
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-js_named_root_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
- void *arg)
-{
- NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg;
- JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
-
- if (rhe->name)
- args->dump(rhe->name, rhe->root, args->data);
- return JS_DHASH_NEXT;
-}
-
-JS_PUBLIC_API(void)
-JS_DumpNamedRoots(JSRuntime *rt,
- void (*dump)(const char *name, void *rp, void *data),
- void *data)
-{
- NamedRootDumpArgs args;
-
- args.dump = dump;
- args.data = data;
- JS_DHashTableEnumerate(&rt->gcRootsHash, js_named_root_dumper, &args);
-}
-
-#endif /* DEBUG */
-
-typedef struct GCRootMapArgs {
- JSGCRootMapFun map;
- void *data;
-} GCRootMapArgs;
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-js_gcroot_mapper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
- void *arg)
-{
- GCRootMapArgs *args = (GCRootMapArgs *) arg;
- JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
- intN mapflags;
- JSDHashOperator op;
-
- mapflags = args->map(rhe->root, rhe->name, args->data);
-
-#if JS_MAP_GCROOT_NEXT == JS_DHASH_NEXT && \
- JS_MAP_GCROOT_STOP == JS_DHASH_STOP && \
- JS_MAP_GCROOT_REMOVE == JS_DHASH_REMOVE
- op = (JSDHashOperator)mapflags;
-#else
- op = JS_DHASH_NEXT;
- if (mapflags & JS_MAP_GCROOT_STOP)
- op |= JS_DHASH_STOP;
- if (mapflags & JS_MAP_GCROOT_REMOVE)
- op |= JS_DHASH_REMOVE;
-#endif
-
- return op;
-}
-
-JS_PUBLIC_API(uint32)
-JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data)
-{
- GCRootMapArgs args;
- uint32 rv;
-
- args.map = map;
- args.data = data;
- JS_LOCK_GC(rt);
- rv = JS_DHashTableEnumerate(&rt->gcRootsHash, js_gcroot_mapper, &args);
- JS_UNLOCK_GC(rt);
- return rv;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_LockGCThing(JSContext *cx, void *thing)
-{
- JSBool ok;
-
- CHECK_REQUEST(cx);
- ok = js_LockGCThing(cx, thing);
- if (!ok)
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_LOCK);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_LockGCThingRT(JSRuntime *rt, void *thing)
-{
- return js_LockGCThingRT(rt, thing);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_UnlockGCThing(JSContext *cx, void *thing)
-{
- JSBool ok;
-
- CHECK_REQUEST(cx);
- ok = js_UnlockGCThingRT(cx->runtime, thing);
- if (!ok)
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_UNLOCK);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_UnlockGCThingRT(JSRuntime *rt, void *thing)
-{
- return js_UnlockGCThingRT(rt, thing);
-}
-
-JS_PUBLIC_API(void)
-JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg)
-{
- JS_ASSERT(cx->runtime->gcLevel > 0);
-#ifdef JS_THREADSAFE
- JS_ASSERT(cx->runtime->gcThread == js_CurrentThreadId());
-#endif
-
- GC_MARK(cx, thing, name, arg);
-}
-
-JS_PUBLIC_API(void)
-JS_GC(JSContext *cx)
-{
- /* Don't nuke active arenas if executing or compiling. */
- if (cx->stackPool.current == &cx->stackPool.first)
- JS_FinishArenaPool(&cx->stackPool);
- if (cx->tempPool.current == &cx->tempPool.first)
- JS_FinishArenaPool(&cx->tempPool);
- js_ForceGC(cx, 0);
-}
-
-JS_PUBLIC_API(void)
-JS_MaybeGC(JSContext *cx)
-{
- JSRuntime *rt;
- uint32 bytes, lastBytes;
-
- rt = cx->runtime;
- bytes = rt->gcBytes;
- lastBytes = rt->gcLastBytes;
- if ((bytes > 8192 && bytes > lastBytes + lastBytes / 2) ||
- rt->gcMallocBytes > rt->gcMaxBytes) {
- /*
- * Run the GC if we have half again as many bytes of GC-things as
- * the last time we GC'd, or if we have malloc'd more bytes through
- * JS_malloc than we were told to allocate by JS_NewRuntime.
- */
- JS_GC(cx);
- }
-}
-
-JS_PUBLIC_API(JSGCCallback)
-JS_SetGCCallback(JSContext *cx, JSGCCallback cb)
-{
- return JS_SetGCCallbackRT(cx->runtime, cb);
-}
-
-JS_PUBLIC_API(JSGCCallback)
-JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb)
-{
- JSGCCallback oldcb;
-
- oldcb = rt->gcCallback;
- rt->gcCallback = cb;
- return oldcb;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsAboutToBeFinalized(JSContext *cx, void *thing)
-{
- JS_ASSERT(thing);
- return js_IsAboutToBeFinalized(cx, thing);
-}
-
-JS_PUBLIC_API(intN)
-JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer)
-{
- return js_ChangeExternalStringFinalizer(NULL, finalizer);
-}
-
-JS_PUBLIC_API(intN)
-JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer)
-{
- return js_ChangeExternalStringFinalizer(finalizer, NULL);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
-{
- JSString *str;
-
- CHECK_REQUEST(cx);
- JS_ASSERT(GCX_EXTERNAL_STRING <= type && type < (intN) GCX_NTYPES);
-
- str = (JSString *) js_AllocGCThing(cx, (uintN) type);
- if (!str)
- return NULL;
- str->length = length;
- str->chars = chars;
- return str;
-}
-
-JS_PUBLIC_API(intN)
-JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)
-{
- uint8 type = (uint8) (*js_GetGCThingFlags(str) & GCF_TYPEMASK);
-
- if (type >= GCX_EXTERNAL_STRING)
- return (intN)type;
- JS_ASSERT(type == GCX_STRING || type == GCX_MUTABLE_STRING);
- return -1;
-}
-
-#ifdef DEBUG
-static void
-CheckStackGrowthDirection(int *dummy1addr, jsuword limitAddr)
-{
- int dummy2;
-
-#if JS_STACK_GROWTH_DIRECTION > 0
- JS_ASSERT(dummy1addr < &dummy2);
- JS_ASSERT((jsuword)&dummy2 < limitAddr);
-#else
- /* Stack grows downward, the common case on modern architectures. */
- JS_ASSERT(&dummy2 < dummy1addr);
- JS_ASSERT(limitAddr < (jsuword)&dummy2);
-#endif
-}
-#endif
-
-JS_PUBLIC_API(void)
-JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr)
-{
-#ifdef DEBUG
- int dummy1;
-
- CheckStackGrowthDirection(&dummy1, limitAddr);
-#endif
-
-#if JS_STACK_GROWTH_DIRECTION > 0
- if (limitAddr == 0)
- limitAddr = (jsuword)-1;
-#endif
- cx->stackLimit = limitAddr;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(void)
-JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
-{
- JS_free(cx, ida);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ValueToId(JSContext *cx, jsval v, jsid *idp)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- if (JSVAL_IS_INT(v)) {
- *idp = v;
- } else {
- atom = js_ValueToStringAtom(cx, v);
- if (!atom)
- return JS_FALSE;
- *idp = (jsid)atom;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IdToValue(JSContext *cx, jsid id, jsval *vp)
-{
- CHECK_REQUEST(cx);
- *vp = ID_TO_VALUE(id);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EnumerateStub(JSContext *cx, JSObject *obj)
-{
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id)
-{
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
-{
-#if JS_BUG_EAGER_TOSTRING
- if (type == JSTYPE_STRING)
- return JS_TRUE;
-#endif
- return js_TryValueOf(cx, obj, type, vp);
-}
-
-JS_PUBLIC_API(void)
-JS_FinalizeStub(JSContext *cx, JSObject *obj)
-{
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
- JSClass *clasp, JSNative constructor, uintN nargs,
- JSPropertySpec *ps, JSFunctionSpec *fs,
- JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
-{
- JSAtom *atom;
- JSObject *proto, *ctor;
- JSBool named;
- JSFunction *fun;
- jsval junk;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
- if (!atom)
- return NULL;
-
- /* Create a prototype object for this class. */
- proto = js_NewObject(cx, clasp, parent_proto, obj);
- if (!proto)
- return NULL;
-
- if (!constructor) {
- /* Lacking a constructor, name the prototype (e.g., Math). */
- named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto),
- NULL, NULL, 0, NULL);
- if (!named)
- goto bad;
- ctor = proto;
- } else {
- /* Define the constructor function in obj's scope. */
- fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
- named = (fun != NULL);
- if (!fun)
- goto bad;
-
- /*
- * Remember the class this function is a constructor for so that
- * we know to create an object of this class when we call the
- * constructor.
- */
- fun->clasp = clasp;
-
- /* Connect constructor and prototype by named properties. */
- ctor = fun->object;
- if (!js_SetClassPrototype(cx, ctor, proto,
- JSPROP_READONLY | JSPROP_PERMANENT)) {
- goto bad;
- }
-
- /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
- if (OBJ_GET_CLASS(cx, ctor) == clasp) {
- /* XXXMLM - this fails in framesets that are writing over
- * themselves!
- * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor));
- */
- OBJ_SET_PROTO(cx, ctor, proto);
- }
- }
-
- /* Add properties and methods to the prototype and the constructor. */
- if ((ps && !JS_DefineProperties(cx, proto, ps)) ||
- (fs && !JS_DefineFunctions(cx, proto, fs)) ||
- (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) ||
- (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) {
- goto bad;
- }
- return proto;
-
-bad:
- if (named)
- (void) OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, &junk);
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
-}
-
-#ifdef JS_THREADSAFE
-JS_PUBLIC_API(JSClass *)
-JS_GetClass(JSContext *cx, JSObject *obj)
-{
- return (JSClass *)
- JSVAL_TO_PRIVATE(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_CLASS));
-}
-#else
-JS_PUBLIC_API(JSClass *)
-JS_GetClass(JSObject *obj)
-{
- return LOCKED_OBJ_GET_CLASS(obj);
-}
-#endif
-
-JS_PUBLIC_API(JSBool)
-JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
-{
- JSFunction *fun;
-
- CHECK_REQUEST(cx);
- if (OBJ_GET_CLASS(cx, obj) == clasp)
- return JS_TRUE;
- if (argv) {
- fun = js_ValueToFunction(cx, &argv[-2], 0);
- if (fun) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_INCOMPATIBLE_PROTO,
- clasp->name, JS_GetFunctionName(fun),
- OBJ_GET_CLASS(cx, obj)->name);
- }
- }
- return JS_FALSE;
-}
-
-JS_PUBLIC_API(void *)
-JS_GetPrivate(JSContext *cx, JSObject *obj)
-{
- jsval v;
-
- JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
- v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (!JSVAL_IS_INT(v))
- return NULL;
- return JSVAL_TO_PRIVATE(v);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)
-{
- JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data));
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(void *)
-JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
- jsval *argv)
-{
- if (!JS_InstanceOf(cx, obj, clasp, argv))
- return NULL;
- return JS_GetPrivate(cx, obj);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetPrototype(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
-
- CHECK_REQUEST(cx);
- proto = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PROTO));
-
- /* Beware ref to dead object (we may be called from obj's finalizer). */
- return proto && proto->map ? proto : NULL;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
-{
- CHECK_REQUEST(cx);
- if (obj->map->ops->setProto)
- return obj->map->ops->setProto(cx, obj, JSSLOT_PROTO, proto);
- OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto));
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetParent(JSContext *cx, JSObject *obj)
-{
- JSObject *parent;
-
- parent = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PARENT));
-
- /* Beware ref to dead object (we may be called from obj's finalizer). */
- return parent && parent->map ? parent : NULL;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
-{
- CHECK_REQUEST(cx);
- if (obj->map->ops->setParent)
- return obj->map->ops->setParent(cx, obj, JSSLOT_PARENT, parent);
- OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent));
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetConstructor(JSContext *cx, JSObject *proto)
-{
- jsval cval;
-
- CHECK_REQUEST(cx);
- if (!OBJ_GET_PROPERTY(cx, proto,
- (jsid)cx->runtime->atomState.constructorAtom,
- &cval)) {
- return NULL;
- }
- if (!JSVAL_IS_FUNCTION(cx, cval)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,
- OBJ_GET_CLASS(cx, proto)->name);
- return NULL;
- }
- return JSVAL_TO_OBJECT(cval);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
-{
- *idp = (jsid) obj;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
-{
- CHECK_REQUEST(cx);
- if (!clasp)
- clasp = &js_ObjectClass; /* default class is Object */
- return js_NewObject(cx, clasp, proto, parent);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep)
-{
- JSScope *scope;
- JSIdArray *ida;
- uint32 nslots;
- jsval v, *vp, *end;
-
- if (!OBJ_IS_NATIVE(obj)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_SEAL_OBJECT,
- OBJ_GET_CLASS(cx, obj)->name);
- return JS_FALSE;
- }
-
- scope = OBJ_SCOPE(obj);
-
-#if defined JS_THREADSAFE && defined DEBUG
- /* Insist on scope being used exclusively by cx's thread. */
- if (scope->ownercx != cx) {
- JS_LOCK_OBJ(cx, obj);
- JS_ASSERT(OBJ_SCOPE(obj) == scope);
- JS_ASSERT(scope->ownercx == cx);
- JS_UNLOCK_SCOPE(cx, scope);
- }
-#endif
-
- /* Nothing to do if obj's scope is already sealed. */
- if (SCOPE_IS_SEALED(scope))
- return JS_TRUE;
-
- /* XXX Enumerate lazy properties now, as they can't be added later. */
- ida = JS_Enumerate(cx, obj);
- if (!ida)
- return JS_FALSE;
- JS_DestroyIdArray(cx, ida);
-
- /* Ensure that obj has its own, mutable scope, and seal that scope. */
- JS_LOCK_OBJ(cx, obj);
- scope = js_GetMutableScope(cx, obj);
- if (scope)
- SCOPE_SET_SEALED(scope);
- JS_UNLOCK_SCOPE(cx, scope);
- if (!scope)
- return JS_FALSE;
-
- /* If we are not sealing an entire object graph, we're done. */
- if (!deep)
- return JS_TRUE;
-
- /* Walk obj->slots and if any value is a non-null object, seal it. */
- nslots = JS_MIN(scope->map.freeslot, scope->map.nslots);
- for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
- v = *vp;
- if (JSVAL_IS_PRIMITIVE(v))
- continue;
- if (!JS_SealObject(cx, JSVAL_TO_OBJECT(v), deep))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent)
-{
- CHECK_REQUEST(cx);
- if (!clasp)
- clasp = &js_ObjectClass; /* default class is Object */
- return js_ConstructObject(cx, clasp, proto, parent, 0, NULL);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent, uintN argc, jsval *argv)
-{
- CHECK_REQUEST(cx);
- if (!clasp)
- clasp = &js_ObjectClass; /* default class is Object */
- return js_ConstructObject(cx, clasp, proto, parent, argc, argv);
-}
-
-static JSBool
-DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN tinyid)
-{
- jsid id;
- JSAtom *atom;
-
- if (attrs & JSPROP_INDEX) {
- id = INT_TO_JSVAL((jsint)name);
- atom = NULL;
- attrs &= ~JSPROP_INDEX;
- } else {
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
- id = (jsid)atom;
- }
- if (flags != 0 && OBJ_IS_NATIVE(obj)) {
- return js_DefineNativeProperty(cx, obj, id, value, getter, setter,
- attrs, flags, tinyid, NULL);
- }
- return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs,
- NULL);
-}
-
-#define AUTO_NAMELEN(s,n) (((n) == (size_t)-1) ? js_strlen(s) : (n))
-
-static JSBool
-DefineUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN tinyid)
-{
- JSAtom *atom;
-
- atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
- if (!atom)
- return JS_FALSE;
- if (flags != 0 && OBJ_IS_NATIVE(obj)) {
- return js_DefineNativeProperty(cx, obj, (jsid)atom, value,
- getter, setter, attrs, flags, tinyid,
- NULL);
- }
- return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, value, getter, setter,
- attrs, NULL);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
- JSObject *proto, uintN attrs)
-{
- JSObject *nobj;
-
- CHECK_REQUEST(cx);
- if (!clasp)
- clasp = &js_ObjectClass; /* default class is Object */
- nobj = js_NewObject(cx, clasp, proto, obj);
- if (!nobj)
- return NULL;
- if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
- 0, 0)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- return nobj;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds)
-{
- JSBool ok;
- jsval value;
- uintN flags;
-
- CHECK_REQUEST(cx);
- for (ok = JS_TRUE; cds->name; cds++) {
- ok = js_NewNumberValue(cx, cds->dval, &value);
- if (!ok)
- break;
- flags = cds->flags;
- if (!flags)
- flags = JSPROP_READONLY | JSPROP_PERMANENT;
- ok = DefineProperty(cx, obj, cds->name, value, NULL, NULL, flags, 0, 0);
- if (!ok)
- break;
- }
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps)
-{
- JSBool ok;
-
- CHECK_REQUEST(cx);
- for (ok = JS_TRUE; ps->name; ps++) {
- ok = DefineProperty(cx, obj, ps->name, JSVAL_VOID,
- ps->getter, ps->setter, ps->flags,
- SPROP_HAS_SHORTID, ps->tinyid);
- if (!ok)
- break;
- }
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
-{
- CHECK_REQUEST(cx);
- return DefineProperty(cx, obj, name, value, getter, setter, attrs, 0, 0);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
- int8 tinyid, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs)
-{
- CHECK_REQUEST(cx);
- return DefineProperty(cx, obj, name, value, getter, setter, attrs,
- SPROP_HAS_SHORTID, tinyid);
-}
-
-static JSBool
-LookupProperty(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
- JSProperty **propp)
-{
- JSAtom *atom;
-
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);
-}
-
-static JSBool
-LookupUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- JSObject **objp, JSProperty **propp)
-{
- JSAtom *atom;
-
- atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
- const char *alias)
-{
- JSObject *obj2;
- JSProperty *prop;
- JSAtom *atom;
- JSBool ok;
- JSScopeProperty *sprop;
-
- CHECK_REQUEST(cx);
- if (!LookupProperty(cx, obj, name, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- js_ReportIsNotDefined(cx, name);
- return JS_FALSE;
- }
- if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
- alias, name, OBJ_GET_CLASS(cx, obj2)->name);
- return JS_FALSE;
- }
- atom = js_Atomize(cx, alias, strlen(alias), 0);
- if (!atom) {
- ok = JS_FALSE;
- } else {
- sprop = (JSScopeProperty *)prop;
- ok = (js_AddNativeProperty(cx, obj, (jsid)atom,
- sprop->getter, sprop->setter, sprop->slot,
- sprop->attrs, sprop->flags | SPROP_IS_ALIAS,
- sprop->shortid)
- != NULL);
- }
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
-}
-
-static jsval
-LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop)
-{
- JSScopeProperty *sprop;
- jsval rval;
-
- if (!prop) {
- /* XXX bad API: no way to tell "not defined" from "void value" */
- return JSVAL_VOID;
- }
- if (OBJ_IS_NATIVE(obj2)) {
- /* Peek at the native property's slot value, without doing a Get. */
- sprop = (JSScopeProperty *)prop;
- rval = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
- ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
- : JSVAL_TRUE;
- } else {
- /* XXX bad API: no way to return "defined but value unknown" */
- rval = JSVAL_TRUE;
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- return rval;
-}
-
-static JSBool
-GetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
- uintN *attrsp, JSBool *foundp)
-{
- JSObject *obj2;
- JSProperty *prop;
- JSBool ok;
-
- if (!atom)
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
- return JS_FALSE;
- if (!prop || obj != obj2) {
- *foundp = JS_FALSE;
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- return JS_TRUE;
- }
-
- *foundp = JS_TRUE;
- ok = OBJ_GET_ATTRIBUTES(cx, obj, (jsid)atom, prop, attrsp);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
-}
-
-static JSBool
-SetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
- uintN attrs, JSBool *foundp)
-{
- JSObject *obj2;
- JSProperty *prop;
- JSBool ok;
-
- if (!atom)
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
- return JS_FALSE;
- if (!prop || obj != obj2) {
- *foundp = JS_FALSE;
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- return JS_TRUE;
- }
-
- *foundp = JS_TRUE;
- ok = OBJ_SET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- 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_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
-{
- JSBool ok;
- JSObject *obj2;
- JSProperty *prop;
-
- CHECK_REQUEST(cx);
- ok = LookupProperty(cx, obj, name, &obj2, &prop);
- if (ok)
- *vp = LookupResult(cx, obj, obj2, prop);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name)
-{
- jsval junk;
-
- CHECK_REQUEST(cx);
- return JS_DeleteProperty2(cx, obj, name, &junk);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name,
- jsval *rval)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs)
-{
- CHECK_REQUEST(cx);
- return DefineUCProperty(cx, obj, name, namelen, value, getter, setter,
- attrs, 0, 0);
-}
-
-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_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- int8 tinyid, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs)
-{
- CHECK_REQUEST(cx);
- return DefineUCProperty(cx, obj, name, namelen, value, getter, setter,
- attrs, SPROP_HAS_SHORTID, tinyid);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_LookupUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp)
-{
- JSBool ok;
- JSObject *obj2;
- JSProperty *prop;
-
- CHECK_REQUEST(cx);
- ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop);
- if (ok)
- *vp = LookupResult(cx, obj, obj2, prop);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DeleteUCProperty2(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *rval)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
- if (!atom)
- return JS_FALSE;
- return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector)
-{
- CHECK_REQUEST(cx);
- /* NB: jsuint cast does ToUint32. */
- return js_NewArrayObject(cx, (jsuint)length, vector);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsArrayObject(JSContext *cx, JSObject *obj)
-{
- return OBJ_GET_CLASS(cx, obj) == &js_ArrayClass;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
-{
- CHECK_REQUEST(cx);
- return js_GetLengthProperty(cx, obj, lengthp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length)
-{
- CHECK_REQUEST(cx);
- return js_SetLengthProperty(cx, obj, length);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
-{
- CHECK_REQUEST(cx);
- return js_HasLengthProperty(cx, obj, lengthp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
-{
- CHECK_REQUEST(cx);
- return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(index), value,
- getter, setter, attrs, NULL);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
-{
- JSObject *obj2;
- JSProperty *prop;
- JSScopeProperty *sprop;
- JSBool ok;
-
- CHECK_REQUEST(cx);
- if (!LookupProperty(cx, obj, name, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- js_ReportIsNotDefined(cx, name);
- return JS_FALSE;
- }
- if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
- char numBuf[12];
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
- numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
- return JS_FALSE;
- }
- sprop = (JSScopeProperty *)prop;
- ok = (js_AddNativeProperty(cx, obj, INT_TO_JSVAL(alias),
- sprop->getter, sprop->setter, sprop->slot,
- sprop->attrs, sprop->flags | SPROP_IS_ALIAS,
- sprop->shortid)
- != NULL);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
-{
- JSBool ok;
- JSObject *obj2;
- JSProperty *prop;
-
- CHECK_REQUEST(cx);
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSVAL(index), &obj2, &prop);
- if (ok)
- *vp = LookupResult(cx, obj, obj2, prop);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
-{
- CHECK_REQUEST(cx);
- return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
-{
- CHECK_REQUEST(cx);
- return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index)
-{
- jsval junk;
-
- CHECK_REQUEST(cx);
- return JS_DeleteElement2(cx, obj, index, &junk);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
-{
- CHECK_REQUEST(cx);
- return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSVAL(index), rval);
-}
-
-JS_PUBLIC_API(void)
-JS_ClearScope(JSContext *cx, JSObject *obj)
-{
- CHECK_REQUEST(cx);
-
- if (obj->map->ops->clear)
- obj->map->ops->clear(cx, obj);
-}
-
-JS_PUBLIC_API(JSIdArray *)
-JS_Enumerate(JSContext *cx, JSObject *obj)
-{
- jsint i, n;
- jsval iter_state, num_properties;
- jsid id;
- JSIdArray *ida;
- jsval *vector;
-
- CHECK_REQUEST(cx);
-
- ida = NULL;
- iter_state = JSVAL_NULL;
-
- /* Get the number of properties to enumerate. */
- if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))
- goto error;
- if (!JSVAL_IS_INT(num_properties)) {
- JS_ASSERT(0);
- goto error;
- }
-
- /* Grow as needed if we don't know the exact amount ahead of time. */
- n = JSVAL_TO_INT(num_properties);
- if (n <= 0)
- n = 8;
-
- /* Create an array of jsids large enough to hold all the properties */
- ida = js_NewIdArray(cx, n);
- if (!ida)
- goto error;
-
- i = 0;
- vector = &ida->vector[0];
- for (;;) {
- if (i == ida->length) {
- /* Grow length by factor of 1.5 instead of doubling. */
- jsint newlen = ida->length + (((jsuint)ida->length + 1) >> 1);
- ida = js_GrowIdArray(cx, ida, newlen);
- if (!ida)
- goto error;
- vector = &ida->vector[0];
- }
-
- if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &id))
- goto error;
-
- /* No more jsid's to enumerate ? */
- if (iter_state == JSVAL_NULL)
- break;
- vector[i++] = id;
- }
- ida->length = i;
- return ida;
-
-error:
- if (iter_state != JSVAL_NULL)
- OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
- if (ida)
- JS_DestroyIdArray(cx, ida);
- return NULL;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
- jsval *vp, uintN *attrsp)
-{
- CHECK_REQUEST(cx);
- return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);
-}
-
-JS_PUBLIC_API(JSCheckAccessOp)
-JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb)
-{
- JSCheckAccessOp oldacb;
-
- oldacb = rt->checkObjectAccess;
- rt->checkObjectAccess = acb;
- return oldacb;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)
-{
- JSClass *clasp;
- uint32 slot;
-
- CHECK_REQUEST(cx);
- clasp = OBJ_GET_CLASS(cx, obj);
- if (index >= JSCLASS_RESERVED_SLOTS(clasp)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_RESERVED_SLOT_RANGE);
- return JS_FALSE;
- }
- slot = JSSLOT_START(clasp) + index;
- *vp = OBJ_GET_REQUIRED_SLOT(cx, obj, slot);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)
-{
- JSClass *clasp;
- uint32 slot;
-
- CHECK_REQUEST(cx);
- clasp = OBJ_GET_CLASS(cx, obj);
- if (index >= JSCLASS_RESERVED_SLOTS(clasp)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_RESERVED_SLOT_RANGE);
- return JS_FALSE;
- }
- slot = JSSLOT_START(clasp) + index;
- OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
- return JS_TRUE;
-}
-
-#ifdef JS_THREADSAFE
-JS_PUBLIC_API(jsrefcount)
-JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals)
-{
- return JS_ATOMIC_INCREMENT(&principals->refcount);
-}
-
-JS_PUBLIC_API(jsrefcount)
-JS_DropPrincipals(JSContext *cx, JSPrincipals *principals)
-{
- jsrefcount rc = JS_ATOMIC_DECREMENT(&principals->refcount);
- if (rc == 0)
- principals->destroy(cx, principals);
- return rc;
-}
-#endif
-
-JS_PUBLIC_API(JSPrincipalsTranscoder)
-JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px)
-{
- JSPrincipalsTranscoder oldpx;
-
- oldpx = rt->principalsTranscoder;
- rt->principalsTranscoder = px;
- return oldpx;
-}
-
-JS_PUBLIC_API(JSObjectPrincipalsFinder)
-JS_SetObjectPrincipalsFinder(JSContext *cx, JSObjectPrincipalsFinder fop)
-{
- JSObjectPrincipalsFinder oldfop;
-
- oldfop = cx->findObjectPrincipals;
- cx->findObjectPrincipals = fop;
- return oldfop;
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
- JSObject *parent, const char *name)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
-
- if (!name) {
- atom = NULL;
- } else {
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return NULL;
- }
- return js_NewFunction(cx, NULL, native, nargs, flags, parent, atom);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
-{
- CHECK_REQUEST(cx);
- if (OBJ_GET_CLASS(cx, funobj) != &js_FunctionClass) {
- /* Indicate we cannot clone this object. */
- return funobj;
- }
- return js_CloneFunctionObject(cx, funobj, parent);
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetFunctionObject(JSFunction *fun)
-{
- return fun->object;
-}
-
-JS_PUBLIC_API(const char *)
-JS_GetFunctionName(JSFunction *fun)
-{
- return fun->atom
- ? JS_GetStringBytes(ATOM_TO_STRING(fun->atom))
- : js_anonymous_str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_GetFunctionId(JSFunction *fun)
-{
- return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
-}
-
-JS_PUBLIC_API(uintN)
-JS_GetFunctionFlags(JSFunction *fun)
-{
- return fun->flags;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ObjectIsFunction(JSContext *cx, JSObject *obj)
-{
- return OBJ_GET_CLASS(cx, obj) == &js_FunctionClass;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
-{
- JSFunction *fun;
-
- CHECK_REQUEST(cx);
- for (; fs->name; fs++) {
- fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs,
- fs->flags);
- if (!fun)
- return JS_FALSE;
- fun->extra = fs->extra;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
- uintN nargs, uintN attrs)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return NULL;
- return js_DefineFunction(cx, obj, atom, call, nargs, attrs);
-}
-
-static JSScript *
-CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts,
- void *tempMark, JSBool *eofp)
-{
- JSBool eof;
- JSArenaPool codePool, notePool;
- JSCodeGenerator cg;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- eof = JS_FALSE;
- JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
- JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
- if (!js_InitCodeGenerator(cx, &cg, &codePool, &notePool,
- ts->filename, ts->lineno,
- ts->principals)) {
- script = NULL;
- } else if (!js_CompileTokenStream(cx, obj, ts, &cg)) {
- script = NULL;
- eof = (ts->flags & TSF_EOF) != 0;
- } else {
- script = js_NewScriptFromCG(cx, &cg, NULL);
- }
- if (eofp)
- *eofp = eof;
- if (!js_CloseTokenStream(cx, ts)) {
- if (script)
- js_DestroyScript(cx, script);
- script = NULL;
- }
- cg.tempMark = tempMark;
- js_FinishCodeGenerator(cx, &cg);
- JS_FinishArenaPool(&codePool);
- JS_FinishArenaPool(&notePool);
- return script;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileScript(JSContext *cx, JSObject *obj,
- const char *bytes, size_t length,
- const char *filename, uintN lineno)
-{
- jschar *chars;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno);
- JS_free(cx, chars);
- return script;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const char *bytes, size_t length,
- const char *filename, uintN lineno)
-{
- jschar *chars;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
- chars, length, filename, lineno);
- JS_free(cx, chars);
- return script;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileUCScript(JSContext *cx, JSObject *obj,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno)
-{
- CHECK_REQUEST(cx);
- return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length,
- filename, lineno);
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno)
-{
- void *mark;
- JSTokenStream *ts;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- mark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
- if (!ts)
- return NULL;
- script = CompileTokenStream(cx, obj, ts, mark, NULL);
-#if JS_HAS_EXCEPTIONS
- if (!script && !cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return script;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
- const char *bytes, size_t length)
-{
- jschar *chars;
- JSBool result;
- JSExceptionState *exnState;
- void *tempMark;
- JSTokenStream *ts;
- JSErrorReporter older;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return JS_TRUE;
-
- /*
- * Return true on any out-of-memory error, so our caller doesn't try to
- * collect more buffered source.
- */
- result = JS_TRUE;
- exnState = JS_SaveExceptionState(cx);
- tempMark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewTokenStream(cx, chars, length, NULL, 0, NULL);
- if (ts) {
- older = JS_SetErrorReporter(cx, NULL);
- if (!js_ParseTokenStream(cx, obj, ts)) {
- /*
- * We ran into an error. If it was because we ran out of source,
- * we return false, so our caller will know to try to collect more
- * buffered source.
- */
- result = (ts->flags & TSF_EOF) == 0;
- }
-
- JS_SetErrorReporter(cx, older);
- js_CloseTokenStream(cx, ts);
- JS_ARENA_RELEASE(&cx->tempPool, tempMark);
- }
-
- JS_free(cx, chars);
- JS_RestoreExceptionState(cx, exnState);
- return result;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
-{
- void *mark;
- JSTokenStream *ts;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- mark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewFileTokenStream(cx, filename, stdin);
- if (!ts)
- return NULL;
- script = CompileTokenStream(cx, obj, ts, mark, NULL);
-#if JS_HAS_EXCEPTIONS
- if (!script && !cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return script;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
- FILE *file)
-{
- return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, NULL);
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
- const char *filename, FILE *file,
- JSPrincipals *principals)
-{
- void *mark;
- JSTokenStream *ts;
- JSScript *script;
-
- CHECK_REQUEST(cx);
- mark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewFileTokenStream(cx, NULL, file);
- if (!ts)
- return NULL;
- ts->filename = filename;
- /* XXXshaver js_NewFileTokenStream should do this, because it drops */
- if (principals) {
- ts->principals = principals;
- JSPRINCIPALS_HOLD(cx, ts->principals);
- }
- script = CompileTokenStream(cx, obj, ts, mark, NULL);
-#if JS_HAS_EXCEPTIONS
- if (!script && !cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return script;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_NewScriptObject(JSContext *cx, JSScript *script)
-{
- JSObject *obj;
-
- /*
- * We use a dummy stack frame to protect the script from a GC caused
- * by debugger-hook execution.
- *
- * XXX We really need a way to manage local roots and such more
- * XXX automatically, at which point we can remove this one-off hack
- * XXX and others within the engine. See bug 40757 for discussion.
- */
- JSStackFrame dummy;
-
- CHECK_REQUEST(cx);
-
- memset(&dummy, 0, sizeof dummy);
- dummy.down = cx->fp;
- dummy.script = script;
- cx->fp = &dummy;
-
- obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
-
- cx->fp = dummy.down;
- if (!obj)
- return NULL;
-
- if (script) {
- if (!JS_SetPrivate(cx, obj, script))
- return NULL;
- script->object = obj;
- }
- return obj;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetScriptObject(JSScript *script)
-{
- return script->object;
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyScript(JSContext *cx, JSScript *script)
-{
- CHECK_REQUEST(cx);
- js_DestroyScript(cx, script);
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
- uintN nargs, const char **argnames,
- const char *bytes, size_t length,
- const char *filename, uintN lineno)
-{
- jschar *chars;
- JSFunction *fun;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length,
- filename, lineno);
- JS_free(cx, chars);
- return fun;
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals, const char *name,
- uintN nargs, const char **argnames,
- const char *bytes, size_t length,
- const char *filename, uintN lineno)
-{
- jschar *chars;
- JSFunction *fun;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
- nargs, argnames, chars, length,
- filename, lineno);
- JS_free(cx, chars);
- return fun;
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
- uintN nargs, const char **argnames,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno)
-{
- CHECK_REQUEST(cx);
- return JS_CompileUCFunctionForPrincipals(cx, obj, NULL, name,
- nargs, argnames,
- chars, length,
- filename, lineno);
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals, const char *name,
- uintN nargs, const char **argnames,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno)
-{
- void *mark;
- JSTokenStream *ts;
- JSFunction *fun;
- JSAtom *funAtom, *argAtom;
- uintN i;
-
- CHECK_REQUEST(cx);
- mark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
- if (!ts) {
- fun = NULL;
- goto out;
- }
- if (!name) {
- funAtom = NULL;
- } else {
- funAtom = js_Atomize(cx, name, strlen(name), 0);
- if (!funAtom) {
- fun = NULL;
- goto out;
- }
- }
- fun = js_NewFunction(cx, NULL, NULL, nargs, 0, obj, funAtom);
- if (!fun)
- goto out;
- if (nargs) {
- for (i = 0; i < nargs; i++) {
- argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
- if (!argAtom)
- break;
- if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom,
- js_GetArgument, js_SetArgument,
- SPROP_INVALID_SLOT,
- JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_SHARED,
- SPROP_HAS_SHORTID, i)) {
- break;
- }
- }
- if (i < nargs) {
- fun = NULL;
- goto out;
- }
- }
- if (!js_CompileFunctionBody(cx, ts, fun)) {
- fun = NULL;
- goto out;
- }
- if (obj && funAtom) {
- if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)funAtom,
- OBJECT_TO_JSVAL(fun->object),
- NULL, NULL, 0, NULL)) {
- return NULL;
- }
- }
-out:
- if (ts)
- js_CloseTokenStream(cx, ts);
- JS_ARENA_RELEASE(&cx->tempPool, mark);
-#if JS_HAS_EXCEPTIONS
- if (!fun && !cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return fun;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
- uintN indent)
-{
- JSPrinter *jp;
- JSString *str;
-
- CHECK_REQUEST(cx);
- jp = js_NewPrinter(cx, name,
- indent & ~JS_DONT_PRETTY_PRINT,
- !(indent & JS_DONT_PRETTY_PRINT));
- if (!jp)
- return NULL;
- if (js_DecompileScript(jp, script))
- str = js_GetPrinterOutput(jp);
- else
- str = NULL;
- js_DestroyPrinter(jp);
- return str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
-{
- JSPrinter *jp;
- JSString *str;
-
- CHECK_REQUEST(cx);
- jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
- indent & ~JS_DONT_PRETTY_PRINT,
- !(indent & JS_DONT_PRETTY_PRINT));
- if (!jp)
- return NULL;
- if (js_DecompileFunction(jp, fun))
- str = js_GetPrinterOutput(jp);
- else
- str = NULL;
- js_DestroyPrinter(jp);
- return str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent)
-{
- JSPrinter *jp;
- JSString *str;
-
- CHECK_REQUEST(cx);
- jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
- indent & ~JS_DONT_PRETTY_PRINT,
- !(indent & JS_DONT_PRETTY_PRINT));
- if (!jp)
- return NULL;
- if (js_DecompileFunctionBody(jp, fun))
- str = js_GetPrinterOutput(jp);
- else
- str = NULL;
- js_DestroyPrinter(jp);
- return str;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval)
-{
- CHECK_REQUEST(cx);
- if (!js_Execute(cx, obj, script, NULL, 0, rval)) {
-#if JS_HAS_EXCEPTIONS
- if (!cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
- JSExecPart part, jsval *rval)
-{
- JSScript tmp;
- JSRuntime *rt;
- JSBool ok;
-
- /* Make a temporary copy of the JSScript structure and farble it a bit. */
- tmp = *script;
- if (part == JSEXEC_PROLOG) {
- tmp.length = PTRDIFF(tmp.main, tmp.code, jsbytecode);
- } else {
- tmp.length -= PTRDIFF(tmp.main, tmp.code, jsbytecode);
- tmp.code = tmp.main;
- }
-
- /* Tell the debugger about our temporary copy of the script structure. */
- rt = cx->runtime;
- if (rt->newScriptHook) {
- rt->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
- rt->newScriptHookData);
- }
-
- /* Execute the farbled struct and tell the debugger to forget about it. */
- ok = JS_ExecuteScript(cx, obj, &tmp, rval);
- if (rt->destroyScriptHook)
- rt->destroyScriptHook(cx, &tmp, rt->destroyScriptHookData);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateScript(JSContext *cx, JSObject *obj,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- jschar *chars;
- JSBool ok;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return JS_FALSE;
- ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
- JS_free(cx, chars);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- jschar *chars;
- JSBool ok;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return JS_FALSE;
- ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,
- filename, lineno, rval);
- JS_free(cx, chars);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
- const jschar *chars, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- CHECK_REQUEST(cx);
- return JS_EvaluateUCScriptForPrincipals(cx, obj, NULL, chars, length,
- filename, lineno, rval);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const jschar *chars, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- JSScript *script;
- JSBool ok;
-
- CHECK_REQUEST(cx);
- script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length,
- filename, lineno);
- if (!script)
- return JS_FALSE;
- ok = js_Execute(cx, obj, script, NULL, 0, rval);
-#if JS_HAS_EXCEPTIONS
- if (!ok && !cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- JS_DestroyScript(cx, script);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
- jsval *argv, jsval *rval)
-{
- CHECK_REQUEST(cx);
- if (!js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv,
- rval)) {
-#if JS_HAS_EXCEPTIONS
- if (!cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
- jsval *argv, jsval *rval)
-{
- jsval fval;
-
- CHECK_REQUEST(cx);
- if (!JS_GetProperty(cx, obj, name, &fval))
- return JS_FALSE;
- if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) {
-#if JS_HAS_EXCEPTIONS
- if (!cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
- jsval *argv, jsval *rval)
-{
- CHECK_REQUEST(cx);
- if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) {
-#if JS_HAS_EXCEPTIONS
- if (!cx->fp)
- js_ReportUncaughtException(cx);
-#endif
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBranchCallback)
-JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb)
-{
- JSBranchCallback oldcb;
-
- oldcb = cx->branchCallback;
- cx->branchCallback = cb;
- return oldcb;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsRunning(JSContext *cx)
-{
- return cx->fp != NULL;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsConstructing(JSContext *cx)
-{
- return cx->fp && (cx->fp->flags & JSFRAME_CONSTRUCTING);
-}
-
-JS_FRIEND_API(JSBool)
-JS_IsAssigning(JSContext *cx)
-{
- JSStackFrame *fp;
- jsbytecode *pc;
-
- for (fp = cx->fp; fp && !fp->script; fp = fp->down)
- continue;
- if (!fp || !(pc = fp->pc))
- return JS_FALSE;
- return (js_CodeSpec[*pc].format & JOF_ASSIGNING) != 0;
-}
-
-JS_PUBLIC_API(void)
-JS_SetCallReturnValue2(JSContext *cx, jsval v)
-{
-#if JS_HAS_LVALUE_RETURN
- cx->rval2 = v;
- cx->rval2set = JS_TRUE;
-#endif
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(JSString *)
-JS_NewString(JSContext *cx, char *bytes, size_t length)
-{
- jschar *chars;
- JSString *str;
-
- CHECK_REQUEST(cx);
- /* Make a Unicode vector from the 8-bit char codes in bytes. */
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
-
- /* Free chars (but not bytes, which caller frees on error) if we fail. */
- str = js_NewString(cx, chars, length, 0);
- if (!str) {
- JS_free(cx, chars);
- return NULL;
- }
-
- /* Hand off bytes to the deflated string cache, if possible. */
- if (!js_SetStringBytes(str, bytes, length))
- JS_free(cx, bytes);
- return str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewStringCopyN(JSContext *cx, const char *s, size_t n)
-{
- jschar *js;
- JSString *str;
-
- CHECK_REQUEST(cx);
- js = js_InflateString(cx, s, n);
- if (!js)
- return NULL;
- str = js_NewString(cx, js, n, 0);
- if (!str)
- JS_free(cx, js);
- return str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewStringCopyZ(JSContext *cx, const char *s)
-{
- size_t n;
- jschar *js;
- JSString *str;
-
- CHECK_REQUEST(cx);
- if (!s)
- return cx->runtime->emptyString;
- n = strlen(s);
- js = js_InflateString(cx, s, n);
- if (!js)
- return NULL;
- str = js_NewString(cx, js, n, 0);
- if (!str)
- JS_free(cx, js);
- return str;
-}
-
-JS_PUBLIC_API(JSString *)
-JS_InternString(JSContext *cx, const char *s)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
- if (!atom)
- return NULL;
- return ATOM_TO_STRING(atom);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewUCString(JSContext *cx, jschar *chars, size_t length)
-{
- CHECK_REQUEST(cx);
- return js_NewString(cx, chars, length, 0);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n)
-{
- CHECK_REQUEST(cx);
- return js_NewStringCopyN(cx, s, n, 0);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
-{
- CHECK_REQUEST(cx);
- if (!s)
- return cx->runtime->emptyString;
- return js_NewStringCopyZ(cx, s, 0);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
-{
- JSAtom *atom;
-
- CHECK_REQUEST(cx);
- atom = js_AtomizeChars(cx, s, length, ATOM_INTERNED);
- if (!atom)
- return NULL;
- return ATOM_TO_STRING(atom);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_InternUCString(JSContext *cx, const jschar *s)
-{
- return JS_InternUCStringN(cx, s, js_strlen(s));
-}
-
-JS_PUBLIC_API(char *)
-JS_GetStringBytes(JSString *str)
-{
- char *bytes;
-
- bytes = js_GetStringBytes(str);
- return bytes ? bytes : "";
-}
-
-JS_PUBLIC_API(jschar *)
-JS_GetStringChars(JSString *str)
-{
- /*
- * API botch (again, shades of JS_GetStringBytes): we have no cx to pass
- * to js_UndependString (called by js_GetStringChars) for out-of-memory
- * error reports, so js_UndependString passes NULL and suppresses errors.
- * If it fails to convert a dependent string into an independent one, our
- * caller will not be guaranteed a \u0000 terminator as a backstop. This
- * may break some clients who already misbehave on embedded NULs.
- *
- * The gain of dependent strings, which cure quadratic and cubic growth
- * rate bugs in string concatenation, is worth this slight loss in API
- * compatibility.
- */
- jschar *chars;
-
- chars = js_GetStringChars(str);
- return chars ? chars : JSSTRING_CHARS(str);
-}
-
-JS_PUBLIC_API(size_t)
-JS_GetStringLength(JSString *str)
-{
- return JSSTRING_LENGTH(str);
-}
-
-JS_PUBLIC_API(intN)
-JS_CompareStrings(JSString *str1, JSString *str2)
-{
- return js_CompareStrings(str1, str2);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length)
-{
- CHECK_REQUEST(cx);
- return js_NewString(cx, chars, length, GCF_MUTABLE);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_NewDependentString(JSContext *cx, JSString *str, size_t start,
- size_t length)
-{
- CHECK_REQUEST(cx);
- return js_NewDependentString(cx, str, start, length, 0);
-}
-
-JS_PUBLIC_API(JSString *)
-JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
-{
- CHECK_REQUEST(cx);
- return js_ConcatStrings(cx, left, right);
-}
-
-JS_PUBLIC_API(const jschar *)
-JS_UndependString(JSContext *cx, JSString *str)
-{
- CHECK_REQUEST(cx);
- return js_UndependString(cx, str);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_MakeStringImmutable(JSContext *cx, JSString *str)
-{
- CHECK_REQUEST(cx);
- if (!js_UndependString(cx, str))
- return JS_FALSE;
-
- *js_GetGCThingFlags(str) &= ~GCF_MUTABLE;
- return JS_TRUE;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(void)
-JS_ReportError(JSContext *cx, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- js_ReportErrorVA(cx, JSREPORT_ERROR, format, ap);
- va_end(ap);
-}
-
-JS_PUBLIC_API(void)
-JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
- void *userRef, const uintN errorNumber, ...)
-{
- va_list ap;
-
- va_start(ap, errorNumber);
- js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
- errorNumber, JS_TRUE, ap);
- va_end(ap);
-}
-
-JS_PUBLIC_API(void)
-JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
- void *userRef, const uintN errorNumber, ...)
-{
- va_list ap;
-
- va_start(ap, errorNumber);
- js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
- errorNumber, JS_FALSE, ap);
- va_end(ap);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ReportWarning(JSContext *cx, const char *format, ...)
-{
- va_list ap;
- JSBool ok;
-
- va_start(ap, format);
- ok = js_ReportErrorVA(cx, JSREPORT_WARNING, format, ap);
- va_end(ap);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags,
- JSErrorCallback errorCallback, void *userRef,
- const uintN errorNumber, ...)
-{
- va_list ap;
- JSBool ok;
-
- va_start(ap, errorNumber);
- ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
- errorNumber, JS_TRUE, ap);
- va_end(ap);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags,
- JSErrorCallback errorCallback, void *userRef,
- const uintN errorNumber, ...)
-{
- va_list ap;
- JSBool ok;
-
- va_start(ap, errorNumber);
- ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
- errorNumber, JS_FALSE, ap);
- va_end(ap);
- return ok;
-}
-
-JS_PUBLIC_API(void)
-JS_ReportOutOfMemory(JSContext *cx)
-{
- js_ReportOutOfMemory(cx, js_GetErrorMessage);
-}
-
-JS_PUBLIC_API(JSErrorReporter)
-JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
-{
- JSErrorReporter older;
-
- older = cx->errorReporter;
- cx->errorReporter = er;
- return older;
-}
-
-/************************************************************************/
-
-/*
- * Regular Expressions.
- */
-JS_PUBLIC_API(JSObject *)
-JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags)
-{
-#if JS_HAS_REGEXPS
- jschar *chars;
- JSObject *obj;
-
- CHECK_REQUEST(cx);
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- obj = js_NewRegExpObject(cx, NULL, chars, length, flags);
- JS_free(cx, chars);
- return obj;
-#else
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
- return NULL;
-#endif
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags)
-{
- CHECK_REQUEST(cx);
-#if JS_HAS_REGEXPS
- return js_NewRegExpObject(cx, NULL, chars, length, flags);
-#else
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
- return NULL;
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline)
-{
- JSRegExpStatics *res;
-
- CHECK_REQUEST(cx);
- /* No locking required, cx is thread-private and input must be live. */
- res = &cx->regExpStatics;
- res->input = input;
- res->multiline = multiline;
- cx->runtime->gcPoke = JS_TRUE;
-}
-
-JS_PUBLIC_API(void)
-JS_ClearRegExpStatics(JSContext *cx)
-{
- JSRegExpStatics *res;
-
- /* No locking required, cx is thread-private and input must be live. */
- res = &cx->regExpStatics;
- res->input = NULL;
- res->multiline = JS_FALSE;
- res->parenCount = 0;
- res->lastMatch = res->lastParen = js_EmptySubString;
- res->leftContext = res->rightContext = js_EmptySubString;
- cx->runtime->gcPoke = JS_TRUE;
-}
-
-JS_PUBLIC_API(void)
-JS_ClearRegExpRoots(JSContext *cx)
-{
- JSRegExpStatics *res;
-
- /* No locking required, cx is thread-private and input must be live. */
- res = &cx->regExpStatics;
- res->input = NULL;
- cx->runtime->gcPoke = JS_TRUE;
-}
-
-/* TODO: compile, execute, get/set other statics... */
-
-/************************************************************************/
-
-JS_PUBLIC_API(void)
-JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks)
-{
- cx->localeCallbacks = callbacks;
-}
-
-JS_PUBLIC_API(JSLocaleCallbacks *)
-JS_GetLocaleCallbacks(JSContext *cx)
-{
- return cx->localeCallbacks;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(JSBool)
-JS_IsExceptionPending(JSContext *cx)
-{
-#if JS_HAS_EXCEPTIONS
- return (JSBool) cx->throwing;
-#else
- return JS_FALSE;
-#endif
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetPendingException(JSContext *cx, jsval *vp)
-{
-#if JS_HAS_EXCEPTIONS
- CHECK_REQUEST(cx);
- if (!cx->throwing)
- return JS_FALSE;
- *vp = cx->exception;
- return JS_TRUE;
-#else
- return JS_FALSE;
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_SetPendingException(JSContext *cx, jsval v)
-{
- CHECK_REQUEST(cx);
-#if JS_HAS_EXCEPTIONS
- cx->throwing = JS_TRUE;
- cx->exception = v;
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_ClearPendingException(JSContext *cx)
-{
-#if JS_HAS_EXCEPTIONS
- cx->throwing = JS_FALSE;
- cx->exception = JSVAL_VOID;
-#endif
-}
-
-#if JS_HAS_EXCEPTIONS
-struct JSExceptionState {
- JSBool throwing;
- jsval exception;
-};
-#endif
-
-JS_PUBLIC_API(JSExceptionState *)
-JS_SaveExceptionState(JSContext *cx)
-{
-#if JS_HAS_EXCEPTIONS
- JSExceptionState *state;
-
- CHECK_REQUEST(cx);
- state = (JSExceptionState *) JS_malloc(cx, sizeof(JSExceptionState));
- if (state) {
- state->throwing = JS_GetPendingException(cx, &state->exception);
- if (state->throwing && JSVAL_IS_GCTHING(state->exception))
- js_AddRoot(cx, &state->exception, "JSExceptionState.exception");
- }
- return state;
-#else
- return NULL;
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state)
-{
-#if JS_HAS_EXCEPTIONS
- CHECK_REQUEST(cx);
- if (state) {
- if (state->throwing)
- JS_SetPendingException(cx, state->exception);
- else
- JS_ClearPendingException(cx);
- JS_DropExceptionState(cx, state);
- }
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_DropExceptionState(JSContext *cx, JSExceptionState *state)
-{
-#if JS_HAS_EXCEPTIONS
- CHECK_REQUEST(cx);
- if (state) {
- if (state->throwing && JSVAL_IS_GCTHING(state->exception))
- JS_RemoveRoot(cx, &state->exception);
- JS_free(cx, state);
- }
-#endif
-}
-
-JS_PUBLIC_API(JSErrorReport *)
-JS_ErrorFromException(JSContext *cx, jsval v)
-{
-#if JS_HAS_EXCEPTIONS
- CHECK_REQUEST(cx);
- return js_ErrorFromException(cx, v);
-#else
- return NULL;
-#endif
-}
-
-#ifdef JS_THREADSAFE
-JS_PUBLIC_API(jsword)
-JS_GetContextThread(JSContext *cx)
-{
- return cx->thread;
-}
-
-JS_PUBLIC_API(jsword)
-JS_SetContextThread(JSContext *cx)
-{
- intN old = cx->thread;
- cx->thread = js_CurrentThreadId();
- return old;
-}
-
-JS_PUBLIC_API(intN)
-JS_ClearContextThread(JSContext *cx)
-{
- intN old = cx->thread;
- cx->thread = 0;
- return old;
-}
-#endif
-
-/************************************************************************/
-
-#if defined(XP_WIN)
-#include <windows.h>
-/*
- * Initialization routine for the JS DLL...
- */
-
-/*
- * Global Instance handle...
- * In Win32 this is the module handle of the DLL.
- *
- * In Win16 this is the instance handle of the application
- * which loaded the DLL.
- */
-
-#ifdef _WIN32
-BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
-{
- return TRUE;
-}
-
-#else /* !_WIN32 */
-
-int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
- WORD cbHeapSize, LPSTR lpszCmdLine )
-{
- return TRUE;
-}
-
-BOOL CALLBACK __loadds WEP(BOOL fSystemExit)
-{
- return TRUE;
-}
-
-#endif /* !_WIN32 */
-#endif /* XP_WIN */
diff --git a/src/extension/script/js/jsapi.h b/src/extension/script/js/jsapi.h
deleted file mode 100644
index 92b4e1d59..000000000
--- a/src/extension/script/js/jsapi.h
+++ /dev/null
@@ -1,1752 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsapi_h___
-#define jsapi_h___
-/*
- * JavaScript API.
- */
-#include <stddef.h>
-#include <stdio.h>
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * Type tags stored in the low bits of a jsval.
- */
-#define JSVAL_OBJECT 0x0 /* untagged reference to object */
-#define JSVAL_INT 0x1 /* tagged 31-bit integer value */
-#define JSVAL_DOUBLE 0x2 /* tagged reference to double */
-#define JSVAL_STRING 0x4 /* tagged reference to string */
-#define JSVAL_BOOLEAN 0x6 /* tagged boolean value */
-
-/* Type tag bitfield length and derived macros. */
-#define JSVAL_TAGBITS 3
-#define JSVAL_TAGMASK JS_BITMASK(JSVAL_TAGBITS)
-#define JSVAL_TAG(v) ((v) & JSVAL_TAGMASK)
-#define JSVAL_SETTAG(v,t) ((v) | (t))
-#define JSVAL_CLRTAG(v) ((v) & ~(jsval)JSVAL_TAGMASK)
-#define JSVAL_ALIGN JS_BIT(JSVAL_TAGBITS)
-
-/* Predicates for type testing. */
-#define JSVAL_IS_OBJECT(v) (JSVAL_TAG(v) == JSVAL_OBJECT)
-#define JSVAL_IS_NUMBER(v) (JSVAL_IS_INT(v) || JSVAL_IS_DOUBLE(v))
-#define JSVAL_IS_INT(v) (((v) & JSVAL_INT) && (v) != JSVAL_VOID)
-#define JSVAL_IS_DOUBLE(v) (JSVAL_TAG(v) == JSVAL_DOUBLE)
-#define JSVAL_IS_STRING(v) (JSVAL_TAG(v) == JSVAL_STRING)
-#define JSVAL_IS_BOOLEAN(v) (JSVAL_TAG(v) == JSVAL_BOOLEAN)
-#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL)
-#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
-#define JSVAL_IS_PRIMITIVE(v) (!JSVAL_IS_OBJECT(v) || JSVAL_IS_NULL(v))
-
-/* Objects, strings, and doubles are GC'ed. */
-#define JSVAL_IS_GCTHING(v) (!((v) & JSVAL_INT) && !JSVAL_IS_BOOLEAN(v))
-#define JSVAL_TO_GCTHING(v) ((void *)JSVAL_CLRTAG(v))
-#define JSVAL_TO_OBJECT(v) ((JSObject *)JSVAL_TO_GCTHING(v))
-#define JSVAL_TO_DOUBLE(v) ((jsdouble *)JSVAL_TO_GCTHING(v))
-#define JSVAL_TO_STRING(v) ((JSString *)JSVAL_TO_GCTHING(v))
-#define OBJECT_TO_JSVAL(obj) ((jsval)(obj))
-#define DOUBLE_TO_JSVAL(dp) JSVAL_SETTAG((jsval)(dp), JSVAL_DOUBLE)
-#define STRING_TO_JSVAL(str) JSVAL_SETTAG((jsval)(str), JSVAL_STRING)
-
-/* Lock and unlock the GC thing held by a jsval. */
-#define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \
- ? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \
- : JS_TRUE)
-#define JSVAL_UNLOCK(cx,v) (JSVAL_IS_GCTHING(v) \
- ? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v)) \
- : JS_TRUE)
-
-/* Domain limits for the jsval int type. */
-#define JSVAL_INT_BITS 31
-#define JSVAL_INT_POW2(n) ((jsval)1 << (n))
-#define JSVAL_INT_MIN ((jsval)1 - JSVAL_INT_POW2(30))
-#define JSVAL_INT_MAX (JSVAL_INT_POW2(30) - 1)
-#define INT_FITS_IN_JSVAL(i) ((jsuint)((i)+JSVAL_INT_MAX) <= 2*JSVAL_INT_MAX)
-#define JSVAL_TO_INT(v) ((jsint)(v) >> 1)
-#define INT_TO_JSVAL(i) (((jsval)(i) << 1) | JSVAL_INT)
-
-/* Convert between boolean and jsval. */
-#define JSVAL_TO_BOOLEAN(v) ((JSBool)((v) >> JSVAL_TAGBITS))
-#define BOOLEAN_TO_JSVAL(b) JSVAL_SETTAG((jsval)(b) << JSVAL_TAGBITS, \
- JSVAL_BOOLEAN)
-
-/* A private data pointer (2-byte-aligned) can be stored as an int jsval. */
-#define JSVAL_TO_PRIVATE(v) ((void *)((v) & ~JSVAL_INT))
-#define PRIVATE_TO_JSVAL(p) ((jsval)(p) | JSVAL_INT)
-
-/* Property attributes, set in JSPropertySpec and passed to API functions. */
-#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
-#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op */
-#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
-#define JSPROP_EXPORTED 0x08 /* property is exported from object */
-#define JSPROP_GETTER 0x10 /* property holds getter function */
-#define JSPROP_SETTER 0x20 /* property holds setter function */
-#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
- property; don't copy the property on
- set of the same-named property in an
- object that delegates to a prototype
- containing this property */
-#define JSPROP_INDEX 0x80 /* name is actually (jsint) index */
-
-/* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */
-#define JSFUN_LAMBDA 0x08 /* expressed, not declared, function */
-#define JSFUN_GETTER JSPROP_GETTER
-#define JSFUN_SETTER JSPROP_SETTER
-#define JSFUN_BOUND_METHOD 0x40 /* bind this to fun->object's parent */
-#define JSFUN_HEAVYWEIGHT 0x80 /* activation requires a Call object */
-#define JSFUN_FLAGS_MASK 0xf8 /* overlay JSFUN_* attributes */
-
-/*
- * Well-known JS values. The extern'd variables are initialized when the
- * first JSContext is created by JS_NewContext (see below).
- */
-#define JSVAL_VOID INT_TO_JSVAL(0 - JSVAL_INT_POW2(30))
-#define JSVAL_NULL OBJECT_TO_JSVAL(0)
-#define JSVAL_ZERO INT_TO_JSVAL(0)
-#define JSVAL_ONE INT_TO_JSVAL(1)
-#define JSVAL_FALSE BOOLEAN_TO_JSVAL(JS_FALSE)
-#define JSVAL_TRUE BOOLEAN_TO_JSVAL(JS_TRUE)
-
-/*
- * Microseconds since the epoch, midnight, January 1, 1970 UTC. See the
- * comment in jstypes.h regarding safe int64 usage.
- */
-extern JS_PUBLIC_API(int64)
-JS_Now();
-
-/* Don't want to export data, so provide accessors for non-inline jsvals. */
-extern JS_PUBLIC_API(jsval)
-JS_GetNaNValue(JSContext *cx);
-
-extern JS_PUBLIC_API(jsval)
-JS_GetNegativeInfinityValue(JSContext *cx);
-
-extern JS_PUBLIC_API(jsval)
-JS_GetPositiveInfinityValue(JSContext *cx);
-
-extern JS_PUBLIC_API(jsval)
-JS_GetEmptyStringValue(JSContext *cx);
-
-/*
- * Format is a string of the following characters (spaces are insignificant),
- * specifying the tabulated type conversions:
- *
- * b JSBool Boolean
- * c uint16/jschar ECMA uint16, Unicode char
- * i int32 ECMA int32
- * u uint32 ECMA uint32
- * j int32 Rounded int32 (coordinate)
- * d jsdouble IEEE double
- * I jsdouble Integral IEEE double
- * s char * C string
- * S JSString * Unicode string, accessed by a JSString pointer
- * W jschar * Unicode character vector, 0-terminated (W for wide)
- * o JSObject * Object reference
- * f JSFunction * Function private
- * v jsval Argument value (no conversion)
- * * N/A Skip this argument (no vararg)
- * / N/A End of required arguments
- *
- * The variable argument list after format must consist of &b, &c, &s, e.g.,
- * where those variables have the types given above. For the pointer types
- * char *, JSString *, and JSObject *, the pointed-at memory returned belongs
- * to the JS runtime, not to the calling native code. The runtime promises
- * to keep this memory valid so long as argv refers to allocated stack space
- * (so long as the native function is active).
- *
- * Fewer arguments than format specifies may be passed only if there is a /
- * in format after the last required argument specifier and argc is at least
- * the number of required arguments. More arguments than format specifies
- * may be passed without error; it is up to the caller to deal with trailing
- * unconverted arguments.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
- ...);
-
-#ifdef va_start
-extern JS_PUBLIC_API(JSBool)
-JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
- const char *format, va_list ap);
-#endif
-
-/*
- * Inverse of JS_ConvertArguments: scan format and convert trailing arguments
- * into jsvals, GC-rooted if necessary by the JS stack. Return null on error,
- * and a pointer to the new argument vector on success. Also return a stack
- * mark on success via *markp, in which case the caller must eventually clean
- * up by calling JS_PopArguments.
- *
- * Note that the number of actual arguments supplied is specified exclusively
- * by format, so there is no argc parameter.
- */
-extern JS_PUBLIC_API(jsval *)
-JS_PushArguments(JSContext *cx, void **markp, const char *format, ...);
-
-#ifdef va_start
-extern JS_PUBLIC_API(jsval *)
-JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap);
-#endif
-
-extern JS_PUBLIC_API(void)
-JS_PopArguments(JSContext *cx, void *mark);
-
-#ifdef JS_ARGUMENT_FORMATTER_DEFINED
-
-/*
- * Add and remove a format string handler for JS_{Convert,Push}Arguments{,VA}.
- * The handler function has this signature (see jspubtd.h):
- *
- * JSBool MyArgumentFormatter(JSContext *cx, const char *format,
- * JSBool fromJS, jsval **vpp, va_list *app);
- *
- * It should return true on success, and return false after reporting an error
- * or detecting an already-reported error.
- *
- * For a given format string, for example "AA", the formatter is called from
- * JS_ConvertArgumentsVA like so:
- *
- * formatter(cx, "AA...", JS_TRUE, &sp, &ap);
- *
- * sp points into the arguments array on the JS stack, while ap points into
- * the stdarg.h va_list on the C stack. The JS_TRUE passed for fromJS tells
- * the formatter to convert zero or more jsvals at sp to zero or more C values
- * accessed via pointers-to-values at ap, updating both sp (via *vpp) and ap
- * (via *app) to point past the converted arguments and their result pointers
- * on the C stack.
- *
- * When called from JS_PushArgumentsVA, the formatter is invoked thus:
- *
- * formatter(cx, "AA...", JS_FALSE, &sp, &ap);
- *
- * where JS_FALSE for fromJS means to wrap the C values at ap according to the
- * format specifier and store them at sp, updating ap and sp appropriately.
- *
- * The "..." after "AA" is the rest of the format string that was passed into
- * JS_{Convert,Push}Arguments{,VA}. The actual format trailing substring used
- * in each Convert or PushArguments call is passed to the formatter, so that
- * one such function may implement several formats, in order to share code.
- *
- * Remove just forgets about any handler associated with format. Add does not
- * copy format, it points at the string storage allocated by the caller, which
- * is typically a string constant. If format is in dynamic storage, it is up
- * to the caller to keep the string alive until Remove is called.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_AddArgumentFormatter(JSContext *cx, const char *format,
- JSArgumentFormatter formatter);
-
-extern JS_PUBLIC_API(void)
-JS_RemoveArgumentFormatter(JSContext *cx, const char *format);
-
-#endif /* JS_ARGUMENT_FORMATTER_DEFINED */
-
-extern JS_PUBLIC_API(JSBool)
-JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_ValueToFunction(JSContext *cx, jsval v);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_ValueToConstructor(JSContext *cx, jsval v);
-
-extern JS_PUBLIC_API(JSString *)
-JS_ValueToString(JSContext *cx, jsval v);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
-
-/*
- * Convert a value to a number, then to an int32, according to the ECMA rules
- * for ToInt32.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
-
-/*
- * Convert a value to a number, then to a uint32, according to the ECMA rules
- * for ToUint32.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
-
-/*
- * Convert a value to a number, then to an int32 if it fits by rounding to
- * nearest; but failing with an error report if the double is out of range
- * or unordered.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
-
-/*
- * ECMA ToUint16, for mapping a jsval to a Unicode point.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
-
-extern JS_PUBLIC_API(JSType)
-JS_TypeOfValue(JSContext *cx, jsval v);
-
-extern JS_PUBLIC_API(const char *)
-JS_GetTypeName(JSContext *cx, JSType type);
-
-/************************************************************************/
-
-/*
- * Initialization, locking, contexts, and memory allocation.
- */
-#define JS_NewRuntime JS_Init
-#define JS_DestroyRuntime JS_Finish
-#define JS_LockRuntime JS_Lock
-#define JS_UnlockRuntime JS_Unlock
-
-extern JS_PUBLIC_API(JSRuntime *)
-JS_NewRuntime(uint32 maxbytes);
-
-extern JS_PUBLIC_API(void)
-JS_DestroyRuntime(JSRuntime *rt);
-
-extern JS_PUBLIC_API(void)
-JS_ShutDown(void);
-
-JS_PUBLIC_API(void *)
-JS_GetRuntimePrivate(JSRuntime *rt);
-
-JS_PUBLIC_API(void)
-JS_SetRuntimePrivate(JSRuntime *rt, void *data);
-
-#ifdef JS_THREADSAFE
-
-extern JS_PUBLIC_API(void)
-JS_BeginRequest(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_EndRequest(JSContext *cx);
-
-/* Yield to pending GC operations, regardless of request depth */
-extern JS_PUBLIC_API(void)
-JS_YieldRequest(JSContext *cx);
-
-extern JS_PUBLIC_API(jsrefcount)
-JS_SuspendRequest(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth);
-
-#endif /* JS_THREADSAFE */
-
-extern JS_PUBLIC_API(void)
-JS_Lock(JSRuntime *rt);
-
-extern JS_PUBLIC_API(void)
-JS_Unlock(JSRuntime *rt);
-
-extern JS_PUBLIC_API(JSContext *)
-JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
-
-extern JS_PUBLIC_API(void)
-JS_DestroyContext(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_DestroyContextNoGC(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_DestroyContextMaybeGC(JSContext *cx);
-
-extern JS_PUBLIC_API(void *)
-JS_GetContextPrivate(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_SetContextPrivate(JSContext *cx, void *data);
-
-extern JS_PUBLIC_API(JSRuntime *)
-JS_GetRuntime(JSContext *cx);
-
-extern JS_PUBLIC_API(JSContext *)
-JS_ContextIterator(JSRuntime *rt, JSContext **iterp);
-
-extern JS_PUBLIC_API(JSVersion)
-JS_GetVersion(JSContext *cx);
-
-extern JS_PUBLIC_API(JSVersion)
-JS_SetVersion(JSContext *cx, JSVersion version);
-
-extern JS_PUBLIC_API(const char *)
-JS_VersionToString(JSVersion version);
-
-extern JS_PUBLIC_API(JSVersion)
-JS_StringToVersion(const char *string);
-
-/*
- * JS options are orthogonal to version, and may be freely composed with one
- * another as well as with version.
- *
- * JSOPTION_VAROBJFIX is recommended -- see the comments associated with the
- * prototypes for JS_ExecuteScript, JS_EvaluateScript, etc.
- */
-#define JSOPTION_STRICT JS_BIT(0) /* warn on dubious practice */
-#define JSOPTION_WERROR JS_BIT(1) /* convert warning to error */
-#define JSOPTION_VAROBJFIX JS_BIT(2) /* make JS_EvaluateScript use
- the last object on its 'obj'
- param's scope chain as the
- ECMA 'variables object' */
-#define JSOPTION_PRIVATE_IS_NSISUPPORTS \
- JS_BIT(3) /* context private data points
- to an nsISupports subclass */
-
-extern JS_PUBLIC_API(uint32)
-JS_GetOptions(JSContext *cx);
-
-extern JS_PUBLIC_API(uint32)
-JS_SetOptions(JSContext *cx, uint32 options);
-
-extern JS_PUBLIC_API(uint32)
-JS_ToggleOptions(JSContext *cx, uint32 options);
-
-extern JS_PUBLIC_API(const char *)
-JS_GetImplementationVersion(void);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetGlobalObject(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_SetGlobalObject(JSContext *cx, JSObject *obj);
-
-/*
- * Initialize standard JS class constructors, prototypes, and any top-level
- * functions and constants associated with the standard classes (e.g. isNaN
- * for Number).
- *
- * NB: This sets cx's global object to obj if it was null.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_InitStandardClasses(JSContext *cx, JSObject *obj);
-
-/*
- * Resolve id, which must contain either a string or an int, to a standard
- * class name in obj if possible, defining the class's constructor and/or
- * prototype and storing true in *resolved. If id does not name a standard
- * class or a top-level property induced by initializing a standard class,
- * store false in *resolved and just return true. Return false on error,
- * as usual for JSBool result-typed API entry points.
- *
- * This API can be called directly from a global object class's resolve op,
- * to define standard classes lazily. The class's enumerate op should call
- * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
- * loops any classes not yet resolved lazily.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
- JSBool *resolved);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetScopeChain(JSContext *cx);
-
-extern JS_PUBLIC_API(void *)
-JS_malloc(JSContext *cx, size_t nbytes);
-
-extern JS_PUBLIC_API(void *)
-JS_realloc(JSContext *cx, void *p, size_t nbytes);
-
-extern JS_PUBLIC_API(void)
-JS_free(JSContext *cx, void *p);
-
-extern JS_PUBLIC_API(char *)
-JS_strdup(JSContext *cx, const char *s);
-
-extern JS_PUBLIC_API(jsdouble *)
-JS_NewDouble(JSContext *cx, jsdouble d);
-
-extern JS_PUBLIC_API(JSBool)
-JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
-
-/*
- * A JS GC root is a pointer to a JSObject *, JSString *, or jsdouble * that
- * itself points into the GC heap (more recently, we support this extension:
- * a root may be a pointer to a jsval v for which JSVAL_IS_GCTHING(v) is true).
- *
- * Therefore, you never pass JSObject *obj to JS_AddRoot(cx, obj). You always
- * call JS_AddRoot(cx, &obj), passing obj by reference. And later, before obj
- * or the structure it is embedded within goes out of scope or is freed, you
- * must call JS_RemoveRoot(cx, &obj).
- *
- * Also, use JS_AddNamedRoot(cx, &structPtr->memberObj, "structPtr->memberObj")
- * in preference to JS_AddRoot(cx, &structPtr->memberObj), in order to identify
- * roots by their source callsites. This way, you can find the callsite while
- * debugging if you should fail to do JS_RemoveRoot(cx, &structPtr->memberObj)
- * before freeing structPtr's memory.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_AddRoot(JSContext *cx, void *rp);
-
-#ifdef NAME_ALL_GC_ROOTS
-#define JS_DEFINE_TO_TOKEN(def) #def
-#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def)
-#define JS_AddRoot(cx,rp) JS_AddNamedRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
-#endif
-
-extern JS_PUBLIC_API(JSBool)
-JS_AddNamedRoot(JSContext *cx, void *rp, const char *name);
-
-extern JS_PUBLIC_API(JSBool)
-JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name);
-
-extern JS_PUBLIC_API(JSBool)
-JS_RemoveRoot(JSContext *cx, void *rp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_RemoveRootRT(JSRuntime *rt, void *rp);
-
-/*
- * The last GC thing of each type (object, string, double, external string
- * types) created on a given context is kept alive until another thing of the
- * same type is created, using a newborn root in the context. These newborn
- * roots help native code protect newly-created GC-things from GC invocations
- * activated before those things can be rooted using local or global roots.
- *
- * However, the newborn roots can also entrain great gobs of garbage, so the
- * JS_GC entry point clears them for the context on which GC is being forced.
- * Embeddings may need to do likewise for all contexts.
- *
- * XXXbe See bug 40757 (http://bugzilla.mozilla.org/show_bug.cgi?id=40757),
- * which proposes switching (with an #ifdef, alas, if we want to maintain API
- * compatibility) to a JNI-like extensible local root frame stack model.
- */
-extern JS_PUBLIC_API(void)
-JS_ClearNewbornRoots(JSContext *cx);
-
-#ifdef DEBUG
-extern JS_PUBLIC_API(void)
-JS_DumpNamedRoots(JSRuntime *rt,
- void (*dump)(const char *name, void *rp, void *data),
- void *data);
-#endif
-
-/*
- * Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data).
- * The root is pointed at by rp; if the root is unnamed, name is null; data is
- * supplied from the third parameter to JS_MapGCRoots.
- *
- * The map function should return JS_MAP_GCROOT_REMOVE to cause the currently
- * enumerated root to be removed. To stop enumeration, set JS_MAP_GCROOT_STOP
- * in the return value. To keep on mapping, return JS_MAP_GCROOT_NEXT. These
- * constants are flags; you can OR them together.
- *
- * This function acquires and releases rt's GC lock around the mapping of the
- * roots table, so the map function should run to completion in as few cycles
- * as possible. Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest,
- * or any JS API entry point that acquires locks, without double-tripping or
- * deadlocking on the GC lock.
- *
- * JS_MapGCRoots returns the count of roots that were successfully mapped.
- */
-#define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */
-#define JS_MAP_GCROOT_STOP 1 /* stop mapping entries */
-#define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */
-
-typedef intN
-(* JS_DLL_CALLBACK JSGCRootMapFun)(void *rp, const char *name, void *data);
-
-extern JS_PUBLIC_API(uint32)
-JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
-
-extern JS_PUBLIC_API(JSBool)
-JS_LockGCThing(JSContext *cx, void *thing);
-
-extern JS_PUBLIC_API(JSBool)
-JS_LockGCThingRT(JSRuntime *rt, void *thing);
-
-extern JS_PUBLIC_API(JSBool)
-JS_UnlockGCThing(JSContext *cx, void *thing);
-
-extern JS_PUBLIC_API(JSBool)
-JS_UnlockGCThingRT(JSRuntime *rt, void *thing);
-
-/*
- * For implementors of JSObjectOps.mark, to mark a GC-thing reachable via a
- * property or other strong ref identified for debugging purposes by name.
- * The name argument's storage needs to live only as long as the call to
- * this routine.
- *
- * The final arg is used by GC_MARK_DEBUG code to build a ref path through
- * the GC's live thing graph. Implementors of JSObjectOps.mark should pass
- * its final arg through to this function when marking all GC-things that are
- * directly reachable from the object being marked.
- *
- * See the JSMarkOp typedef in jspubtd.h, and the JSObjectOps struct below.
- */
-extern JS_PUBLIC_API(void)
-JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg);
-
-extern JS_PUBLIC_API(void)
-JS_GC(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_MaybeGC(JSContext *cx);
-
-extern JS_PUBLIC_API(JSGCCallback)
-JS_SetGCCallback(JSContext *cx, JSGCCallback cb);
-
-extern JS_PUBLIC_API(JSGCCallback)
-JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsAboutToBeFinalized(JSContext *cx, void *thing);
-
-/*
- * Add an external string finalizer, one created by JS_NewExternalString (see
- * below) using a type-code returned from this function, and that understands
- * how to free or release the memory pointed at by JS_GetStringChars(str).
- *
- * Return a nonnegative type index if there is room for finalizer in the
- * global GC finalizers table, else return -1. If the engine is compiled
- * JS_THREADSAFE and used in a multi-threaded environment, this function must
- * be invoked on the primordial thread only, at startup -- or else the entire
- * program must single-thread itself while loading a module that calls this
- * function.
- */
-extern JS_PUBLIC_API(intN)
-JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer);
-
-/*
- * Remove finalizer from the global GC finalizers table, returning its type
- * code if found, -1 if not found.
- *
- * As with JS_AddExternalStringFinalizer, there is a threading restriction
- * if you compile the engine JS_THREADSAFE: this function may be called for a
- * given finalizer pointer on only one thread; different threads may call to
- * remove distinct finalizers safely.
- *
- * You must ensure that all strings with finalizer's type have been collected
- * before calling this function. Otherwise, string data will be leaked by the
- * GC, for want of a finalizer to call.
- */
-extern JS_PUBLIC_API(intN)
-JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer);
-
-/*
- * Create a new JSString whose chars member refers to external memory, i.e.,
- * memory requiring special, type-specific finalization. The type code must
- * be a nonnegative return value from JS_AddExternalStringFinalizer.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type);
-
-/*
- * Returns the external-string finalizer index for this string, or -1 if it is
- * an "internal" (native to JS engine) string.
- */
-extern JS_PUBLIC_API(intN)
-JS_GetExternalStringGCType(JSRuntime *rt, JSString *str);
-
-/*
- * Sets maximum (if stack grows upward) or minimum (downward) legal stack byte
- * address in limitAddr for the thread or process stack used by cx. To disable
- * stack size checking, pass 0 for limitAddr.
- */
-extern JS_PUBLIC_API(void)
-JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr);
-
-/************************************************************************/
-
-/*
- * Classes, objects, and properties.
- */
-
-/* For detailed comments on the function pointer types, see jspubtd.h. */
-struct JSClass {
- const char *name;
- uint32 flags;
-
- /* Mandatory non-null function pointer members. */
- JSPropertyOp addProperty;
- JSPropertyOp delProperty;
- JSPropertyOp getProperty;
- JSPropertyOp setProperty;
- JSEnumerateOp enumerate;
- JSResolveOp resolve;
- JSConvertOp convert;
- JSFinalizeOp finalize;
-
- /* Optionally non-null members start here. */
- JSGetObjectOps getObjectOps;
- JSCheckAccessOp checkAccess;
- JSNative call;
- JSNative construct;
- JSXDRObjectOp xdrObject;
- JSHasInstanceOp hasInstance;
- JSMarkOp mark;
- jsword spare;
-};
-
-#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
-#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */
-#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */
-#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */
-#define JSCLASS_SHARE_ALL_PROPERTIES (1<<4) /* all properties are SHARED */
-#define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets starting
- object in prototype chain
- passed in via *objp in/out
- parameter */
-
-/*
- * To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or
- * JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where
- * n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1.
- */
-#define JSCLASS_RESERVED_SLOTS_SHIFT 8 /* room for 8 flags below */
-#define JSCLASS_RESERVED_SLOTS_WIDTH 8 /* and 16 above this field */
-#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH)
-#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \
- << JSCLASS_RESERVED_SLOTS_SHIFT)
-#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \
- >> JSCLASS_RESERVED_SLOTS_SHIFT) \
- & JSCLASS_RESERVED_SLOTS_MASK)
-
-/* Initializer for unused members of statically initialized JSClass structs. */
-#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
-
-/* For detailed comments on these function pointer types, see jspubtd.h. */
-struct JSObjectOps {
- /* Mandatory non-null function pointer members. */
- JSNewObjectMapOp newObjectMap;
- JSObjectMapOp destroyObjectMap;
- JSLookupPropOp lookupProperty;
- JSDefinePropOp defineProperty;
- JSPropertyIdOp getProperty;
- JSPropertyIdOp setProperty;
- JSAttributesOp getAttributes;
- JSAttributesOp setAttributes;
- JSPropertyIdOp deleteProperty;
- JSConvertOp defaultValue;
- JSNewEnumerateOp enumerate;
- JSCheckAccessIdOp checkAccess;
-
- /* Optionally non-null members start here. */
- JSObjectOp thisObject;
- JSPropertyRefOp dropProperty;
- JSNative call;
- JSNative construct;
- JSXDRObjectOp xdrObject;
- JSHasInstanceOp hasInstance;
- JSSetObjectSlotOp setProto;
- JSSetObjectSlotOp setParent;
- JSMarkOp mark;
- JSFinalizeOp clear;
- JSGetRequiredSlotOp getRequiredSlot;
- JSSetRequiredSlotOp setRequiredSlot;
-};
-
-/*
- * Classes that expose JSObjectOps via a non-null getObjectOps class hook may
- * derive a property structure from this struct, return a pointer to it from
- * lookupProperty and defineProperty, and use the pointer to avoid rehashing
- * in getAttributes and setAttributes.
- *
- * The jsid type contains either an int jsval (see JSVAL_IS_INT above), or an
- * internal pointer that is opaque to users of this API, but which users may
- * convert from and to a jsval using JS_ValueToId and JS_IdToValue.
- */
-struct JSProperty {
- jsid id;
-};
-
-struct JSIdArray {
- jsint length;
- jsid vector[1]; /* actually, length jsid words */
-};
-
-extern JS_PUBLIC_API(void)
-JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ValueToId(JSContext *cx, jsval v, jsid *idp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IdToValue(JSContext *cx, jsid id, jsval *vp);
-
-#define JSRESOLVE_QUALIFIED 0x01 /* resolve a qualified property id */
-#define JSRESOLVE_ASSIGNING 0x02 /* resolve on the left of assignment */
-
-extern JS_PUBLIC_API(JSBool)
-JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EnumerateStub(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
-
-extern JS_PUBLIC_API(void)
-JS_FinalizeStub(JSContext *cx, JSObject *obj);
-
-struct JSConstDoubleSpec {
- jsdouble dval;
- const char *name;
- uint8 flags;
- uint8 spare[3];
-};
-
-/*
- * To define an array element rather than a named property member, cast the
- * element's index to (const char *) and initialize name with it, and set the
- * JSPROP_INDEX bit in flags.
- */
-struct JSPropertySpec {
- const char *name;
- int8 tinyid;
- uint8 flags;
- JSPropertyOp getter;
- JSPropertyOp setter;
-};
-
-struct JSFunctionSpec {
- const char *name;
- JSNative call;
- uint8 nargs;
- uint8 flags;
- uint16 extra; /* number of arg slots for local GC roots */
-};
-
-extern JS_PUBLIC_API(JSObject *)
-JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
- JSClass *clasp, JSNative constructor, uintN nargs,
- JSPropertySpec *ps, JSFunctionSpec *fs,
- JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
-
-#ifdef JS_THREADSAFE
-extern JS_PUBLIC_API(JSClass *)
-JS_GetClass(JSContext *cx, JSObject *obj);
-
-#define JS_GET_CLASS(cx,obj) JS_GetClass(cx, obj)
-#else
-extern JS_PUBLIC_API(JSClass *)
-JS_GetClass(JSObject *obj);
-
-#define JS_GET_CLASS(cx,obj) JS_GetClass(obj)
-#endif
-
-extern JS_PUBLIC_API(JSBool)
-JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv);
-
-extern JS_PUBLIC_API(void *)
-JS_GetPrivate(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetPrivate(JSContext *cx, JSObject *obj, void *data);
-
-extern JS_PUBLIC_API(void *)
-JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
- jsval *argv);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetPrototype(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetParent(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetConstructor(JSContext *cx, JSObject *proto);
-
-/*
- * Get a unique identifier for obj, good for the lifetime of obj (even if it
- * is moved by a copying GC). Return false on failure (likely out of memory),
- * and true with *idp containing the unique id on success.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent, uintN argc, jsval *argv);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
- JSObject *proto, uintN attrs);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, 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_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
- 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_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
- uintN attrs, JSBool *foundp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
- int8 tinyid, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs);
-
-extern JS_PUBLIC_API(JSBool)
-JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
- const char *alias);
-
-extern JS_PUBLIC_API(JSBool)
-JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- 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)
-JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- int8 tinyid, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs);
-
-extern JS_PUBLIC_API(JSBool)
-JS_LookupUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetUCProperty(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DeleteUCProperty2(JSContext *cx, JSObject *obj,
- const jschar *name, size_t namelen,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsArrayObject(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length);
-
-extern JS_PUBLIC_API(JSBool)
-JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
-
-extern JS_PUBLIC_API(JSBool)
-JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias);
-
-extern JS_PUBLIC_API(JSBool)
-JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval);
-
-extern JS_PUBLIC_API(void)
-JS_ClearScope(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSIdArray *)
-JS_Enumerate(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
- jsval *vp, uintN *attrsp);
-
-extern JS_PUBLIC_API(JSCheckAccessOp)
-JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v);
-
-/************************************************************************/
-
-/*
- * Security protocol.
- */
-struct JSPrincipals {
- char *codebase;
- void * (* JS_DLL_CALLBACK getPrincipalArray)(JSContext *cx, JSPrincipals *);
- JSBool (* JS_DLL_CALLBACK globalPrivilegesEnabled)(JSContext *cx, JSPrincipals *);
-
- /* Don't call "destroy"; use reference counting macros below. */
- jsrefcount refcount;
- void (* JS_DLL_CALLBACK destroy)(JSContext *cx, struct JSPrincipals *);
-};
-
-#ifdef JS_THREADSAFE
-#define JSPRINCIPALS_HOLD(cx, principals) JS_HoldPrincipals(cx,principals)
-#define JSPRINCIPALS_DROP(cx, principals) JS_DropPrincipals(cx,principals)
-
-extern JS_PUBLIC_API(jsrefcount)
-JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals);
-
-extern JS_PUBLIC_API(jsrefcount)
-JS_DropPrincipals(JSContext *cx, JSPrincipals *principals);
-
-#else
-#define JSPRINCIPALS_HOLD(cx, principals) (++(principals)->refcount)
-#define JSPRINCIPALS_DROP(cx, principals) \
- ((--(principals)->refcount == 0) \
- ? ((*(principals)->destroy)((cx), (principals)), 0) \
- : (principals)->refcount)
-#endif
-
-extern JS_PUBLIC_API(JSPrincipalsTranscoder)
-JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px);
-
-extern JS_PUBLIC_API(JSObjectPrincipalsFinder)
-JS_SetObjectPrincipalsFinder(JSContext *cx, JSObjectPrincipalsFinder fop);
-
-/************************************************************************/
-
-/*
- * Functions and scripts.
- */
-extern JS_PUBLIC_API(JSFunction *)
-JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags,
- JSObject *parent, const char *name);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFunctionObject(JSFunction *fun);
-
-/*
- * Deprecated, useful only for diagnostics. Use JS_GetFunctionId instead for
- * anonymous vs. "anonymous" disambiguation and Unicode fidelity.
- */
-extern JS_PUBLIC_API(const char *)
-JS_GetFunctionName(JSFunction *fun);
-
-/*
- * Return the function's identifier as a JSString, or null if fun is unnamed.
- * The returned string lives as long as fun, so you don't need to root a saved
- * reference to it if fun is well-connected or rooted, and provided you bound
- * the use of the saved reference by fun's lifetime.
- *
- * Prefer JS_GetFunctionId over JS_GetFunctionName because it returns null for
- * truly anonymous functions, and because it doesn't chop to ISO-Latin-1 chars
- * from UTF-16-ish jschars.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_GetFunctionId(JSFunction *fun);
-
-/*
- * Return JSFUN_* flags for fun.
- */
-extern JS_PUBLIC_API(uintN)
-JS_GetFunctionFlags(JSFunction *fun);
-
-/*
- * Infallible predicate to test whether obj is a function object (faster than
- * comparing obj's class name to "Function", but equivalent unless someone has
- * overwritten the "Function" identifier with a different constructor and then
- * created instances using that constructor that might be passed in as obj).
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ObjectIsFunction(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
- uintN nargs, uintN attrs);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
-
-/*
- * Given a buffer, return JS_FALSE if the buffer might become a valid
- * javascript statement with the addition of more lines. Otherwise return
- * JS_TRUE. The intent is to support interactive compilation - accumulate
- * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
- * the compiler.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
- const char *bytes, size_t length);
-
-/*
- * The JSScript objects returned by the following functions refer to string and
- * other kinds of literals, including doubles and RegExp objects. These
- * literals are vulnerable to garbage collection; to root script objects and
- * prevent literals from being collected, create a rootable object using
- * JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root.
- */
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileScript(JSContext *cx, JSObject *obj,
- const char *bytes, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const char *bytes, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileUCScript(JSContext *cx, JSObject *obj,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
- FILE *fh);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
- const char *filename, FILE *fh,
- JSPrincipals *principals);
-
-/*
- * NB: you must use JS_NewScriptObject and root a pointer to its return value
- * in order to keep a JSScript and its atoms safe from garbage collection after
- * creating the script via JS_Compile* and before a JS_ExecuteScript* call.
- * E.g., and without error checks:
- *
- * JSScript *script = JS_CompileFile(cx, global, filename);
- * JSObject *scrobj = JS_NewScriptObject(cx, script);
- * JS_AddNamedRoot(cx, &scrobj, "scrobj");
- * do {
- * jsval result;
- * JS_ExecuteScript(cx, global, script, &result);
- * JS_GC();
- * } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result));
- * JS_RemoveRoot(cx, &scrobj);
- */
-extern JS_PUBLIC_API(JSObject *)
-JS_NewScriptObject(JSContext *cx, JSScript *script);
-
-/*
- * Infallible getter for a script's object. If JS_NewScriptObject has not been
- * called on script yet, the return value will be null.
- */
-extern JS_PUBLIC_API(JSObject *)
-JS_GetScriptObject(JSScript *script);
-
-extern JS_PUBLIC_API(void)
-JS_DestroyScript(JSContext *cx, JSScript *script);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
- uintN nargs, const char **argnames,
- const char *bytes, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals, const char *name,
- uintN nargs, const char **argnames,
- const char *bytes, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
- uintN nargs, const char **argnames,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals, const char *name,
- uintN nargs, const char **argnames,
- const jschar *chars, size_t length,
- const char *filename, uintN lineno);
-
-extern JS_PUBLIC_API(JSString *)
-JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
- uintN indent);
-
-/*
- * API extension: OR this into indent to avoid pretty-printing the decompiled
- * source resulting from JS_DecompileFunction{,Body}.
- */
-#define JS_DONT_PRETTY_PRINT ((uintN)0x8000)
-
-extern JS_PUBLIC_API(JSString *)
-JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent);
-
-extern JS_PUBLIC_API(JSString *)
-JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent);
-
-/*
- * NB: JS_ExecuteScript, JS_ExecuteScriptPart, and the JS_Evaluate*Script*
- * quadruplets all use the obj parameter as the initial scope chain header,
- * the 'this' keyword value, and the variables object (ECMA parlance for where
- * 'var' and 'function' bind names) of the execution context for script.
- *
- * Using obj as the variables object is problematic if obj's parent (which is
- * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in
- * this case, variables created by 'var x = 0', e.g., go in obj, but variables
- * created by assignment to an unbound id, 'x = 0', go in the last object on
- * the scope chain linked by parent.
- *
- * ECMA calls that last scoping object the "global object", but note that many
- * embeddings have several such objects. ECMA requires that "global code" be
- * executed with the variables object equal to this global object. But these
- * JS API entry points provide freedom to execute code against a "sub-global",
- * i.e., a parented or scoped object, in which case the variables object will
- * differ from the last object on the scope chain, resulting in confusing and
- * non-ECMA explicit vs. implicit variable creation.
- *
- * Caveat embedders: unless you already depend on this buggy variables object
- * binding behavior, you should call JS_SetOptions(cx, JSOPTION_VAROBJFIX) or
- * JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_VAROBJFIX) -- the latter if
- * someone may have set other options on cx already -- for each context in the
- * application, if you pass parented objects as the obj parameter, or may ever
- * pass such objects in the future.
- *
- * Why a runtime option? The alternative is to add six or so new API entry
- * points with signatures matching the following six, and that doesn't seem
- * worth the code bloat cost. Such new entry points would probably have less
- * obvious names, too, so would not tend to be used. The JS_SetOption call,
- * OTOH, can be more easily hacked into existing code that does not depend on
- * the bug; such code can continue to use the familiar JS_EvaluateScript,
- * etc., entry points.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval);
-
-/*
- * Execute either the function-defining prolog of a script, or the script's
- * main body, but not both.
- */
-typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart;
-
-extern JS_PUBLIC_API(JSBool)
-JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
- JSExecPart part, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateScript(JSContext *cx, JSObject *obj,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
- const jschar *chars, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
- JSPrincipals *principals,
- const jschar *chars, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
- jsval *argv, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
- jsval *argv, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
- jsval *argv, jsval *rval);
-
-extern JS_PUBLIC_API(JSBranchCallback)
-JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsRunning(JSContext *cx);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsConstructing(JSContext *cx);
-
-/*
- * Returns true if a script is executing and its current bytecode is a set
- * (assignment) operation, even if there are native (no script) stack frames
- * between the script and the caller to JS_IsAssigning.
- */
-extern JS_FRIEND_API(JSBool)
-JS_IsAssigning(JSContext *cx);
-
-/*
- * Set the second return value, which should be a string or int jsval that
- * identifies a property in the returned object, to form an ECMA reference
- * type value (obj, id). Only native methods can return reference types,
- * and if the returned value is used on the left-hand side of an assignment
- * op, the identified property will be set. If the return value is in an
- * r-value, the interpreter just gets obj[id]'s value.
- */
-extern JS_PUBLIC_API(void)
-JS_SetCallReturnValue2(JSContext *cx, jsval v);
-
-/************************************************************************/
-
-/*
- * Strings.
- *
- * NB: JS_NewString takes ownership of bytes on success, avoiding a copy; but
- * on error (signified by null return), it leaves bytes owned by the caller.
- * So the caller must free bytes in the error case, if it has no use for them.
- * In contrast, all the JS_New*StringCopy* functions do not take ownership of
- * the character memory passed to them -- they copy it.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_NewString(JSContext *cx, char *bytes, size_t length);
-
-extern JS_PUBLIC_API(JSString *)
-JS_NewStringCopyN(JSContext *cx, const char *s, size_t n);
-
-extern JS_PUBLIC_API(JSString *)
-JS_NewStringCopyZ(JSContext *cx, const char *s);
-
-extern JS_PUBLIC_API(JSString *)
-JS_InternString(JSContext *cx, const char *s);
-
-extern JS_PUBLIC_API(JSString *)
-JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
-
-extern JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
-
-extern JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
-
-extern JS_PUBLIC_API(JSString *)
-JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
-
-extern JS_PUBLIC_API(JSString *)
-JS_InternUCString(JSContext *cx, const jschar *s);
-
-extern JS_PUBLIC_API(char *)
-JS_GetStringBytes(JSString *str);
-
-extern JS_PUBLIC_API(jschar *)
-JS_GetStringChars(JSString *str);
-
-extern JS_PUBLIC_API(size_t)
-JS_GetStringLength(JSString *str);
-
-extern JS_PUBLIC_API(intN)
-JS_CompareStrings(JSString *str1, JSString *str2);
-
-/*
- * Mutable string support. A string's characters are never mutable in this JS
- * implementation, but a growable string has a buffer that can be reallocated,
- * and a dependent string is a substring of another (growable, dependent, or
- * immutable) string. The direct data members of the (opaque to API clients)
- * JSString struct may be changed in a single-threaded way for growable and
- * dependent strings.
- *
- * Therefore mutable strings cannot be used by more than one thread at a time.
- * You may call JS_MakeStringImmutable to convert the string from a mutable
- * (growable or dependent) string to an immutable (and therefore thread-safe)
- * string. The engine takes care of converting growable and dependent strings
- * to immutable for you if you store strings in multi-threaded objects using
- * JS_SetProperty or kindred API entry points.
- *
- * If you store a JSString pointer in a native data structure that is (safely)
- * accessible to multiple threads, you must call JS_MakeStringImmutable before
- * retiring the store.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length);
-
-/*
- * Create a dependent string, i.e., a string that owns no character storage,
- * but that refers to a slice of another string's chars. Dependent strings
- * are mutable by definition, so the thread safety comments above apply.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_NewDependentString(JSContext *cx, JSString *str, size_t start,
- size_t length);
-
-/*
- * Concatenate two strings, resulting in a new growable string. If you create
- * the left string and pass it to JS_ConcatStrings on a single thread, try to
- * use JS_NewGrowableString to create the left string -- doing so helps Concat
- * avoid allocating a new buffer for the result and copying left's chars into
- * the new buffer. See above for thread safety comments.
- */
-extern JS_PUBLIC_API(JSString *)
-JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
-
-/*
- * Convert a dependent string into an independent one. This function does not
- * change the string's mutability, so the thread safety comments above apply.
- */
-extern JS_PUBLIC_API(const jschar *)
-JS_UndependString(JSContext *cx, JSString *str);
-
-/*
- * Convert a mutable string (either growable or dependent) into an immutable,
- * thread-safe one.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_MakeStringImmutable(JSContext *cx, JSString *str);
-
-/************************************************************************/
-
-/*
- * Locale specific string conversion callback.
- */
-struct JSLocaleCallbacks {
- JSLocaleToUpperCase localeToUpperCase;
- JSLocaleToLowerCase localeToLowerCase;
- JSLocaleCompare localeCompare;
-};
-
-/*
- * Establish locale callbacks. The pointer must persist as long as the
- * JSContext. Passing NULL restores the default behaviour.
- */
-extern JS_PUBLIC_API(void)
-JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks);
-
-/*
- * Return the address of the current locale callbacks struct, which may
- * be NULL.
- */
-extern JS_PUBLIC_API(JSLocaleCallbacks *)
-JS_GetLocaleCallbacks(JSContext *cx);
-
-/************************************************************************/
-
-/*
- * Error reporting.
- */
-
-/*
- * Report an exception represented by the sprintf-like conversion of format
- * and its arguments. This exception message string is passed to a pre-set
- * JSErrorReporter function (set by JS_SetErrorReporter; see jspubtd.h for
- * the JSErrorReporter typedef).
- */
-extern JS_PUBLIC_API(void)
-JS_ReportError(JSContext *cx, const char *format, ...);
-
-/*
- * Use an errorNumber to retrieve the format string, args are char *
- */
-extern JS_PUBLIC_API(void)
-JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
- void *userRef, const uintN errorNumber, ...);
-
-/*
- * Use an errorNumber to retrieve the format string, args are jschar *
- */
-extern JS_PUBLIC_API(void)
-JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
- void *userRef, const uintN errorNumber, ...);
-
-/*
- * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
- * Return true if there was no error trying to issue the warning, and if the
- * warning was not converted into an error due to the JSOPTION_WERROR option
- * being set, false otherwise.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_ReportWarning(JSContext *cx, const char *format, ...);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags,
- JSErrorCallback errorCallback, void *userRef,
- const uintN errorNumber, ...);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags,
- JSErrorCallback errorCallback, void *userRef,
- const uintN errorNumber, ...);
-
-/*
- * Complain when out of memory.
- */
-extern JS_PUBLIC_API(void)
-JS_ReportOutOfMemory(JSContext *cx);
-
-struct JSErrorReport {
- const char *filename; /* source file name, URL, etc., or null */
- uintN lineno; /* source line number */
- const char *linebuf; /* offending source line without final \n */
- const char *tokenptr; /* pointer to error token in linebuf */
- const jschar *uclinebuf; /* unicode (original) line buffer */
- const jschar *uctokenptr; /* unicode (original) token pointer */
- uintN flags; /* error/warning, etc. */
- uintN errorNumber; /* the error number, e.g. see js.msg */
- const jschar *ucmessage; /* the (default) error message */
- const jschar **messageArgs; /* arguments for the error message */
-};
-
-/*
- * JSErrorReport flag values. These may be freely composed.
- */
-#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */
-#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
-#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */
-#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */
-
-/*
- * 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_IsExceptionPending if
- * JS_ExecuteScript returns failure, and signal or propagate the exception, as
- * appropriate.
- */
-#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0)
-#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0)
-#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0)
-
-extern JS_PUBLIC_API(JSErrorReporter)
-JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
-
-/************************************************************************/
-
-/*
- * Regular Expressions.
- */
-#define JSREG_FOLD 0x01 /* fold uppercase to lowercase */
-#define JSREG_GLOB 0x02 /* global exec, creates array of matches */
-#define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */
-
-extern JS_PUBLIC_API(JSObject *)
-JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags);
-
-extern JS_PUBLIC_API(void)
-JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline);
-
-extern JS_PUBLIC_API(void)
-JS_ClearRegExpStatics(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_ClearRegExpRoots(JSContext *cx);
-
-/* TODO: compile, exec, get/set other statics... */
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsExceptionPending(JSContext *cx);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetPendingException(JSContext *cx, jsval *vp);
-
-extern JS_PUBLIC_API(void)
-JS_SetPendingException(JSContext *cx, jsval v);
-
-extern JS_PUBLIC_API(void)
-JS_ClearPendingException(JSContext *cx);
-
-/*
- * Save the current exception state. This takes a snapshot of cx's current
- * exception state without making any change to that state.
- *
- * The returned state pointer MUST be passed later to JS_RestoreExceptionState
- * (to restore that saved state, overriding any more recent state) or else to
- * JS_DropExceptionState (to free the state struct in case it is not correct
- * or desirable to restore it). Both Restore and Drop free the state struct,
- * so callers must stop using the pointer returned from Save after calling the
- * Release or Drop API.
- */
-extern JS_PUBLIC_API(JSExceptionState *)
-JS_SaveExceptionState(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state);
-
-extern JS_PUBLIC_API(void)
-JS_DropExceptionState(JSContext *cx, JSExceptionState *state);
-
-/*
- * If the given value is an exception object that originated from an error,
- * the exception will contain an error report struct, and this API will return
- * the address of that struct. Otherwise, it returns NULL. The lifetime of
- * the error report struct that might be returned is the same as the lifetime
- * of the exception object.
- */
-extern JS_PUBLIC_API(JSErrorReport *)
-JS_ErrorFromException(JSContext *cx, jsval v);
-
-#ifdef JS_THREADSAFE
-
-/*
- * Associate the current thread with the given context. This is done
- * implicitly by JS_NewContext.
- *
- * Returns the old thread id for this context, which should be treated as
- * an opaque value. This value is provided for comparison to 0, which
- * indicates that ClearContextThread has been called on this context
- * since the last SetContextThread, or non-0, which indicates the opposite.
- */
-extern JS_PUBLIC_API(jsword)
-JS_GetContextThread(JSContext *cx);
-
-extern JS_PUBLIC_API(jsword)
-JS_SetContextThread(JSContext *cx);
-
-extern JS_PUBLIC_API(intN)
-JS_ClearContextThread(JSContext *cx);
-
-#endif /* JS_THREADSAFE */
-
-/************************************************************************/
-
-JS_END_EXTERN_C
-
-#endif /* jsapi_h___ */
diff --git a/src/extension/script/js/jsarena.c b/src/extension/script/js/jsarena.c
deleted file mode 100644
index 4cc2e7c53..000000000
--- a/src/extension/script/js/jsarena.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * Lifetime-based fast allocation, inspired by much prior art, including
- * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
- * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsbit.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jslock.h"
-
-static JSArena *arena_freelist;
-
-#ifdef JS_THREADSAFE
-static JSLock *arena_freelist_lock;
-#endif
-
-#ifdef JS_ARENAMETER
-static JSArenaStats *arena_stats_list;
-
-#define COUNT(pool,what) (pool)->stats.what++
-#else
-#define COUNT(pool,what) /* nothing */
-#endif
-
-#define JS_ARENA_DEFAULT_ALIGN sizeof(double)
-
-JS_PUBLIC_API(void)
-JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
-{
-#ifdef JS_THREADSAFE
- /* Must come through here once in primordial thread to init safely! */
- if (!arena_freelist_lock) {
- arena_freelist_lock = JS_NEW_LOCK();
- JS_ASSERT(arena_freelist_lock);
- }
-#endif
- if (align == 0)
- align = JS_ARENA_DEFAULT_ALIGN;
- pool->mask = JS_BITMASK(JS_CeilingLog2(align));
- pool->first.next = NULL;
- pool->first.base = pool->first.avail = pool->first.limit =
- JS_ARENA_ALIGN(pool, &pool->first + 1);
- pool->current = &pool->first;
- pool->arenasize = size;
-#ifdef JS_ARENAMETER
- memset(&pool->stats, 0, sizeof pool->stats);
- pool->stats.name = strdup(name);
- pool->stats.next = arena_stats_list;
- arena_stats_list = &pool->stats;
-#endif
-}
-
-/*
- * An allocation that consumes more than pool->arenasize also has a header
- * pointing back to its previous arena's next member. This header is not
- * included in [a->base, a->limit), so its space can't be wrongly claimed.
- *
- * As the header is a pointer, it must be well-aligned. If pool->mask is
- * greater than or equal to POINTER_MASK, the header just preceding a->base
- * for an oversized arena a is well-aligned, because a->base is well-aligned.
- * However, we may need to add more space to pad the JSArena ** back-pointer
- * so that it lies just behind a->base, because a might not be aligned such
- * that (jsuword)(a + 1) is on a pointer boundary.
- *
- * By how much must we pad? Let M be the alignment modulus for pool and P
- * the modulus for a pointer. Given M >= P, the greatest distance between a
- * pointer aligned on an M boundary and one aligned on a P boundary is M-P.
- * If M and P are powers of two, then M-P = (pool->mask - POINTER_MASK).
- *
- * How much extra padding might spill over unused into the remainder of the
- * allocation, in the worst case (where M > P)?
- *
- * If we add M-P to the nominal back-pointer address and then round down to
- * align on a P boundary, we will use at most M-P bytes of padding, and at
- * least P (M > P => M >= 2P; M == 2P gives the least padding, P). So if we
- * use P bytes of padding, then we will overallocate a by P+M-1 bytes, as we
- * also add M-1 to the estimated size in case malloc returns an odd pointer.
- * a->limit must include this overestimation to satisfy a->avail in [a->base,
- * a->limit].
- *
- * Similarly, if pool->mask is less than POINTER_MASK, we must include enough
- * space in the header size to align the back-pointer on a P boundary so that
- * it can be found by subtracting P from a->base. This means a->base must be
- * on a P boundary, even though subsequent allocations from a may be aligned
- * on a lesser (M) boundary. Given powers of two M and P as above, the extra
- * space needed when P > M is P-M or POINTER_MASK - pool->mask.
- *
- * The size of a header including padding is given by the HEADER_SIZE macro,
- * below, for any pool (for any value of M).
- *
- * The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or
- * HEADER_BASE_MASK(pool).
- *
- * PTR_TO_HEADER computes the address of the back-pointer, given an oversized
- * allocation at p. By definition, p must be a->base for the arena a that
- * contains p. GET_HEADER and SET_HEADER operate on an oversized arena a, in
- * the case of SET_HEADER with back-pointer ap.
- */
-#define POINTER_MASK ((jsuword)(JS_ALIGN_OF_POINTER - 1))
-#define HEADER_SIZE(pool) (sizeof(JSArena **) \
- + (((pool)->mask < POINTER_MASK) \
- ? POINTER_MASK - (pool)->mask \
- : (pool)->mask - POINTER_MASK))
-#define HEADER_BASE_MASK(pool) ((pool)->mask | POINTER_MASK)
-#define PTR_TO_HEADER(pool,p) (JS_ASSERT(((jsuword)(p) \
- & HEADER_BASE_MASK(pool)) \
- == 0), \
- (JSArena ***)(p) - 1)
-#define GET_HEADER(pool,a) (*PTR_TO_HEADER(pool, (a)->base))
-#define SET_HEADER(pool,a,ap) (*PTR_TO_HEADER(pool, (a)->base) = (ap))
-
-JS_PUBLIC_API(void *)
-JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
-{
- JSArena **ap, **bp, *a, *b;
- jsuword extra, hdrsz, gross, sz;
- void *p;
-
- /* Search pool from current forward till we find or make enough space. */
- JS_ASSERT((nb & pool->mask) == 0);
- for (a = pool->current; a->avail + nb > a->limit; pool->current = a) {
- ap = &a->next;
- if (!*ap) {
- /* Not enough space in pool -- try to reclaim a free arena. */
- extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0;
- hdrsz = sizeof *a + extra + pool->mask;
- gross = hdrsz + JS_MAX(nb, pool->arenasize);
- bp = &arena_freelist;
- JS_ACQUIRE_LOCK(arena_freelist_lock);
- while ((b = *bp) != NULL) {
- /*
- * Insist on exact arenasize match if nb is not greater than
- * arenasize. Otherwise take any arena big enough, but not by
- * more than gross + arenasize.
- */
- sz = JS_UPTRDIFF(b->limit, b);
- if (extra
- ? sz >= gross && sz <= gross + pool->arenasize
- : sz == gross) {
- *bp = b->next;
- JS_RELEASE_LOCK(arena_freelist_lock);
- b->next = NULL;
- COUNT(pool, nreclaims);
- goto claim;
- }
- bp = &b->next;
- }
-
- /* Nothing big enough on the freelist, so we must malloc. */
- JS_RELEASE_LOCK(arena_freelist_lock);
- b = (JSArena *) malloc(gross);
- if (!b)
- return 0;
- b->next = NULL;
- b->limit = (jsuword)b + gross;
- JS_COUNT_ARENA(pool,++);
- COUNT(pool, nmallocs);
-
- claim:
- /* If oversized, store ap in the header, just before a->base. */
- *ap = a = b;
- JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
- if (extra) {
- a->base = a->avail =
- ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
- SET_HEADER(pool, a, ap);
- } else {
- a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1);
- }
- continue;
- }
- a = *ap; /* move to next arena */
- }
-
- p = (void *)a->avail;
- a->avail += nb;
- JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
- return p;
-}
-
-JS_PUBLIC_API(void *)
-JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
-{
- JSArena **ap, *a, *b;
- jsuword boff, aoff, extra, hdrsz, gross;
-
- /*
- * Use the oversized-single-allocation header to avoid searching for ap.
- * See JS_ArenaAllocate, the SET_HEADER call.
- */
- if (size > pool->arenasize) {
- ap = *PTR_TO_HEADER(pool, p);
- a = *ap;
- } else {
- ap = &pool->first.next;
- while ((a = *ap) != pool->current)
- ap = &a->next;
- }
-
- JS_ASSERT(a->base == (jsuword)p);
- boff = JS_UPTRDIFF(a->base, a);
- aoff = size + incr;
- JS_ASSERT(aoff > pool->arenasize);
- extra = HEADER_SIZE(pool); /* oversized header holds ap */
- hdrsz = sizeof *a + extra + pool->mask; /* header and alignment slop */
- gross = hdrsz + aoff;
- a = (JSArena *) realloc(a, gross);
- if (!a)
- return NULL;
-#ifdef JS_ARENAMETER
- pool->stats.nreallocs++;
-#endif
-
- if (a != *ap) {
- /* Oops, realloc moved the allocation: update other pointers to a. */
- if (pool->current == *ap)
- pool->current = a;
- b = a->next;
- if (b && b->avail - b->base > pool->arenasize) {
- JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
- SET_HEADER(pool, b, &a->next);
- }
-
- /* Now update *ap, the next link of the arena before a. */
- *ap = a;
- }
-
- a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
- a->limit = (jsuword)a + gross;
- a->avail = JS_ARENA_ALIGN(pool, a->base + aoff);
- JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
-
- /* Check whether realloc aligned differently, and copy if necessary. */
- if (boff != JS_UPTRDIFF(a->base, a))
- memmove((void *)a->base, (char *)a + boff, size);
-
- /* Store ap in the oversized-load arena header. */
- SET_HEADER(pool, a, ap);
- return (void *)a->base;
-}
-
-JS_PUBLIC_API(void *)
-JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
-{
- void *newp;
-
- /*
- * If p points to an oversized allocation, it owns an entire arena, so we
- * can simply realloc the arena.
- */
- if (size > pool->arenasize)
- return JS_ArenaRealloc(pool, p, size, incr);
-
- JS_ARENA_ALLOCATE(newp, pool, size + incr);
- if (newp)
- memcpy(newp, p, size);
- return newp;
-}
-
-/*
- * Free tail arenas linked after head, which may not be the true list head.
- * Reset pool->current to point to head in case it pointed at a tail arena.
- */
-static void
-FreeArenaList(JSArenaPool *pool, JSArena *head, JSBool reallyFree)
-{
- JSArena **ap, *a;
-
- ap = &head->next;
- a = *ap;
- if (!a)
- return;
-
-#ifdef DEBUG
- do {
- JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
- a->avail = a->base;
- JS_CLEAR_UNUSED(a);
- } while ((a = a->next) != NULL);
- a = *ap;
-#endif
-
- if (reallyFree) {
- do {
- *ap = a->next;
- JS_CLEAR_ARENA(a);
- JS_COUNT_ARENA(pool,--);
- free(a);
- } while ((a = *ap) != NULL);
- } else {
- /* Insert the whole arena chain at the front of the freelist. */
- do {
- ap = &(*ap)->next;
- } while (*ap);
- JS_ACQUIRE_LOCK(arena_freelist_lock);
- *ap = arena_freelist;
- arena_freelist = a;
- JS_RELEASE_LOCK(arena_freelist_lock);
- head->next = NULL;
- }
-
- pool->current = head;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaRelease(JSArenaPool *pool, char *mark)
-{
- JSArena *a;
-
- for (a = &pool->first; a; a = a->next) {
- JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
-
- if (JS_UPTRDIFF(mark, a->base) <= JS_UPTRDIFF(a->avail, a->base)) {
- a->avail = JS_ARENA_ALIGN(pool, mark);
- JS_ASSERT(a->avail <= a->limit);
- FreeArenaList(pool, a, JS_TRUE);
- return;
- }
- }
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size)
-{
- JSArena **ap, *a, *b;
- jsuword q;
-
- /*
- * If the allocation is oversized, it consumes an entire arena, and it has
- * a header just before the allocation pointing back to its predecessor's
- * next member. Otherwise, we have to search pool for a.
- */
- if (size > pool->arenasize) {
- ap = *PTR_TO_HEADER(pool, p);
- a = *ap;
- } else {
- q = (jsuword)p + size;
- q = JS_ARENA_ALIGN(pool, q);
- ap = &pool->first.next;
- while ((a = *ap) != NULL) {
- JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
-
- if (a->avail == q) {
- /*
- * If a is consumed by the allocation at p, we can free it to
- * the malloc heap.
- */
- if (a->base == (jsuword)p)
- break;
-
- /*
- * We can't free a, but we can "retract" its avail cursor --
- * whether there are others after it in pool.
- */
- a->avail = (jsuword)p;
- return;
- }
- ap = &a->next;
- }
- }
-
- /*
- * At this point, a is doomed, so ensure that pool->current doesn't point
- * at it. What's more, force future allocations to scavenge all arenas on
- * pool, in case some have free space.
- */
- if (pool->current == a)
- pool->current = &pool->first;
-
- /*
- * This is a non-LIFO deallocation, so take care to fix up a->next's back
- * pointer in its header, if a->next is oversized.
- */
- *ap = b = a->next;
- if (b && b->avail - b->base > pool->arenasize) {
- JS_ASSERT(GET_HEADER(pool, b) == &a->next);
- SET_HEADER(pool, b, ap);
- }
- JS_CLEAR_ARENA(a);
- JS_COUNT_ARENA(pool,--);
- free(a);
-}
-
-JS_PUBLIC_API(void)
-JS_FreeArenaPool(JSArenaPool *pool)
-{
- FreeArenaList(pool, &pool->first, JS_FALSE);
- COUNT(pool, ndeallocs);
-}
-
-JS_PUBLIC_API(void)
-JS_FinishArenaPool(JSArenaPool *pool)
-{
- FreeArenaList(pool, &pool->first, JS_TRUE);
-#ifdef JS_ARENAMETER
- {
- JSArenaStats *stats, **statsp;
-
- if (pool->stats.name)
- free(pool->stats.name);
- for (statsp = &arena_stats_list; (stats = *statsp) != 0;
- statsp = &stats->next) {
- if (stats == &pool->stats) {
- *statsp = stats->next;
- return;
- }
- }
- }
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaFinish()
-{
- JSArena *a, *next;
-
- JS_ACQUIRE_LOCK(arena_freelist_lock);
- a = arena_freelist;
- arena_freelist = NULL;
- JS_RELEASE_LOCK(arena_freelist_lock);
- for (; a; a = next) {
- next = a->next;
- free(a);
- }
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaShutDown(void)
-{
-#ifdef JS_THREADSAFE
- /* Must come through here once in the process's last thread! */
- if (arena_freelist_lock) {
- JS_DESTROY_LOCK(arena_freelist_lock);
- arena_freelist_lock = NULL;
- }
-#endif
-}
-
-#ifdef JS_ARENAMETER
-JS_PUBLIC_API(void)
-JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb)
-{
- pool->stats.nallocs++;
- pool->stats.nbytes += nb;
- if (nb > pool->stats.maxalloc)
- pool->stats.maxalloc = nb;
- pool->stats.variance += nb * nb;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr)
-{
- pool->stats.ninplace++;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr)
-{
- pool->stats.ngrows++;
- pool->stats.nbytes += incr;
- pool->stats.variance -= size * size;
- size += incr;
- if (size > pool->stats.maxalloc)
- pool->stats.maxalloc = size;
- pool->stats.variance += size * size;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
-{
- pool->stats.nreleases++;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
-{
- pool->stats.nfastrels++;
-}
-
-#include <math.h>
-#include <stdio.h>
-
-JS_PUBLIC_API(void)
-JS_DumpArenaStats(FILE *fp)
-{
- JSArenaStats *stats;
- uint32 nallocs, nbytes;
- double mean, variance, sigma;
-
- for (stats = arena_stats_list; stats; stats = stats->next) {
- nallocs = stats->nallocs;
- if (nallocs != 0) {
- nbytes = stats->nbytes;
- mean = (double)nbytes / nallocs;
- variance = stats->variance * nallocs - nbytes * nbytes;
- if (variance < 0 || nallocs == 1)
- variance = 0;
- else
- variance /= nallocs * (nallocs - 1);
- sigma = sqrt(variance);
- } else {
- mean = variance = sigma = 0;
- }
-
- fprintf(fp, "\n%s allocation statistics:\n", stats->name);
- fprintf(fp, " number of arenas: %u\n", stats->narenas);
- fprintf(fp, " number of allocations: %u\n", stats->nallocs);
- fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims);
- fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs);
- fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs);
- fprintf(fp, " number of allocation growths: %u\n", stats->ngrows);
- fprintf(fp, " number of in-place growths: %u\n", stats->ninplace);
- fprintf(fp, " number of realloc'ing growths: %u\n", stats->nreallocs);
- fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
- fprintf(fp, " number of fast releases: %u\n", stats->nfastrels);
- fprintf(fp, " total bytes allocated: %u\n", stats->nbytes);
- fprintf(fp, " mean allocation size: %g\n", mean);
- fprintf(fp, " standard deviation: %g\n", sigma);
- fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc);
- }
-}
-#endif /* JS_ARENAMETER */
diff --git a/src/extension/script/js/jsarena.h b/src/extension/script/js/jsarena.h
deleted file mode 100644
index e52398a1a..000000000
--- a/src/extension/script/js/jsarena.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsarena_h___
-#define jsarena_h___
-/*
- * Lifetime-based fast allocation, inspired by much prior art, including
- * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
- * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
- *
- * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE).
- */
-#include <stdlib.h>
-#include "jstypes.h"
-#include "jscompat.h"
-
-JS_BEGIN_EXTERN_C
-
-typedef struct JSArena JSArena;
-typedef struct JSArenaPool JSArenaPool;
-
-struct JSArena {
- JSArena *next; /* next arena for this lifetime */
- jsuword base; /* aligned base address, follows this header */
- jsuword limit; /* one beyond last byte in arena */
- jsuword avail; /* points to next available byte */
-};
-
-#ifdef JS_ARENAMETER
-typedef struct JSArenaStats JSArenaStats;
-
-struct JSArenaStats {
- JSArenaStats *next; /* next in arenaStats list */
- char *name; /* name for debugging */
- uint32 narenas; /* number of arenas in pool */
- uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */
- uint32 nreclaims; /* number of reclaims from freeArenas */
- uint32 nmallocs; /* number of malloc() calls */
- uint32 ndeallocs; /* number of lifetime deallocations */
- uint32 ngrows; /* number of JS_ARENA_GROW() calls */
- uint32 ninplace; /* number of in-place growths */
- uint32 nreallocs; /* number of arena grow extending reallocs */
- uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */
- uint32 nfastrels; /* number of "fast path" releases */
- size_t nbytes; /* total bytes allocated */
- size_t maxalloc; /* maximum allocation size in bytes */
- double variance; /* size variance accumulator */
-};
-#endif
-
-struct JSArenaPool {
- JSArena first; /* first arena in pool list */
- JSArena *current; /* arena from which to allocate space */
- size_t arenasize; /* net exact size of a new arena */
- jsuword mask; /* alignment mask (power-of-2 - 1) */
-#ifdef JS_ARENAMETER
- JSArenaStats stats;
-#endif
-};
-
-/*
- * If the including .c file uses only one power-of-2 alignment, it may define
- * JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
- * per ALLOCATE and GROW.
- */
-#ifdef JS_ARENA_CONST_ALIGN_MASK
-#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \
- & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK)
-
-#define JS_INIT_ARENA_POOL(pool, name, size) \
- JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1)
-#else
-#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
-#endif
-
-#define JS_ARENA_ALLOCATE(p, pool, nb) \
- JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
-
-#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \
- JS_ARENA_ALLOCATE_CAST(p, type *, pool, sizeof(type))
-
-#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \
- JS_BEGIN_MACRO \
- JSArena *_a = (pool)->current; \
- size_t _nb = JS_ARENA_ALIGN(pool, nb); \
- jsuword _p = _a->avail; \
- jsuword _q = _p + _nb; \
- JS_ASSERT(_q >= _p); \
- if (_q > _a->limit) \
- _p = (jsuword)JS_ArenaAllocate(pool, _nb); \
- else \
- _a->avail = _q; \
- p = (type) _p; \
- JS_ArenaCountAllocation(pool, nb); \
- JS_END_MACRO
-
-#define JS_ARENA_GROW(p, pool, size, incr) \
- JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
-
-#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \
- JS_BEGIN_MACRO \
- JSArena *_a = (pool)->current; \
- if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \
- size_t _nb = (size) + (incr); \
- jsuword _q = (jsuword)(p) + JS_ARENA_ALIGN(pool, _nb); \
- if (_q <= _a->limit) { \
- _a->avail = _q; \
- JS_ArenaCountInplaceGrowth(pool, size, incr); \
- } else if ((jsuword)(p) == _a->base) { \
- p = (type) JS_ArenaRealloc(pool, p, size, incr); \
- } else { \
- p = (type) JS_ArenaGrow(pool, p, size, incr); \
- } \
- } else { \
- p = (type) JS_ArenaGrow(pool, p, size, incr); \
- } \
- JS_ArenaCountGrowth(pool, size, incr); \
- JS_END_MACRO
-
-#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail)
-#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q))
-
-#ifdef DEBUG
-#define JS_FREE_PATTERN 0xDA
-#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
- memset((void*)(a)->avail, JS_FREE_PATTERN, \
- (a)->limit - (a)->avail))
-#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \
- (a)->limit - (jsuword)(a))
-#else
-#define JS_CLEAR_UNUSED(a) /* nothing */
-#define JS_CLEAR_ARENA(a) /* nothing */
-#endif
-
-#define JS_ARENA_RELEASE(pool, mark) \
- JS_BEGIN_MACRO \
- char *_m = (char *)(mark); \
- JSArena *_a = (pool)->current; \
- if (_a != &(pool)->first && \
- JS_UPTRDIFF(_m, _a->base) <= JS_UPTRDIFF(_a->avail, _a->base)) { \
- _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \
- JS_ASSERT(_a->avail <= _a->limit); \
- JS_CLEAR_UNUSED(_a); \
- JS_ArenaCountRetract(pool, _m); \
- } else { \
- JS_ArenaRelease(pool, _m); \
- } \
- JS_ArenaCountRelease(pool, _m); \
- JS_END_MACRO
-
-#ifdef JS_ARENAMETER
-#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
-#else
-#define JS_COUNT_ARENA(pool,op)
-#endif
-
-#define JS_ARENA_DESTROY(pool, a, pnext) \
- JS_BEGIN_MACRO \
- JS_COUNT_ARENA(pool,--); \
- if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
- *(pnext) = (a)->next; \
- JS_CLEAR_ARENA(a); \
- free(a); \
- (a) = NULL; \
- JS_END_MACRO
-
-/*
- * Initialize an arena pool with the given name for debugging and metering,
- * with a minimum size per arena of size bytes.
- */
-extern JS_PUBLIC_API(void)
-JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
- size_t align);
-
-/*
- * Free the arenas in pool. The user may continue to allocate from pool
- * after calling this function. There is no need to call JS_InitArenaPool()
- * again unless JS_FinishArenaPool(pool) has been called.
- */
-extern JS_PUBLIC_API(void)
-JS_FreeArenaPool(JSArenaPool *pool);
-
-/*
- * Free the arenas in pool and finish using it altogether.
- */
-extern JS_PUBLIC_API(void)
-JS_FinishArenaPool(JSArenaPool *pool);
-
-/*
- * Finish using arenas, freeing all memory associated with them except for
- * any locks needed for thread safety.
- */
-extern JS_PUBLIC_API(void)
-JS_ArenaFinish(void);
-
-/*
- * Free any locks or other memory needed for thread safety, just before
- * shutting down. At that point, we must be called by a single thread.
- *
- * After shutting down, the next thread to call JS_InitArenaPool must not
- * race with any other thread. Once a pool has been initialized, threads
- * may safely call jsarena.c functions on thread-local pools. The upshot
- * is that pools are per-thread, but the underlying global freelist is
- * thread-safe, provided that both the first pool initialization and the
- * shut-down call are single-threaded.
- */
-extern JS_PUBLIC_API(void)
-JS_ArenaShutDown(void);
-
-/*
- * Friend functions used by the JS_ARENA_*() macros.
- */
-extern JS_PUBLIC_API(void *)
-JS_ArenaAllocate(JSArenaPool *pool, size_t nb);
-
-extern JS_PUBLIC_API(void *)
-JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void *)
-JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaRelease(JSArenaPool *pool, char *mark);
-
-/*
- * Function to be used directly when an allocation has likely grown to consume
- * an entire JSArena, in which case the arena is returned to the malloc heap.
- */
-extern JS_PUBLIC_API(void)
-JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size);
-
-#ifdef JS_ARENAMETER
-
-#include <stdio.h>
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
-
-extern JS_PUBLIC_API(void)
-JS_DumpArenaStats(FILE *fp);
-
-#else /* !JS_ARENAMETER */
-
-#define JS_ArenaCountAllocation(ap, nb) /* nothing */
-#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
-#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */
-#define JS_ArenaCountRelease(ap, mark) /* nothing */
-#define JS_ArenaCountRetract(ap, mark) /* nothing */
-
-#endif /* !JS_ARENAMETER */
-
-JS_END_EXTERN_C
-
-#endif /* jsarena_h___ */
diff --git a/src/extension/script/js/jsarray.c b/src/extension/script/js/jsarray.c
deleted file mode 100644
index 250c67557..000000000
--- a/src/extension/script/js/jsarray.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS array class.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsstr.h"
-
-/* 2^32 - 1 as a number and a string */
-#define MAXINDEX 4294967295u
-#define MAXSTR "4294967295"
-
-/*
- * Determine if the id represents an array index.
- *
- * An id is an array index according to ECMA by (15.4):
- *
- * "Array objects give special treatment to a certain class of property names.
- * A property name P (in the form of a string value) is an array index if and
- * only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
- * to 2^32-1."
- *
- * In our implementation, it would be sufficient to check for JSVAL_IS_INT(id)
- * except that by using signed 32-bit integers we miss the top half of the
- * valid range. This function checks the string representation itself; note
- * that calling a standard conversion routine might allow strings such as
- * "08" or "4.0" as array indices, which they are not.
- */
-static JSBool
-IdIsIndex(jsid id, jsuint *indexp)
-{
- JSString *str;
- jschar *cp;
-
- if (JSVAL_IS_INT(id)) {
- jsint i;
- i = JSVAL_TO_INT(id);
- if (i < 0)
- return JS_FALSE;
- *indexp = (jsuint)i;
- return JS_TRUE;
- }
-
- /* It must be a string. */
- str = JSVAL_TO_STRING(id);
- cp = JSSTRING_CHARS(str);
- if (JS7_ISDEC(*cp) && JSSTRING_LENGTH(str) < sizeof(MAXSTR)) {
- jsuint index = JS7_UNDEC(*cp++);
- jsuint oldIndex = 0;
- jsuint c = 0;
- if (index != 0) {
- while (JS7_ISDEC(*cp)) {
- oldIndex = index;
- c = JS7_UNDEC(*cp);
- index = 10*index + c;
- cp++;
- }
- }
- /* Make sure all characters were consumed and that it couldn't
- * have overflowed.
- */
- if (*cp == 0 &&
- (oldIndex < (MAXINDEX / 10) ||
- (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
- {
- *indexp = index;
- return JS_TRUE;
- }
- }
- return JS_FALSE;
-}
-
-static JSBool
-ValueIsLength(JSContext *cx, jsval v, jsuint *lengthp)
-{
- jsint i;
- jsdouble d;
-
- if (JSVAL_IS_INT(v)) {
- i = JSVAL_TO_INT(v);
- if (i < 0) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_ARRAY_LENGTH);
- return JS_FALSE;
- }
- *lengthp = (jsuint) i;
- return JS_TRUE;
- }
-
- if (!js_ValueToNumber(cx, v, &d)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_ARRAY_LENGTH);
- return JS_FALSE;
- }
- if (!js_DoubleToECMAUint32(cx, d, (uint32 *)lengthp)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_ARRAY_LENGTH);
- return JS_FALSE;
- }
- if (JSDOUBLE_IS_NaN(d) || d != *lengthp) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_ARRAY_LENGTH);
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JSBool
-js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
-{
- jsid id;
- jsint i;
- jsval v;
-
- id = (jsid) cx->runtime->atomState.lengthAtom;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
-
- /* Short-circuit, because js_ValueToECMAUint32 fails when
- * called during init time.
- */
- if (JSVAL_IS_INT(v)) {
- i = JSVAL_TO_INT(v);
- /* jsuint cast does ToUint32. */
- *lengthp = (jsuint)i;
- return JS_TRUE;
- }
- return js_ValueToECMAUint32(cx, v, (uint32 *)lengthp);
-}
-
-static JSBool
-IndexToValue(JSContext *cx, jsuint length, jsval *vp)
-{
- if (length <= JSVAL_INT_MAX) {
- *vp = INT_TO_JSVAL(length);
- return JS_TRUE;
- }
- return js_NewDoubleValue(cx, (jsdouble)length, vp);
-}
-
-static JSBool
-IndexToId(JSContext *cx, jsuint length, jsid *idp)
-{
- JSString *str;
- JSAtom *atom;
-
- if (length <= JSVAL_INT_MAX) {
- *idp = (jsid) INT_TO_JSVAL(length);
- } else {
- str = js_NumberToString(cx, (jsdouble)length);
- if (!str)
- return JS_FALSE;
- atom = js_AtomizeString(cx, str, 0);
- if (!atom)
- return JS_FALSE;
- *idp = (jsid)atom;
-
- }
- return JS_TRUE;
-}
-
-JSBool
-js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length)
-{
- jsval v;
- jsid id;
-
- if (!IndexToValue(cx, length, &v))
- return JS_FALSE;
- id = (jsid) cx->runtime->atomState.lengthAtom;
- return OBJ_SET_PROPERTY(cx, obj, id, &v);
-}
-
-JSBool
-js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
-{
- JSErrorReporter older;
- jsid id;
- JSBool ok;
- jsval v;
-
- older = JS_SetErrorReporter(cx, NULL);
- id = (jsid) cx->runtime->atomState.lengthAtom;
- ok = OBJ_GET_PROPERTY(cx, obj, id, &v);
- JS_SetErrorReporter(cx, older);
- if (!ok)
- return JS_FALSE;
- return ValueIsLength(cx, v, lengthp);
-}
-
-/*
- * This get function is specific to Array.prototype.length and other array
- * instance length properties. It calls back through the class get function
- * in case some magic happens there (see call_getProperty in jsfun.c).
- */
-static JSBool
-array_length_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, id, vp);
-}
-
-static JSBool
-array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsuint newlen, oldlen, slot;
- jsid id2;
- jsval junk;
-
- if (!ValueIsLength(cx, *vp, &newlen))
- return JS_FALSE;
- if (!js_GetLengthProperty(cx, obj, &oldlen))
- return JS_FALSE;
- slot = oldlen;
- while (slot > newlen) {
- --slot;
- if (!IndexToId(cx, slot, &id2))
- return JS_FALSE;
- if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
- return JS_FALSE;
- }
- return IndexToValue(cx, newlen, vp);
-}
-
-static JSBool
-array_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsuint index, length;
-
- if (!(IdIsIndex(id, &index)))
- return JS_TRUE;
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- if (index >= length) {
- length = index + 1;
- return js_SetLengthProperty(cx, obj, length);
- }
- return JS_TRUE;
-}
-
-static JSBool
-array_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
-{
- jsuint length;
-
- if (cx->version == JSVERSION_1_2) {
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- switch (type) {
- case JSTYPE_NUMBER:
- return IndexToValue(cx, length, vp);
- case JSTYPE_BOOLEAN:
- *vp = BOOLEAN_TO_JSVAL(length > 0);
- return JS_TRUE;
- default:
- return JS_TRUE;
- }
- }
- return js_TryValueOf(cx, obj, type, vp);
-}
-
-JSClass js_ArrayClass = {
- "Array",
- 0,
- array_addProperty, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, array_convert, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-static JSBool
-array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize,
- jsval *rval, JSBool localeString)
-{
- JSBool ok;
- jsval v;
- jsuint length, index;
- jschar *chars, *ochars;
- size_t nchars, growth, seplen, tmplen;
- const jschar *sepstr;
- JSString *str;
- JSHashEntry *he;
- JSObject *obj2;
-
- ok = js_GetLengthProperty(cx, obj, &length);
- if (!ok)
- return JS_FALSE;
- ok = JS_TRUE;
-
- he = js_EnterSharpObject(cx, obj, NULL, &chars);
- if (!he)
- return JS_FALSE;
- if (literalize) {
- if (IS_SHARP(he)) {
-#if JS_HAS_SHARP_VARS
- nchars = js_strlen(chars);
-#else
- chars[0] = '[';
- chars[1] = ']';
- chars[2] = 0;
- nchars = 2;
-#endif
- goto make_string;
- }
-
- /*
- * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the
- * terminating 0.
- */
- growth = (1 + 3 + 1) * sizeof(jschar);
- if (!chars) {
- nchars = 0;
- chars = (jschar *) malloc(growth);
- if (!chars)
- goto done;
- } else {
- MAKE_SHARP(he);
- nchars = js_strlen(chars);
- chars = (jschar *)
- realloc((ochars = chars), nchars * sizeof(jschar) + growth);
- if (!chars) {
- free(ochars);
- goto done;
- }
- }
- chars[nchars++] = '[';
- } else {
- /*
- * Free any sharp variable definition in chars. Normally, we would
- * MAKE_SHARP(he) so that only the first sharp variable annotation is
- * a definition, and all the rest are references, but in the current
- * case of (!literalize), we don't need chars at all.
- */
- if (chars)
- JS_free(cx, chars);
- chars = NULL;
- nchars = 0;
-
- /* Return the empty string on a cycle as well as on empty join. */
- if (IS_BUSY(he) || length == 0) {
- js_LeaveSharpObject(cx, NULL);
- *rval = JS_GetEmptyStringValue(cx);
- return ok;
- }
-
- /* Flag he as BUSY so we can distinguish a cycle from a join-point. */
- MAKE_BUSY(he);
- }
- sepstr = NULL;
- seplen = JSSTRING_LENGTH(sep);
-
- v = JSVAL_NULL;
- for (index = 0; index < length; index++) {
- ok = JS_GetElement(cx, obj, index, &v);
- if (!ok)
- goto done;
-
- if (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v)) {
- str = cx->runtime->emptyString;
- } else {
- if (localeString) {
- if (!js_ValueToObject(cx, v, &obj2) ||
- !js_TryMethod(cx, obj2,
- cx->runtime->atomState.toLocaleStringAtom,
- 0, NULL, &v)) {
- str = NULL;
- } else {
- str = js_ValueToString(cx, v);
- }
- } else {
- str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v);
- }
- if (!str) {
- ok = JS_FALSE;
- goto done;
- }
- }
-
- /* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */
- growth = (nchars + (sepstr ? seplen : 0) +
- JSSTRING_LENGTH(str) +
- 3 + 1) * sizeof(jschar);
- if (!chars) {
- chars = (jschar *) malloc(growth);
- if (!chars)
- goto done;
- } else {
- chars = (jschar *) realloc((ochars = chars), growth);
- if (!chars) {
- free(ochars);
- goto done;
- }
- }
-
- if (sepstr) {
- js_strncpy(&chars[nchars], sepstr, seplen);
- nchars += seplen;
- }
- sepstr = JSSTRING_CHARS(sep);
-
- tmplen = JSSTRING_LENGTH(str);
- js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen);
- nchars += tmplen;
- }
-
- done:
- if (literalize) {
- if (chars) {
- if (JSVAL_IS_VOID(v)) {
- chars[nchars++] = ',';
- chars[nchars++] = ' ';
- }
- chars[nchars++] = ']';
- }
- } else {
- CLEAR_BUSY(he);
- }
- js_LeaveSharpObject(cx, NULL);
- if (!ok) {
- if (chars)
- free(chars);
- return ok;
- }
-
- make_string:
- if (!chars) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- chars[nchars] = 0;
- str = js_NewString(cx, chars, nchars, 0);
- if (!str) {
- free(chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static jschar comma_space_ucstr[] = {',', ' ', 0};
-static jschar comma_ucstr[] = {',', 0};
-static JSString comma_space = {2, comma_space_ucstr};
-static JSString comma = {1, comma_ucstr};
-
-#if JS_HAS_TOSOURCE
-static JSBool
-array_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- return array_join_sub(cx, obj, &comma_space, JS_TRUE, rval, JS_FALSE);
-}
-#endif
-
-static JSBool
-array_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSBool literalize;
-
- /*
- * JS1.2 arrays convert to array literals, with a comma followed by a space
- * between each element.
- */
- literalize = (cx->version == JSVERSION_1_2);
- return array_join_sub(cx, obj, literalize ? &comma_space : &comma,
- literalize, rval, JS_FALSE);
-}
-
-static JSBool
-array_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- /*
- * Passing comma here as the separator. Need a way to get a
- * locale-specific version.
- */
- return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_TRUE);
-}
-
-static JSBool
-InitArrayElements(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
-{
- jsuint index;
- jsid id;
-
- for (index = 0; index < length; index++) {
- if (!IndexToId(cx, index, &id))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id, &vector[index]))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-static JSBool
-InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
-{
- jsval v;
- jsid id;
-
- if (!IndexToValue(cx, length, &v))
- return JS_FALSE;
- id = (jsid) cx->runtime->atomState.lengthAtom;
- if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v,
- array_length_getter, array_length_setter,
- JSPROP_PERMANENT,
- NULL)) {
- return JS_FALSE;
- }
- if (!vector)
- return JS_TRUE;
- return InitArrayElements(cx, obj, length, vector);
-}
-
-#if JS_HAS_SOME_PERL_FUN
-/*
- * Perl-inspired join, reverse, and sort.
- */
-static JSBool
-array_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
-
- if (JSVAL_IS_VOID(argv[0]))
- return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_FALSE);
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str);
- return array_join_sub(cx, obj, str, JS_FALSE, rval, JS_FALSE);
-}
-
-static JSBool
-array_reverse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsuint len, half, i;
- jsid id, id2;
- jsval v, v2;
-
- if (!js_GetLengthProperty(cx, obj, &len))
- return JS_FALSE;
-
- half = len / 2;
- for (i = 0; i < half; i++) {
- if (!IndexToId(cx, i, &id))
- return JS_FALSE;
- if (!IndexToId(cx, len - i - 1, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id2, &v2))
- return JS_FALSE;
-
-#if JS_HAS_SPARSE_ARRAYS
- /* This part isn't done yet. */
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */
- continue;
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
-#endif
-
- if (!OBJ_SET_PROPERTY(cx, obj, id, &v2))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
- return JS_FALSE;
- }
-
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
-}
-
-typedef struct HSortArgs {
- void *vec;
- size_t elsize;
- void *pivot;
- JSComparator cmp;
- void *arg;
- JSBool fastcopy;
-} HSortArgs;
-
-static int
-sort_compare(const void *a, const void *b, void *arg);
-
-static int
-sort_compare_strings(const void *a, const void *b, void *arg);
-
-static void
-HeapSortHelper(JSBool building, HSortArgs *hsa, size_t lo, size_t hi)
-{
- void *pivot, *vec, *vec2, *arg, *a, *b;
- size_t elsize;
- JSComparator cmp;
- JSBool fastcopy;
- size_t j, hiDiv2;
-
- pivot = hsa->pivot;
- vec = hsa->vec;
- elsize = hsa->elsize;
- vec2 = (char *)vec - 2 * elsize;
- cmp = hsa->cmp;
- arg = hsa->arg;
-
- fastcopy = hsa->fastcopy;
-#define MEMCPY(p,q,n) \
- (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))
-
- if (lo == 1) {
- j = 2;
- b = (char *)vec + elsize;
- if (j < hi && cmp(vec, b, arg) < 0)
- j++;
- a = (char *)vec + (hi - 1) * elsize;
- b = (char *)vec2 + j * elsize;
-
- /*
- * During sorting phase b points to a member of heap that cannot be
- * bigger then biggest of vec[0] and vec[1], and cmp(a, b, arg) <= 0
- * always holds.
- */
- if ((building || hi == 2) && cmp(a, b, arg) >= 0)
- return;
-
- MEMCPY(pivot, a, elsize);
- MEMCPY(a, b, elsize);
- lo = j;
- } else {
- a = (char *)vec2 + lo * elsize;
- MEMCPY(pivot, a, elsize);
- }
-
- hiDiv2 = hi/2;
- while (lo <= hiDiv2) {
- j = lo + lo;
- a = (char *)vec2 + j * elsize;
- b = (char *)vec + (j - 1) * elsize;
- if (j < hi && cmp(a, b, arg) < 0)
- j++;
- b = (char *)vec2 + j * elsize;
- if (cmp(pivot, b, arg) >= 0)
- break;
-
- a = (char *)vec2 + lo * elsize;
- MEMCPY(a, b, elsize);
- lo = j;
- }
-
- a = (char *)vec2 + lo * elsize;
- MEMCPY(a, pivot, elsize);
-#undef MEMCPY
-}
-
-JSBool
-js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg)
-{
- void *pivot;
- HSortArgs hsa;
- size_t i;
-
- pivot = malloc(elsize);
- if (!pivot)
- return JS_FALSE;
- hsa.vec = vec;
- hsa.elsize = elsize;
- hsa.pivot = pivot;
- hsa.cmp = cmp;
- hsa.arg = arg;
- hsa.fastcopy = (cmp == sort_compare || cmp == sort_compare_strings);
-
- for (i = nel/2; i != 0; i--)
- HeapSortHelper(JS_TRUE, &hsa, i, nel);
- while (nel > 2)
- HeapSortHelper(JS_FALSE, &hsa, 1, --nel);
-
- free(pivot);
- return JS_TRUE;
-}
-
-typedef struct CompareArgs {
- JSContext *context;
- jsval fval;
- JSBool status;
-} CompareArgs;
-
-static int
-sort_compare(const void *a, const void *b, void *arg)
-{
- jsval av = *(const jsval *)a, bv = *(const jsval *)b;
- CompareArgs *ca = (CompareArgs *) arg;
- JSContext *cx = ca->context;
- jsdouble cmp = -1;
- jsval fval, argv[2], rval;
- JSBool ok;
-
- fval = ca->fval;
- if (fval == JSVAL_NULL) {
- JSString *astr, *bstr;
-
- if (av == bv) {
- cmp = 0;
- } else if (av == JSVAL_VOID || bv == JSVAL_VOID) {
- /* Put undefined properties at the end. */
- cmp = (av == JSVAL_VOID) ? 1 : -1;
- } else if ((astr = js_ValueToString(cx, av)) != NULL &&
- (bstr = js_ValueToString(cx, bv)) != NULL) {
- cmp = js_CompareStrings(astr, bstr);
- } else {
- ca->status = JS_FALSE;
- }
- } else {
- argv[0] = av;
- argv[1] = bv;
- ok = js_InternalCall(cx,
- OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
- fval, 2, argv, &rval);
- if (ok) {
- ok = js_ValueToNumber(cx, rval, &cmp);
- /* Clamp cmp to -1, 0, 1. */
- if (JSDOUBLE_IS_NaN(cmp)) {
- /* XXX report some kind of error here? ECMA talks about
- * 'consistent compare functions' that don't return NaN, but is
- * silent about what the result should be. So we currently
- * ignore it.
- */
- cmp = 0;
- } else if (cmp != 0) {
- cmp = cmp > 0 ? 1 : -1;
- }
- } else {
- ca->status = ok;
- }
- }
- return (int)cmp;
-}
-
-static int
-sort_compare_strings(const void *a, const void *b, void *arg)
-{
- jsval av = *(const jsval *)a, bv = *(const jsval *)b;
-
- return (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));
-}
-
-/* XXXmccabe do the sort helper functions need to take int? (Or can we claim
- * that 2^32 * 32 is too large to worry about?) Something dumps when I change
- * to unsigned int; is qsort using -1 as a fencepost?
- */
-static JSBool
-array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval fval;
- CompareArgs ca;
- jsuint len, newlen, i;
- jsval *vec;
- jsid id;
- size_t nbytes;
-
- /*
- * Optimize the default compare function case if all of obj's elements
- * have values of type string.
- */
- JSBool all_strings;
-
- if (argc > 0) {
- if (JSVAL_IS_PRIMITIVE(argv[0])) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_SORT_ARG);
- return JS_FALSE;
- }
- fval = argv[0];
- all_strings = JS_FALSE; /* non-default compare function */
- } else {
- fval = JSVAL_NULL;
- all_strings = JS_TRUE; /* check for all string values */
- }
-
- if (!js_GetLengthProperty(cx, obj, &len))
- return JS_FALSE;
- if (len == 0) {
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
- }
-
- /*
- * Test for size_t overflow, which could lead to indexing beyond the end
- * of the malloc'd vector.
- */
- nbytes = len * sizeof(jsval);
- if (nbytes != (double) len * sizeof(jsval)) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- vec = (jsval *) JS_malloc(cx, nbytes);
- if (!vec)
- return JS_FALSE;
-
-#if JS_HAS_SPARSE_ARRAYS
- newlen = 0;
-#else
- newlen = len;
-#endif
-
- for (i = 0; i < len; i++) {
- ca.status = IndexToId(cx, i, &id);
- if (!ca.status)
- goto out;
-#if JS_HAS_SPARSE_ARRAYS
- {
- JSObject *obj2;
- JSProperty *prop;
- ca.status = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ca.status)
- goto out;
- if (!prop) {
- vec[i] = JSVAL_VOID;
- continue;
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- newlen++;
- }
-#endif
- ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]);
- if (!ca.status)
- goto out;
-
- /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
- all_strings &= JSVAL_IS_STRING(vec[i]);
- }
-
- ca.context = cx;
- ca.fval = fval;
- ca.status = JS_TRUE;
- if (!js_HeapSort(vec, (size_t) len, sizeof(jsval),
- all_strings ? sort_compare_strings : sort_compare,
- &ca)) {
- JS_ReportOutOfMemory(cx);
- ca.status = JS_FALSE;
- }
-
- if (ca.status) {
- ca.status = InitArrayElements(cx, obj, newlen, vec);
- if (ca.status)
- *rval = OBJECT_TO_JSVAL(obj);
-#if JS_HAS_SPARSE_ARRAYS
- /* set length of newly-created array object to old length. */
- if (ca.status && newlen < len) {
- ca.status = js_SetLengthProperty(cx, obj, len);
-
- /* Delete any leftover properties greater than newlen. */
- while (ca.status && newlen < len) {
- jsval junk;
-
- ca.status = !IndexToId(cx, newlen, &id) ||
- !OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
- newlen++;
- }
- }
-#endif
- }
-
-out:
- if (vec)
- JS_free(cx, vec);
- return ca.status;
-}
-#endif /* JS_HAS_SOME_PERL_FUN */
-
-#if JS_HAS_MORE_PERL_FUN
-/*
- * Perl-inspired push, pop, shift, unshift, and splice methods.
- */
-static JSBool
-array_push(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsuint length;
- uintN i;
- jsid id;
-
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- for (i = 0; i < argc; i++) {
- if (!IndexToId(cx, length + i, &id))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
- return JS_FALSE;
- }
-
- /*
- * If JS1.2, follow Perl4 by returning the last thing pushed. Otherwise,
- * return the new array length.
- */
- length += argc;
- if (cx->version == JSVERSION_1_2) {
- *rval = argc ? argv[argc-1] : JSVAL_VOID;
- } else {
- if (!IndexToValue(cx, length, rval))
- return JS_FALSE;
- }
- return js_SetLengthProperty(cx, obj, length);
-}
-
-static JSBool
-array_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsuint index;
- jsid id;
- jsval junk;
-
- if (!js_GetLengthProperty(cx, obj, &index))
- return JS_FALSE;
- if (index > 0) {
- index--;
- if (!IndexToId(cx, index, &id))
- return JS_FALSE;
-
- /* Get the to-be-deleted property's value into rval. */
- if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
- return JS_FALSE;
-
- if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
- return JS_FALSE;
- }
- return js_SetLengthProperty(cx, obj, index);
-}
-
-static JSBool
-array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsuint length, i;
- jsid id, id2;
- jsval v, junk;
-
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- if (length > 0) {
- length--;
- id = JSVAL_ZERO;
-
- /* Get the to-be-deleted property's value into rval ASAP. */
- if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
- return JS_FALSE;
-
- /*
- * Slide down the array above the first element.
- */
- if (length > 0) {
- for (i = 1; i <= length; i++) {
- if (!IndexToId(cx, i, &id))
- return JS_FALSE;
- if (!IndexToId(cx, i - 1, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
- return JS_FALSE;
- }
- }
-
- /* Delete the only or last element. */
- if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
- return JS_FALSE;
- }
- return js_SetLengthProperty(cx, obj, length);
-}
-
-static JSBool
-array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsuint length, last;
- uintN i;
- jsid id, id2;
- jsval v;
-#if JS_HAS_SPARSE_ARRAYS
- JSObject *obj2;
- JSProperty *prop;
-#endif
-
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- if (argc > 0) {
- /* Slide up the array to make room for argc at the bottom. */
- if (length > 0) {
- last = length;
- while (last--) {
- if (!IndexToId(cx, last, &id))
- return JS_FALSE;
- if (!IndexToId(cx, last + argc, &id2))
- return JS_FALSE;
-#if JS_HAS_SPARSE_ARRAYS
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */
- continue;
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
-#endif
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
- return JS_FALSE;
- }
- }
-
- /* Copy from argv to the bottom of the array. */
- for (i = 0; i < argc; i++) {
- if (!IndexToId(cx, i, &id))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
- return JS_FALSE;
- }
-
- /* Follow Perl by returning the new array length. */
- length += argc;
- if (!js_SetLengthProperty(cx, obj, length))
- return JS_FALSE;
- }
- return IndexToValue(cx, length, rval);
-}
-
-static JSBool
-array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsuint length, begin, end, count, delta, last;
- uintN i;
- jsdouble d;
- jsid id, id2;
- jsval v;
- JSObject *obj2;
-
- /* Nothing to do if no args. Otherwise lock and load length. */
- if (argc == 0)
- return JS_TRUE;
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
-
- /* Convert the first argument into a starting index. */
- if (!js_ValueToNumber(cx, *argv, &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- if (d < 0) {
- d += length;
- if (d < 0)
- d = 0;
- } else if (d > length) {
- d = length;
- }
- begin = (jsuint)d; /* d has been clamped to uint32 */
- argc--;
- argv++;
-
- /* Convert the second argument from a count into a fencepost index. */
- delta = length - begin;
- if (argc == 0) {
- count = delta;
- end = length;
- } else {
- if (!js_ValueToNumber(cx, *argv, &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- if (d < 0)
- d = 0;
- else if (d > delta)
- d = delta;
- count = (jsuint)d;
- end = begin + count;
- argc--;
- argv++;
- }
-
- if (count == 1 && cx->version == JSVERSION_1_2) {
- /*
- * JS lacks "list context", whereby in Perl one turns the single
- * scalar that's spliced out into an array just by assigning it to
- * @single instead of $single, or by using it as Perl push's first
- * argument, for instance.
- *
- * JS1.2 emulated Perl too closely and returned a non-Array for
- * the single-splice-out case, requiring callers to test and wrap
- * in [] if necessary. So JS1.3, default, and other versions all
- * return an array of length 1 for uniformity.
- */
- if (!IndexToId(cx, begin, &id))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
- return JS_FALSE;
- } else {
- if (cx->version != JSVERSION_1_2 || count > 0) {
- /*
- * Create a new array value to return. Our ECMA v2 proposal specs
- * that splice always returns an array value, even when given no
- * arguments. We think this is best because it eliminates the need
- * for callers to do an extra test to handle the empty splice case.
- */
- obj2 = js_NewArrayObject(cx, 0, NULL);
- if (!obj2)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(obj2);
-
- /* If there are elements to remove, put them into the return value. */
- if (count > 0) {
- for (last = begin; last < end; last++) {
- if (!IndexToId(cx, last, &id))
- return JS_FALSE;
- if (!IndexToId(cx, last - begin, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj2, id2, &v))
- return JS_FALSE;
- }
- }
- }
- }
-
- /* Find the direction (up or down) to copy and make way for argv. */
- if (argc > count) {
- delta = (jsuint)argc - count;
- last = length;
- /* (uint) end could be 0, so can't use vanilla >= test */
- while (last-- > end) {
- if (!IndexToId(cx, last, &id))
- return JS_FALSE;
- if (!IndexToId(cx, last + delta, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
- return JS_FALSE;
- }
- length += delta;
- } else if (argc < count) {
- delta = count - (jsuint)argc;
- for (last = end; last < length; last++) {
- if (!IndexToId(cx, last, &id))
- return JS_FALSE;
- if (!IndexToId(cx, last - delta, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
- return JS_FALSE;
- }
- length -= delta;
- }
-
- /* Copy from argv into the hole to complete the splice. */
- for (i = 0; i < argc; i++) {
- if (!IndexToId(cx, begin + i, &id))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
- return JS_FALSE;
- }
-
- /* Update length in case we deleted elements from the end. */
- return js_SetLengthProperty(cx, obj, length);
-}
-#endif /* JS_HAS_MORE_PERL_FUN */
-
-#if JS_HAS_SEQUENCE_OPS
-/*
- * Python-esque sequence operations.
- */
-static JSBool
-array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSObject *nobj, *aobj;
- jsuint length, alength, slot;
- uintN i;
- jsval v;
- jsid id, id2;
-
- /* Treat obj as the first argument; see ECMA 15.4.4.4. */
- --argv;
- JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0]));
-
- /* Create a new Array object and store it in the rval local root. */
- nobj = js_NewArrayObject(cx, 0, NULL);
- if (!nobj)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(nobj);
-
- /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
- length = 0;
- for (i = 0; i <= argc; i++) {
- v = argv[i];
- if (JSVAL_IS_OBJECT(v)) {
- aobj = JSVAL_TO_OBJECT(v);
- if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) {
- if (!OBJ_GET_PROPERTY(cx, aobj,
- (jsid)cx->runtime->atomState.lengthAtom,
- &v)) {
- return JS_FALSE;
- }
- if (!ValueIsLength(cx, v, &alength))
- return JS_FALSE;
- for (slot = 0; slot < alength; slot++) {
- if (!IndexToId(cx, slot, &id))
- return JS_FALSE;
- if (!IndexToId(cx, length + slot, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, aobj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
- return JS_FALSE;
- }
- length += alength;
- continue;
- }
- }
-
- if (!IndexToId(cx, length, &id))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, nobj, id, &v))
- return JS_FALSE;
- length++;
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSObject *nobj;
- jsuint length, begin, end, slot;
- jsdouble d;
- jsid id, id2;
- jsval v;
-
- nobj = js_NewArrayObject(cx, 0, NULL);
- if (!nobj)
- return JS_FALSE;
-
- if (!js_GetLengthProperty(cx, obj, &length))
- return JS_FALSE;
- begin = 0;
- end = length;
-
- if (argc > 0) {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- if (d < 0) {
- d += length;
- if (d < 0)
- d = 0;
- } else if (d > length) {
- d = length;
- }
- begin = (jsuint)d;
-
- if (argc > 1) {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- if (d < 0) {
- d += length;
- if (d < 0)
- d = 0;
- } else if (d > length) {
- d = length;
- }
- end = (jsuint)d;
- }
- }
-
- for (slot = begin; slot < end; slot++) {
- if (!IndexToId(cx, slot, &id))
- return JS_FALSE;
- if (!IndexToId(cx, slot - begin, &id2))
- return JS_FALSE;
- if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
- return JS_FALSE;
- if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
- return JS_FALSE;
- }
- *rval = OBJECT_TO_JSVAL(nobj);
- return JS_TRUE;
-}
-#endif /* JS_HAS_SEQUENCE_OPS */
-
-static JSFunctionSpec array_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, array_toSource, 0,0,0},
-#endif
- {js_toString_str, array_toString, 0,0,0},
- {js_toLocaleString_str, array_toLocaleString, 0,0,0},
-
- /* Perl-ish methods. */
-#if JS_HAS_SOME_PERL_FUN
- {"join", array_join, 1,0,0},
- {"reverse", array_reverse, 0,0,0},
- {"sort", array_sort, 1,0,0},
-#endif
-#if JS_HAS_MORE_PERL_FUN
- {"push", array_push, 1,0,0},
- {"pop", array_pop, 0,0,0},
- {"shift", array_shift, 0,0,0},
- {"unshift", array_unshift, 1,0,0},
- {"splice", array_splice, 1,0,0},
-#endif
-
- /* Python-esque sequence methods. */
-#if JS_HAS_SEQUENCE_OPS
- {"concat", array_concat, 0,0,0},
- {"slice", array_slice, 0,0,0},
-#endif
-
- {0,0,0,0,0}
-};
-
-static JSBool
-Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsuint length;
- jsval *vector;
-
- /* If called without new, replace obj with a new Array object. */
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(obj);
- }
-
- if (argc == 0) {
- length = 0;
- vector = NULL;
- } else if (cx->version == JSVERSION_1_2) {
- length = (jsuint) argc;
- vector = argv;
- } else if (argc > 1) {
- length = (jsuint) argc;
- vector = argv;
- } else if (!JSVAL_IS_NUMBER(argv[0])) {
- length = 1;
- vector = argv;
- } else {
- if (!ValueIsLength(cx, argv[0], &length))
- return JS_FALSE;
- vector = NULL;
- }
- return InitArrayObject(cx, obj, length, vector);
-}
-
-JSObject *
-js_InitArrayClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
-
- proto = JS_InitClass(cx, obj, NULL, &js_ArrayClass, Array, 1,
- NULL, array_methods, NULL, NULL);
-
- /* Initialize the Array prototype object so it gets a length property. */
- if (!proto || !InitArrayObject(cx, proto, 0, NULL))
- return NULL;
- return proto;
-}
-
-JSObject *
-js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector)
-{
- JSObject *obj;
-
- obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
- if (!obj)
- return NULL;
- if (!InitArrayObject(cx, obj, length, vector)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- return obj;
-}
diff --git a/src/extension/script/js/jsarray.h b/src/extension/script/js/jsarray.h
deleted file mode 100644
index cbb2aedf1..000000000
--- a/src/extension/script/js/jsarray.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsarray_h___
-#define jsarray_h___
-/*
- * JS Array interface.
- */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-extern JSClass js_ArrayClass;
-
-extern JSObject *
-js_InitArrayClass(JSContext *cx, JSObject *obj);
-
-extern JSObject *
-js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector);
-
-extern JSBool
-js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
-
-extern JSBool
-js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length);
-
-extern JSBool
-js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
-
-/*
- * JS-specific heap sort function.
- */
-typedef int (*JSComparator)(const void *a, const void *b, void *arg);
-
-extern JSBool
-js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg);
-
-JS_END_EXTERN_C
-
-#endif /* jsarray_h___ */
diff --git a/src/extension/script/js/jsatom.c b/src/extension/script/js/jsatom.c
deleted file mode 100644
index 59cb4b801..000000000
--- a/src/extension/script/js/jsatom.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS atom table.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jshash.h" /* Added by JSIFY */
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsgc.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsopcode.h"
-#include "jsstr.h"
-
-JS_FRIEND_API(const char *)
-js_AtomToPrintableString(JSContext *cx, JSAtom *atom)
-{
- JSString *str;
- const char *bytes;
-
- str = js_QuoteString(cx, ATOM_TO_STRING(atom), 0);
- if (!str)
- return NULL;
- bytes = js_GetStringBytes(str);
- if (!bytes)
- JS_ReportOutOfMemory(cx);
- return bytes;
-}
-
-extern const char js_Error_str[]; /* trivial, from jsexn.h */
-
-/*
- * Keep this in sync with jspubtd.h -- an assertion below will insist that
- * its length match the JSType enum's JSTYPE_LIMIT limit value.
- */
-const char *js_type_str[] = {
- "undefined",
- "object",
- "function",
- "string",
- "number",
- "boolean",
-};
-
-const char *js_boolean_str[] = {
- js_false_str,
- js_true_str
-};
-
-const char js_Arguments_str[] = "Arguments";
-const char js_Array_str[] = "Array";
-const char js_Boolean_str[] = "Boolean";
-const char js_Call_str[] = "Call";
-const char js_Date_str[] = "Date";
-const char js_Function_str[] = "Function";
-const char js_Math_str[] = "Math";
-const char js_Number_str[] = "Number";
-const char js_Object_str[] = "Object";
-const char js_RegExp_str[] = "RegExp";
-const char js_Script_str[] = "Script";
-const char js_String_str[] = "String";
-const char js_anonymous_str[] = "anonymous";
-const char js_arguments_str[] = "arguments";
-const char js_arity_str[] = "arity";
-const char js_callee_str[] = "callee";
-const char js_caller_str[] = "caller";
-const char js_class_prototype_str[] = "prototype";
-const char js_constructor_str[] = "constructor";
-const char js_count_str[] = "__count__";
-const char js_eval_str[] = "eval";
-const char js_getter_str[] = "getter";
-const char js_get_str[] = "get";
-const char js_index_str[] = "index";
-const char js_input_str[] = "input";
-const char js_length_str[] = "length";
-const char js_name_str[] = "name";
-const char js_noSuchMethod_str[] = "__noSuchMethod__";
-const char js_parent_str[] = "__parent__";
-const char js_proto_str[] = "__proto__";
-const char js_setter_str[] = "setter";
-const char js_set_str[] = "set";
-const char js_toSource_str[] = "toSource";
-const char js_toString_str[] = "toString";
-const char js_toLocaleString_str[] = "toLocaleString";
-const char js_valueOf_str[] = "valueOf";
-
-#define HASH_OBJECT(o) ((JSHashNumber)(o) >> JSVAL_TAGBITS)
-#define HASH_INT(i) ((JSHashNumber)(i))
-#define HASH_DOUBLE(dp) ((JSHashNumber)(((uint32*)(dp))[0] ^ ((uint32*)(dp))[1]))
-#define HASH_BOOLEAN(b) ((JSHashNumber)(b))
-
-JS_STATIC_DLL_CALLBACK(JSHashNumber)
-js_hash_atom_key(const void *key)
-{
- jsval v;
- jsdouble *dp;
-
- /* Order JSVAL_IS_* tests by likelihood of success. */
- v = (jsval)key;
- if (JSVAL_IS_STRING(v))
- return js_HashString(JSVAL_TO_STRING(v));
- if (JSVAL_IS_INT(v))
- return HASH_INT(JSVAL_TO_INT(v));
- if (JSVAL_IS_DOUBLE(v)) {
- dp = JSVAL_TO_DOUBLE(v);
- return HASH_DOUBLE(dp);
- }
- if (JSVAL_IS_OBJECT(v))
- return HASH_OBJECT(JSVAL_TO_OBJECT(v));
- if (JSVAL_IS_BOOLEAN(v))
- return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
- return (JSHashNumber)v;
-}
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_compare_atom_keys(const void *k1, const void *k2)
-{
- jsval v1, v2;
-
- v1 = (jsval)k1, v2 = (jsval)k2;
- if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))
- return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));
- if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {
- double d1 = *JSVAL_TO_DOUBLE(v1);
- double d2 = *JSVAL_TO_DOUBLE(v2);
- if (JSDOUBLE_IS_NaN(d1))
- return JSDOUBLE_IS_NaN(d2);
-#if defined(XP_WIN)
- /* XXX MSVC miscompiles such that (NaN == 0) */
- if (JSDOUBLE_IS_NaN(d2))
- return JS_FALSE;
-#endif
- return d1 == d2;
- }
- return v1 == v2;
-}
-
-JS_STATIC_DLL_CALLBACK(int)
-js_compare_stub(const void *v1, const void *v2)
-{
- return 1;
-}
-
-/* These next two are exported to jsscript.c and used similarly there. */
-void * JS_DLL_CALLBACK
-js_alloc_table_space(void *priv, size_t size)
-{
- return malloc(size);
-}
-
-void JS_DLL_CALLBACK
-js_free_table_space(void *priv, void *item)
-{
- free(item);
-}
-
-JS_STATIC_DLL_CALLBACK(JSHashEntry *)
-js_alloc_atom(void *priv, const void *key)
-{
- JSAtomState *state = (JSAtomState *) priv;
- JSAtom *atom;
-
- atom = (JSAtom *) malloc(sizeof(JSAtom));
- if (!atom)
- return NULL;
-#ifdef JS_THREADSAFE
- state->tablegen++;
-#endif
- atom->entry.key = key;
- atom->entry.value = NULL;
- atom->flags = 0;
- atom->number = state->number++;
- return &atom->entry;
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-js_free_atom(void *priv, JSHashEntry *he, uintN flag)
-{
- if (flag != HT_FREE_ENTRY)
- return;
-#ifdef JS_THREADSAFE
- ((JSAtomState *)priv)->tablegen++;
-#endif
- free(he);
-}
-
-static JSHashAllocOps atom_alloc_ops = {
- js_alloc_table_space, js_free_table_space,
- js_alloc_atom, js_free_atom
-};
-
-#define JS_ATOM_HASH_SIZE 1024
-
-JSBool
-js_InitAtomState(JSContext *cx, JSAtomState *state)
-{
- state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,
- js_compare_atom_keys, js_compare_stub,
- &atom_alloc_ops, state);
- if (!state->table) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- state->runtime = cx->runtime;
-#ifdef JS_THREADSAFE
- js_InitLock(&state->lock);
- state->tablegen = 0;
-#endif
-
- if (!js_InitPinnedAtoms(cx, state)) {
- js_FreeAtomState(cx, state);
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JSBool
-js_InitPinnedAtoms(JSContext *cx, JSAtomState *state)
-{
- uintN i;
-
-#define FROB(lval,str) \
- JS_BEGIN_MACRO \
- if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED))) \
- return JS_FALSE; \
- JS_END_MACRO
-
- JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);
- for (i = 0; i < JSTYPE_LIMIT; i++)
- FROB(typeAtoms[i], js_type_str[i]);
-
- FROB(booleanAtoms[0], js_false_str);
- FROB(booleanAtoms[1], js_true_str);
- FROB(nullAtom, js_null_str);
-
- FROB(ArgumentsAtom, js_Arguments_str);
- FROB(ArrayAtom, js_Array_str);
- FROB(BooleanAtom, js_Boolean_str);
- FROB(CallAtom, js_Call_str);
- FROB(DateAtom, js_Date_str);
- FROB(ErrorAtom, js_Error_str);
- FROB(FunctionAtom, js_Function_str);
- FROB(MathAtom, js_Math_str);
- FROB(NumberAtom, js_Number_str);
- FROB(ObjectAtom, js_Object_str);
- FROB(RegExpAtom, js_RegExp_str);
- FROB(ScriptAtom, js_Script_str);
- FROB(StringAtom, js_String_str);
- FROB(anonymousAtom, js_anonymous_str);
- FROB(argumentsAtom, js_arguments_str);
- FROB(arityAtom, js_arity_str);
- FROB(calleeAtom, js_callee_str);
- FROB(callerAtom, js_caller_str);
- FROB(classPrototypeAtom, js_class_prototype_str);
- FROB(constructorAtom, js_constructor_str);
- FROB(countAtom, js_count_str);
- FROB(evalAtom, js_eval_str);
- FROB(getAtom, js_get_str);
- FROB(getterAtom, js_getter_str);
- FROB(indexAtom, js_index_str);
- FROB(inputAtom, js_input_str);
- FROB(lengthAtom, js_length_str);
- FROB(nameAtom, js_name_str);
- FROB(noSuchMethodAtom, js_noSuchMethod_str);
- FROB(parentAtom, js_parent_str);
- FROB(protoAtom, js_proto_str);
- FROB(setAtom, js_set_str);
- FROB(setterAtom, js_setter_str);
- FROB(toSourceAtom, js_toSource_str);
- FROB(toStringAtom, js_toString_str);
- FROB(toLocaleStringAtom, js_toLocaleString_str);
- FROB(valueOfAtom, js_valueOf_str);
-
-#undef FROB
-
- memset(&state->lazy, 0, sizeof state->lazy);
- return JS_TRUE;
-}
-
-/* NB: cx unused; js_FinishAtomState calls us with null cx. */
-void
-js_FreeAtomState(JSContext *cx, JSAtomState *state)
-{
- if (state->table)
- JS_HashTableDestroy(state->table);
-#ifdef JS_THREADSAFE
- js_FinishLock(&state->lock);
-#endif
- memset(state, 0, sizeof *state);
-}
-
-typedef struct UninternArgs {
- JSRuntime *rt;
- jsatomid leaks;
-} UninternArgs;
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_atom_uninterner(JSHashEntry *he, intN i, void *arg)
-{
- JSAtom *atom;
- UninternArgs *args;
-
- atom = (JSAtom *)he;
- args = (UninternArgs *)arg;
- if (ATOM_IS_STRING(atom))
- js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom));
- else if (ATOM_IS_OBJECT(atom))
- args->leaks++;
- return HT_ENUMERATE_NEXT;
-}
-
-void
-js_FinishAtomState(JSAtomState *state)
-{
- UninternArgs args;
-
- if (!state->table)
- return;
- args.rt = state->runtime;
- args.leaks = 0;
- JS_HashTableEnumerateEntries(state->table, js_atom_uninterner, &args);
-#ifdef DEBUG
- if (args.leaks != 0) {
- fprintf(stderr,
-"JS engine warning: %lu atoms remain after destroying the JSRuntime.\n"
-" These atoms may point to freed memory. Things reachable\n"
-" through them have not been finalized.\n",
- (unsigned long) args.leaks);
- }
-#endif
- js_FreeAtomState(NULL, state);
-}
-
-typedef struct MarkArgs {
- uintN gcflags;
- JSGCThingMarker mark;
- void *data;
-} MarkArgs;
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_atom_marker(JSHashEntry *he, intN i, void *arg)
-{
- JSAtom *atom;
- MarkArgs *args;
- jsval key;
-
- atom = (JSAtom *)he;
- args = (MarkArgs *)arg;
- if ((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) ||
- (args->gcflags & GC_KEEP_ATOMS)) {
- atom->flags |= ATOM_MARK;
- key = ATOM_KEY(atom);
- if (JSVAL_IS_GCTHING(key))
- args->mark(JSVAL_TO_GCTHING(key), args->data);
- }
- return HT_ENUMERATE_NEXT;
-}
-
-void
-js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
- void *data)
-{
- MarkArgs args;
-
- if (!state->table)
- return;
- args.gcflags = gcflags;
- args.mark = mark;
- args.data = data;
- JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args);
-}
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_atom_sweeper(JSHashEntry *he, intN i, void *arg)
-{
- JSAtom *atom;
- JSAtomState *state;
-
- atom = (JSAtom *)he;
- if (atom->flags & ATOM_MARK) {
- atom->flags &= ~ATOM_MARK;
- state = (JSAtomState *)arg;
- state->liveAtoms++;
- return HT_ENUMERATE_NEXT;
- }
- JS_ASSERT((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) == 0);
- atom->entry.key = NULL;
- atom->flags = 0;
- return HT_ENUMERATE_REMOVE;
-}
-
-void
-js_SweepAtomState(JSAtomState *state)
-{
- state->liveAtoms = 0;
- if (state->table)
- JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, state);
-}
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_atom_unpinner(JSHashEntry *he, intN i, void *arg)
-{
- JSAtom *atom;
-
- atom = (JSAtom *)he;
- atom->flags &= ~ATOM_PINNED;
- return HT_ENUMERATE_NEXT;
-}
-
-void
-js_UnpinPinnedAtoms(JSAtomState *state)
-{
- if (state->table)
- JS_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL);
-}
-
-static JSAtom *
-js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
-{
- JSAtomState *state;
- JSHashTable *table;
- JSHashEntry *he, **hep;
- JSAtom *atom;
-
- state = &cx->runtime->atomState;
- JS_LOCK(&state->lock, cx);
- table = state->table;
- hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
- if ((he = *hep) == NULL) {
- he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
- if (!he) {
- JS_ReportOutOfMemory(cx);
- atom = NULL;
- goto out;
- }
- }
-
- atom = (JSAtom *)he;
- atom->flags |= flags;
- cx->lastAtom = atom;
-out:
- JS_UNLOCK(&state->lock,cx);
- return atom;
-}
-
-JSAtom *
-js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags)
-{
- jsval key;
- JSHashNumber keyHash;
-
- /* XXX must be set in the following order or MSVC1.52 will crash */
- keyHash = HASH_OBJECT(obj);
- key = OBJECT_TO_JSVAL(obj);
- return js_AtomizeHashedKey(cx, key, keyHash, flags);
-}
-
-JSAtom *
-js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
-{
- jsval key;
- JSHashNumber keyHash;
-
- key = BOOLEAN_TO_JSVAL(b);
- keyHash = HASH_BOOLEAN(b);
- return js_AtomizeHashedKey(cx, key, keyHash, flags);
-}
-
-JSAtom *
-js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
-{
- jsval key;
- JSHashNumber keyHash;
-
- key = INT_TO_JSVAL(i);
- keyHash = HASH_INT(i);
- return js_AtomizeHashedKey(cx, key, keyHash, flags);
-}
-
-/* Worst-case alignment grain and aligning macro for 2x-sized buffer. */
-#define ALIGNMENT(t) JS_MAX(JSVAL_ALIGN, sizeof(t))
-#define ALIGN(b,t) ((t*) &(b)[ALIGNMENT(t) - (jsuword)(b) % ALIGNMENT(t)])
-
-JSAtom *
-js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
-{
- jsdouble *dp;
- JSHashNumber keyHash;
- jsval key;
- JSAtomState *state;
- JSHashTable *table;
- JSHashEntry *he, **hep;
- JSAtom *atom;
- char buf[2 * ALIGNMENT(double)];
-
- dp = ALIGN(buf, double);
- *dp = d;
- keyHash = HASH_DOUBLE(dp);
- key = DOUBLE_TO_JSVAL(dp);
- state = &cx->runtime->atomState;
- JS_LOCK(&state->lock, cx);
- table = state->table;
- hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
- if ((he = *hep) == NULL) {
-#ifdef JS_THREADSAFE
- uint32 gen = state->tablegen;
-#endif
- JS_UNLOCK(&state->lock,cx);
- if (!js_NewDoubleValue(cx, d, &key))
- return NULL;
- JS_LOCK(&state->lock, cx);
-#ifdef JS_THREADSAFE
- if (state->tablegen != gen) {
- hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
- if ((he = *hep) != NULL) {
- atom = (JSAtom *)he;
- goto out;
- }
- }
-#endif
- he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
- if (!he) {
- JS_ReportOutOfMemory(cx);
- atom = NULL;
- goto out;
- }
- }
-
- atom = (JSAtom *)he;
- atom->flags |= flags;
- cx->lastAtom = atom;
-out:
- JS_UNLOCK(&state->lock,cx);
- return atom;
-}
-
-JSAtom *
-js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
-{
- JSHashNumber keyHash;
- jsval key;
- JSAtomState *state;
- JSHashTable *table;
- JSHashEntry *he, **hep;
- JSAtom *atom;
-
- keyHash = js_HashString(str);
- key = STRING_TO_JSVAL(str);
- state = &cx->runtime->atomState;
- JS_LOCK(&state->lock, cx);
- table = state->table;
- hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
- if ((he = *hep) == NULL) {
-#ifdef JS_THREADSAFE
- uint32 gen = state->tablegen;
- JS_UNLOCK(&state->lock, cx);
-#endif
-
- if (flags & ATOM_TMPSTR) {
- str = (flags & ATOM_NOCOPY)
- ? js_NewString(cx, str->chars, str->length, 0)
- : js_NewStringCopyN(cx, str->chars, str->length, 0);
- if (!str)
- return NULL;
- key = STRING_TO_JSVAL(str);
- } else {
- if (!JS_MakeStringImmutable(cx, str))
- return NULL;
- }
-
-#ifdef JS_THREADSAFE
- JS_LOCK(&state->lock, cx);
- if (state->tablegen != gen) {
- hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
- if ((he = *hep) != NULL) {
- atom = (JSAtom *)he;
- if (flags & ATOM_NOCOPY)
- str->chars = NULL;
- goto out;
- }
- }
-#endif
-
- he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
- if (!he) {
- JS_ReportOutOfMemory(cx);
- atom = NULL;
- goto out;
- }
- }
-
- atom = (JSAtom *)he;
- atom->flags |= flags & (ATOM_PINNED | ATOM_INTERNED);
- cx->lastAtom = atom;
-out:
- JS_UNLOCK(&state->lock,cx);
- return atom;
-}
-
-JS_FRIEND_API(JSAtom *)
-js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags)
-{
- jschar *chars;
- JSString *str;
- JSAtom *atom;
- char buf[2 * ALIGNMENT(JSString)];
-
- /*
- * Avoiding the malloc in js_InflateString on shorter strings saves us
- * over 20,000 malloc calls on mozilla browser startup. This compares to
- * only 131 calls where the string is longer than a 31 char (net) buffer.
- * The vast majority of atomized strings are already in the hashtable. So
- * js_AtomizeString rarely has to copy the temp string we make.
- */
-#define ATOMIZE_BUF_MAX 32
- jschar inflated[ATOMIZE_BUF_MAX];
-
- if (length < ATOMIZE_BUF_MAX) {
- js_InflateStringToBuffer(inflated, bytes, length);
- chars = inflated;
- } else {
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return NULL;
- flags |= ATOM_NOCOPY;
- }
-
- str = ALIGN(buf, JSString);
-
- str->chars = chars;
- str->length = length;
- atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
- if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars))
- JS_free(cx, chars);
- return atom;
-}
-
-JS_FRIEND_API(JSAtom *)
-js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
-{
- JSString *str;
- char buf[2 * ALIGNMENT(JSString)];
-
- str = ALIGN(buf, JSString);
- str->chars = (jschar *)chars;
- str->length = length;
- return js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
-}
-
-JSAtom *
-js_AtomizeValue(JSContext *cx, jsval value, uintN flags)
-{
- if (JSVAL_IS_STRING(value))
- return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
- if (JSVAL_IS_INT(value))
- return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
- if (JSVAL_IS_DOUBLE(value))
- return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
- if (JSVAL_IS_OBJECT(value))
- return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags);
- if (JSVAL_IS_BOOLEAN(value))
- return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
- return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags);
-}
-
-JSAtom *
-js_ValueToStringAtom(JSContext *cx, jsval v)
-{
- JSString *str;
-
- str = js_ValueToString(cx, v);
- if (!str)
- return NULL;
- return js_AtomizeString(cx, str, 0);
-}
-
-JS_STATIC_DLL_CALLBACK(JSHashNumber)
-js_hash_atom_ptr(const void *key)
-{
- const JSAtom *atom = key;
- return atom->number;
-}
-
-JS_STATIC_DLL_CALLBACK(void *)
-js_alloc_temp_space(void *priv, size_t size)
-{
- JSContext *cx = priv;
- void *space;
-
- JS_ARENA_ALLOCATE(space, &cx->tempPool, size);
- if (!space)
- JS_ReportOutOfMemory(cx);
- return space;
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-js_free_temp_space(void *priv, void *item)
-{
-}
-
-JS_STATIC_DLL_CALLBACK(JSHashEntry *)
-js_alloc_temp_entry(void *priv, const void *key)
-{
- JSContext *cx = priv;
- JSAtomListElement *ale;
-
- JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
- if (!ale) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- return &ale->entry;
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-js_free_temp_entry(void *priv, JSHashEntry *he, uintN flag)
-{
-}
-
-static JSHashAllocOps temp_alloc_ops = {
- js_alloc_temp_space, js_free_temp_space,
- js_alloc_temp_entry, js_free_temp_entry
-};
-
-JSAtomListElement *
-js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
-{
- JSAtomListElement *ale, *ale2, *next;
- JSHashEntry **hep;
-
- ATOM_LIST_LOOKUP(ale, hep, al, atom);
- if (!ale) {
- if (al->count <= 5) {
- /* Few enough for linear search, no hash table needed. */
- JS_ASSERT(!al->table);
- ale = (JSAtomListElement *)js_alloc_temp_entry(cx, atom);
- if (!ale)
- return NULL;
- ALE_SET_ATOM(ale, atom);
- ALE_SET_NEXT(ale, al->list);
- al->list = ale;
- } else {
- /* We want to hash. Have we already made a hash table? */
- if (!al->table) {
- /* No hash table yet, so hep had better be null! */
- JS_ASSERT(!hep);
- al->table = JS_NewHashTable(8, js_hash_atom_ptr,
- JS_CompareValues, JS_CompareValues,
- &temp_alloc_ops, cx);
- if (!al->table)
- return NULL;
-
- /* Insert each ale on al->list into the new hash table. */
- for (ale2 = al->list; ale2; ale2 = next) {
- next = ALE_NEXT(ale2);
- ale2->entry.keyHash = ALE_ATOM(ale2)->number;
- hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash,
- ale2->entry.key);
- ALE_SET_NEXT(ale2, *hep);
- *hep = &ale2->entry;
- }
- al->list = NULL;
-
- /* Set hep for insertion of atom's ale, immediately below. */
- hep = JS_HashTableRawLookup(al->table, atom->number, atom);
- }
-
- /* Finally, add an entry for atom into the hash bucket at hep. */
- ale = (JSAtomListElement *)
- JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL);
- if (!ale)
- return NULL;
- }
-
- ALE_SET_INDEX(ale, al->count++);
- }
- return ale;
-}
-
-JS_FRIEND_API(JSAtom *)
-js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
-{
- JSAtom *atom;
- static JSAtom dummy;
-
- JS_ASSERT(map->vector && i < map->length);
- if (!map->vector || i >= map->length) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%lu", (unsigned long)i);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_ATOMIC_NUMBER, numBuf);
- return &dummy;
- }
- atom = map->vector[i];
- JS_ASSERT(atom);
- return atom;
-}
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_map_atom(JSHashEntry *he, intN i, void *arg)
-{
- JSAtomListElement *ale = (JSAtomListElement *)he;
- JSAtom **vector = arg;
-
- vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
- return HT_ENUMERATE_NEXT;
-}
-
-#ifdef DEBUG
-jsrefcount js_atom_map_count;
-jsrefcount js_atom_map_hash_table_count;
-#endif
-
-JS_FRIEND_API(JSBool)
-js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
-{
- JSAtom **vector;
- JSAtomListElement *ale;
- uint32 count;
-
-#ifdef DEBUG
- JS_ATOMIC_INCREMENT(&js_atom_map_count);
-#endif
- ale = al->list;
- if (!ale && !al->table) {
- map->vector = NULL;
- map->length = 0;
- return JS_TRUE;
- }
-
- count = al->count;
- if (count >= ATOM_INDEX_LIMIT) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_TOO_MANY_LITERALS);
- return JS_FALSE;
- }
- vector = (JSAtom **) JS_malloc(cx, (size_t) count * sizeof *vector);
- if (!vector)
- return JS_FALSE;
-
- if (al->table) {
-#ifdef DEBUG
- JS_ATOMIC_INCREMENT(&js_atom_map_hash_table_count);
-#endif
- JS_HashTableEnumerateEntries(al->table, js_map_atom, vector);
- } else {
- do {
- vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
- } while ((ale = ALE_NEXT(ale)) != NULL);
- }
- ATOM_LIST_INIT(al);
-
- map->vector = vector;
- map->length = (jsatomid)count;
- return JS_TRUE;
-}
-
-JS_FRIEND_API(void)
-js_FreeAtomMap(JSContext *cx, JSAtomMap *map)
-{
- if (map->vector) {
- JS_free(cx, map->vector);
- map->vector = NULL;
- }
- map->length = 0;
-}
diff --git a/src/extension/script/js/jsatom.h b/src/extension/script/js/jsatom.h
deleted file mode 100644
index ec9b52f80..000000000
--- a/src/extension/script/js/jsatom.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsatom_h___
-#define jsatom_h___
-/*
- * JS atom table.
- */
-#include <stddef.h>
-#include "jstypes.h"
-#include "jshash.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-#ifdef JS_THREADSAFE
-#include "jslock.h"
-#endif
-
-JS_BEGIN_EXTERN_C
-
-#define ATOM_PINNED 0x01 /* atom is pinned against GC */
-#define ATOM_INTERNED 0x02 /* pinned variant for JS_Intern* API */
-#define ATOM_MARK 0x04 /* atom is reachable via GC */
-#define ATOM_NOCOPY 0x40 /* don't copy atom string bytes */
-#define ATOM_TMPSTR 0x80 /* internal, to avoid extra string */
-
-struct JSAtom {
- JSHashEntry entry; /* key is jsval, value keyword info */
- uint32 flags; /* pinned, interned, and mark flags */
- jsatomid number; /* atom serial number and hash code */
-};
-
-#define ATOM_KEY(atom) ((jsval)(atom)->entry.key)
-#define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom))
-#define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom))
-#define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom))
-#define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom))
-#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom))
-#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom))
-#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom))
-#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom))
-#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
-#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
-
-/*
- * Return a printable, lossless char[] representation of a string-type atom.
- * The lifetime of the result extends at least until the next GC activation,
- * longer if cx's string newborn root is not overwritten.
- */
-extern JS_FRIEND_API(const char *)
-js_AtomToPrintableString(JSContext *cx, JSAtom *atom);
-
-#define ATOM_KEYWORD(atom) ((struct keyword *)(atom)->entry.value)
-#define ATOM_SET_KEYWORD(atom,kw) ((atom)->entry.value = (kw))
-
-struct JSAtomListElement {
- JSHashEntry entry;
-};
-
-#define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key)
-#define ALE_INDEX(ale) ((jsatomid) (ale)->entry.value)
-#define ALE_JSOP(ale) ((JSOp) (ale)->entry.value)
-#define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next)
-
-#define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom))
-#define ALE_SET_INDEX(ale,index)((ale)->entry.value = (void *)(index))
-#define ALE_SET_JSOP(ale,op) ((ale)->entry.value = (void *)(op))
-#define ALE_SET_NEXT(ale,link) ((ale)->entry.next = (JSHashEntry *)(link))
-
-struct JSAtomList {
- JSAtomListElement *list; /* literals indexed for mapping */
- JSHashTable *table; /* hash table if list gets too long */
- jsuint count; /* count of indexed literals */
-};
-
-#define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \
- (al)->count = 0)
-
-#define ATOM_LIST_SEARCH(_ale,_al,_atom) \
- JS_BEGIN_MACRO \
- JSHashEntry **_hep; \
- ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \
- JS_END_MACRO
-
-#define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \
- JS_BEGIN_MACRO \
- if ((_al)->table) { \
- _hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \
- _ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \
- } else { \
- JSAtomListElement **_alep = &(_al)->list; \
- _hep = NULL; \
- while ((_ale = *_alep) != NULL) { \
- if (ALE_ATOM(_ale) == (_atom)) { \
- /* Hit, move atom's element to the front of the list. */ \
- *_alep = ALE_NEXT(_ale); \
- ALE_SET_NEXT(_ale, (_al)->list); \
- (_al)->list = _ale; \
- break; \
- } \
- _alep = (JSAtomListElement **)&_ale->entry.next; \
- } \
- } \
- JS_END_MACRO
-
-struct JSAtomMap {
- JSAtom **vector; /* array of ptrs to indexed atoms */
- jsatomid length; /* count of (to-be-)indexed atoms */
-};
-
-struct JSAtomState {
- JSRuntime *runtime; /* runtime that owns us */
- JSHashTable *table; /* hash table containing all atoms */
- jsatomid number; /* one beyond greatest atom number */
- jsatomid liveAtoms; /* number of live atoms after last GC */
-
- /* Type names and value literals. */
- JSAtom *typeAtoms[JSTYPE_LIMIT];
- JSAtom *booleanAtoms[2];
- JSAtom *nullAtom;
-
- /* Various built-in or commonly-used atoms, pinned on first context. */
- JSAtom *ArgumentsAtom;
- JSAtom *ArrayAtom;
- JSAtom *BooleanAtom;
- JSAtom *CallAtom;
- JSAtom *DateAtom;
- JSAtom *ErrorAtom;
- JSAtom *FunctionAtom;
- JSAtom *MathAtom;
- JSAtom *NumberAtom;
- JSAtom *ObjectAtom;
- JSAtom *RegExpAtom;
- JSAtom *ScriptAtom;
- JSAtom *StringAtom;
- JSAtom *anonymousAtom;
- JSAtom *argumentsAtom;
- JSAtom *arityAtom;
- JSAtom *calleeAtom;
- JSAtom *callerAtom;
- JSAtom *classPrototypeAtom;
- JSAtom *constructorAtom;
- JSAtom *countAtom;
- JSAtom *evalAtom;
- JSAtom *getAtom;
- JSAtom *getterAtom;
- JSAtom *indexAtom;
- JSAtom *inputAtom;
- JSAtom *lengthAtom;
- JSAtom *nameAtom;
- JSAtom *noSuchMethodAtom;
- JSAtom *parentAtom;
- JSAtom *protoAtom;
- JSAtom *setAtom;
- JSAtom *setterAtom;
- JSAtom *toLocaleStringAtom;
- JSAtom *toSourceAtom;
- JSAtom *toStringAtom;
- JSAtom *valueOfAtom;
-
- /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
- struct {
- JSAtom *EvalErrorAtom;
- JSAtom *InfinityAtom;
- JSAtom *InternalErrorAtom;
- JSAtom *NaNAtom;
- JSAtom *RangeErrorAtom;
- JSAtom *ReferenceErrorAtom;
- JSAtom *SyntaxErrorAtom;
- JSAtom *TypeErrorAtom;
- JSAtom *URIErrorAtom;
- JSAtom *decodeURIAtom;
- JSAtom *decodeURIComponentAtom;
- JSAtom *defineGetterAtom;
- JSAtom *defineSetterAtom;
- JSAtom *encodeURIAtom;
- JSAtom *encodeURIComponentAtom;
- JSAtom *escapeAtom;
- JSAtom *hasOwnPropertyAtom;
- JSAtom *isFiniteAtom;
- JSAtom *isNaNAtom;
- JSAtom *isPrototypeOfAtom;
- JSAtom *lookupGetterAtom;
- JSAtom *lookupSetterAtom;
- JSAtom *parseFloatAtom;
- JSAtom *parseIntAtom;
- JSAtom *propertyIsEnumerableAtom;
- JSAtom *unescapeAtom;
- JSAtom *unevalAtom;
- JSAtom *unwatchAtom;
- JSAtom *watchAtom;
- } lazy;
-
-#ifdef JS_THREADSAFE
- JSThinLock lock;
- volatile uint32 tablegen;
-#endif
-};
-
-/* Well-known predefined strings and their atoms. */
-extern const char *js_type_str[];
-extern const char *js_boolean_str[];
-
-extern const char js_Arguments_str[];
-extern const char js_Array_str[];
-extern const char js_Boolean_str[];
-extern const char js_Call_str[];
-extern const char js_Date_str[];
-extern const char js_Function_str[];
-extern const char js_Math_str[];
-extern const char js_Number_str[];
-extern const char js_Object_str[];
-extern const char js_RegExp_str[];
-extern const char js_Script_str[];
-extern const char js_String_str[];
-extern const char js_anonymous_str[];
-extern const char js_arguments_str[];
-extern const char js_arity_str[];
-extern const char js_callee_str[];
-extern const char js_caller_str[];
-extern const char js_class_prototype_str[];
-extern const char js_constructor_str[];
-extern const char js_count_str[];
-extern const char js_eval_str[];
-extern const char js_getter_str[];
-extern const char js_get_str[];
-extern const char js_index_str[];
-extern const char js_input_str[];
-extern const char js_length_str[];
-extern const char js_name_str[];
-extern const char js_noSuchMethod_str[];
-extern const char js_parent_str[];
-extern const char js_proto_str[];
-extern const char js_setter_str[];
-extern const char js_set_str[];
-extern const char js_toSource_str[];
-extern const char js_toString_str[];
-extern const char js_toLocaleString_str[];
-extern const char js_valueOf_str[];
-
-/*
- * Initialize atom state. Return true on success, false with an out of
- * memory error report on failure.
- */
-extern JSBool
-js_InitAtomState(JSContext *cx, JSAtomState *state);
-
-/*
- * Free and clear atom state (except for any interned string atoms).
- */
-extern void
-js_FreeAtomState(JSContext *cx, JSAtomState *state);
-
-/*
- * Interned strings are atoms that live until state's runtime is destroyed.
- * This function frees all interned string atoms, and then frees and clears
- * state's members (just as js_FreeAtomState does), unless there aren't any
- * interned strings in state -- in which case state must be "free" already.
- *
- * NB: js_FreeAtomState is called for each "last" context being destroyed in
- * a runtime, where there may yet be another context created in the runtime;
- * whereas js_FinishAtomState is called from JS_DestroyRuntime, when we know
- * that no more contexts will be created. Thus we minimize garbage during
- * context-free episodes on a runtime, while preserving atoms created by the
- * JS_Intern*String APIs for the life of the runtime.
- */
-extern void
-js_FinishAtomState(JSAtomState *state);
-
-/*
- * Atom garbage collection hooks.
- */
-typedef void
-(*JSGCThingMarker)(void *thing, void *data);
-
-extern void
-js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
- void *data);
-
-extern void
-js_SweepAtomState(JSAtomState *state);
-
-extern JSBool
-js_InitPinnedAtoms(JSContext *cx, JSAtomState *state);
-
-extern void
-js_UnpinPinnedAtoms(JSAtomState *state);
-
-/*
- * Find or create the atom for an object. If we create a new atom, give it the
- * type indicated in flags. Return 0 on failure to allocate memory.
- */
-extern JSAtom *
-js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags);
-
-/*
- * Find or create the atom for a Boolean value. If we create a new atom, give
- * it the type indicated in flags. Return 0 on failure to allocate memory.
- */
-extern JSAtom *
-js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
-
-/*
- * Find or create the atom for an integer value. If we create a new atom, give
- * it the type indicated in flags. Return 0 on failure to allocate memory.
- */
-extern JSAtom *
-js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
-
-/*
- * Find or create the atom for a double value. If we create a new atom, give
- * it the type indicated in flags. Return 0 on failure to allocate memory.
- */
-extern JSAtom *
-js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
-
-/*
- * Find or create the atom for a string. If we create a new atom, give it the
- * type indicated in flags. Return 0 on failure to allocate memory.
- */
-extern JSAtom *
-js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
-
-extern JS_FRIEND_API(JSAtom *)
-js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
-
-extern JS_FRIEND_API(JSAtom *)
-js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
-
-/*
- * This variant handles all value tag types.
- */
-extern JSAtom *
-js_AtomizeValue(JSContext *cx, jsval value, uintN flags);
-
-/*
- * Convert v to an atomized string.
- */
-extern JSAtom *
-js_ValueToStringAtom(JSContext *cx, jsval v);
-
-/*
- * Assign atom an index and insert it on al.
- */
-extern JSAtomListElement *
-js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al);
-
-/*
- * Get the atom with index i from map.
- */
-extern JS_FRIEND_API(JSAtom *)
-js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i);
-
-/*
- * For all unmapped atoms recorded in al, add a mapping from the atom's index
- * to its address. The GC must not run until all indexed atoms in atomLists
- * have been mapped by scripts connected to live objects (Function and Script
- * class objects have scripts as/in their private data -- the GC knows about
- * these two classes).
- */
-extern JS_FRIEND_API(JSBool)
-js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al);
-
-/*
- * Free map->vector and clear map.
- */
-extern JS_FRIEND_API(void)
-js_FreeAtomMap(JSContext *cx, JSAtomMap *map);
-
-JS_END_EXTERN_C
-
-#endif /* jsatom_h___ */
diff --git a/src/extension/script/js/jsautocfg.h b/src/extension/script/js/jsautocfg.h
deleted file mode 100644
index a7f5d6bc8..000000000
--- a/src/extension/script/js/jsautocfg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef js_cpucfg___
-#define js_cpucfg___
-
-/* AUTOMATICALLY GENERATED - DO NOT EDIT */
-
-#define IS_LITTLE_ENDIAN 1
-#undef IS_BIG_ENDIAN
-
-#define JS_BYTES_PER_BYTE 1L
-#define JS_BYTES_PER_SHORT 2L
-#define JS_BYTES_PER_INT 4L
-#define JS_BYTES_PER_INT64 8L
-#define JS_BYTES_PER_LONG 4L
-#define JS_BYTES_PER_FLOAT 4L
-#define JS_BYTES_PER_DOUBLE 8L
-#define JS_BYTES_PER_WORD 4L
-#define JS_BYTES_PER_DWORD 8L
-
-#define JS_BITS_PER_BYTE 8L
-#define JS_BITS_PER_SHORT 16L
-#define JS_BITS_PER_INT 32L
-#define JS_BITS_PER_INT64 64L
-#define JS_BITS_PER_LONG 32L
-#define JS_BITS_PER_FLOAT 32L
-#define JS_BITS_PER_DOUBLE 64L
-#define JS_BITS_PER_WORD 32L
-
-#define JS_BITS_PER_BYTE_LOG2 3L
-#define JS_BITS_PER_SHORT_LOG2 4L
-#define JS_BITS_PER_INT_LOG2 5L
-#define JS_BITS_PER_INT64_LOG2 6L
-#define JS_BITS_PER_LONG_LOG2 5L
-#define JS_BITS_PER_FLOAT_LOG2 5L
-#define JS_BITS_PER_DOUBLE_LOG2 6L
-#define JS_BITS_PER_WORD_LOG2 5L
-
-#define JS_ALIGN_OF_SHORT 2L
-#define JS_ALIGN_OF_INT 4L
-#define JS_ALIGN_OF_LONG 4L
-#define JS_ALIGN_OF_INT64 4L
-#define JS_ALIGN_OF_FLOAT 4L
-#define JS_ALIGN_OF_DOUBLE 4L
-#define JS_ALIGN_OF_POINTER 4L
-#define JS_ALIGN_OF_WORD 4L
-
-#define JS_BYTES_PER_WORD_LOG2 2L
-#define JS_BYTES_PER_DWORD_LOG2 3L
-#define JS_WORDS_PER_DWORD_LOG2 1L
-
-#endif /* js_cpucfg___ */
diff --git a/src/extension/script/js/jsbit.h b/src/extension/script/js/jsbit.h
deleted file mode 100644
index db41acf9f..000000000
--- a/src/extension/script/js/jsbit.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsbit_h___
-#define jsbit_h___
-
-#include "jstypes.h"
-JS_BEGIN_EXTERN_C
-
-/*
-** A jsbitmap_t is a long integer that can be used for bitmaps
-*/
-typedef JSUword jsbitmap_t; /* NSPR name, a la Unix system types */
-typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */
-
-#define JS_TEST_BIT(_map,_bit) \
- ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & (1L << ((_bit) & (JS_BITS_PER_WORD-1))))
-#define JS_SET_BIT(_map,_bit) \
- ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= (1L << ((_bit) & (JS_BITS_PER_WORD-1))))
-#define JS_CLEAR_BIT(_map,_bit) \
- ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= ~(1L << ((_bit) & (JS_BITS_PER_WORD-1))))
-
-/*
-** Compute the log of the least power of 2 greater than or equal to n
-*/
-extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i);
-
-/*
-** Compute the log of the greatest power of 2 less than or equal to n
-*/
-extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i);
-
-/*
-** Macro version of JS_CeilingLog2: Compute the log of the least power of
-** 2 greater than or equal to _n. The result is returned in _log2.
-*/
-#define JS_CEILING_LOG2(_log2,_n) \
- JS_BEGIN_MACRO \
- JSUint32 j_ = (JSUint32)(_n); \
- (_log2) = 0; \
- if ((j_) & ((j_)-1)) \
- (_log2) += 1; \
- if ((j_) >> 16) \
- (_log2) += 16, (j_) >>= 16; \
- if ((j_) >> 8) \
- (_log2) += 8, (j_) >>= 8; \
- if ((j_) >> 4) \
- (_log2) += 4, (j_) >>= 4; \
- if ((j_) >> 2) \
- (_log2) += 2, (j_) >>= 2; \
- if ((j_) >> 1) \
- (_log2) += 1; \
- JS_END_MACRO
-
-/*
-** Macro version of JS_FloorLog2: Compute the log of the greatest power of
-** 2 less than or equal to _n. The result is returned in _log2.
-**
-** This is equivalent to finding the highest set bit in the word.
-*/
-#define JS_FLOOR_LOG2(_log2,_n) \
- JS_BEGIN_MACRO \
- JSUint32 j_ = (JSUint32)(_n); \
- (_log2) = 0; \
- if ((j_) >> 16) \
- (_log2) += 16, (j_) >>= 16; \
- if ((j_) >> 8) \
- (_log2) += 8, (j_) >>= 8; \
- if ((j_) >> 4) \
- (_log2) += 4, (j_) >>= 4; \
- if ((j_) >> 2) \
- (_log2) += 2, (j_) >>= 2; \
- if ((j_) >> 1) \
- (_log2) += 1; \
- JS_END_MACRO
-
-JS_END_EXTERN_C
-#endif /* jsbit_h___ */
diff --git a/src/extension/script/js/jsbool.c b/src/extension/script/js/jsbool.c
deleted file mode 100644
index 05f596556..000000000
--- a/src/extension/script/js/jsbool.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS boolean implementation.
- */
-#include "jsstddef.h"
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jsbool.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsstr.h"
-
-static JSClass boolean_class = {
- "Boolean",
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-#if JS_HAS_TOSOURCE
-#include "jsprf.h"
-
-static JSBool
-bool_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsval v;
- char buf[32];
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (!JSVAL_IS_BOOLEAN(v))
- return js_obj_toSource(cx, obj, argc, argv, rval);
- JS_snprintf(buf, sizeof buf, "(new %s(%s))",
- boolean_class.name,
- js_boolean_str[JSVAL_TO_BOOLEAN(v) ? 1 : 0]);
- str = JS_NewStringCopyZ(cx, buf);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif
-
-static JSBool
-bool_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsval v;
- JSAtom *atom;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (!JSVAL_IS_BOOLEAN(v))
- return js_obj_toString(cx, obj, argc, argv, rval);
- atom = cx->runtime->atomState.booleanAtoms[JSVAL_TO_BOOLEAN(v) ? 1 : 0];
- str = ATOM_TO_STRING(atom);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-bool_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
- return JS_FALSE;
- *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- return JS_TRUE;
-}
-
-static JSFunctionSpec boolean_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, bool_toSource, 0,0,0},
-#endif
- {js_toString_str, bool_toString, 0,0,0},
- {js_valueOf_str, bool_valueOf, 0,0,0},
- {0,0,0,0,0}
-};
-
-#ifdef XP_MAC
-#undef Boolean
-#define Boolean js_Boolean
-#endif
-
-static JSBool
-Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSBool b;
- jsval bval;
-
- if (argc != 0) {
- if (!js_ValueToBoolean(cx, argv[0], &b))
- return JS_FALSE;
- bval = BOOLEAN_TO_JSVAL(b);
- } else {
- bval = JSVAL_FALSE;
- }
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- *rval = bval;
- return JS_TRUE;
- }
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, bval);
- return JS_TRUE;
-}
-
-JSObject *
-js_InitBooleanClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
-
- proto = JS_InitClass(cx, obj, NULL, &boolean_class, Boolean, 1,
- NULL, boolean_methods, NULL, NULL);
- if (!proto)
- return NULL;
- OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_FALSE);
- return proto;
-}
-
-JSObject *
-js_BooleanToObject(JSContext *cx, JSBool b)
-{
- JSObject *obj;
-
- obj = js_NewObject(cx, &boolean_class, NULL, NULL);
- if (!obj)
- return NULL;
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, BOOLEAN_TO_JSVAL(b));
- return obj;
-}
-
-JSString *
-js_BooleanToString(JSContext *cx, JSBool b)
-{
- return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]);
-}
-
-JSBool
-js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
-{
- JSBool b;
- jsdouble d;
-
-#if defined _MSC_VER && _MSC_VER <= 800
- /* MSVC1.5 coredumps */
- if (!bp)
- return JS_TRUE;
- /* This should be an if-else chain, but MSVC1.5 crashes if it is. */
-#define ELSE
-#else
-#define ELSE else
-#endif
-
- if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
- /* Must return early to avoid falling thru to JSVAL_IS_OBJECT case. */
- *bp = JS_FALSE;
- return JS_TRUE;
- }
- if (JSVAL_IS_OBJECT(v)) {
- if (!JSVERSION_IS_ECMA(cx->version)) {
- if (!OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), JSTYPE_BOOLEAN, &v))
- return JS_FALSE;
- if (!JSVAL_IS_BOOLEAN(v))
- v = JSVAL_TRUE; /* non-null object is true */
- b = JSVAL_TO_BOOLEAN(v);
- } else {
- b = JS_TRUE;
- }
- } ELSE
- if (JSVAL_IS_STRING(v)) {
- b = JSSTRING_LENGTH(JSVAL_TO_STRING(v)) ? JS_TRUE : JS_FALSE;
- } ELSE
- if (JSVAL_IS_INT(v)) {
- b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE;
- } ELSE
- if (JSVAL_IS_DOUBLE(v)) {
- d = *JSVAL_TO_DOUBLE(v);
- b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE;
- } ELSE
-#if defined _MSC_VER && _MSC_VER <= 800
- if (JSVAL_IS_BOOLEAN(v)) {
- b = JSVAL_TO_BOOLEAN(v);
- }
-#else
- {
- JS_ASSERT(JSVAL_IS_BOOLEAN(v));
- b = JSVAL_TO_BOOLEAN(v);
- }
-#endif
-
-#undef ELSE
- *bp = b;
- return JS_TRUE;
-}
diff --git a/src/extension/script/js/jsbool.h b/src/extension/script/js/jsbool.h
deleted file mode 100644
index c07910f59..000000000
--- a/src/extension/script/js/jsbool.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsbool_h___
-#define jsbool_h___
-/*
- * JS boolean interface.
- */
-
-JS_BEGIN_EXTERN_C
-
-extern JSObject *
-js_InitBooleanClass(JSContext *cx, JSObject *obj);
-
-extern JSObject *
-js_BooleanToObject(JSContext *cx, JSBool b);
-
-extern JSString *
-js_BooleanToString(JSContext *cx, JSBool b);
-
-extern JSBool
-js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
-
-JS_END_EXTERN_C
-
-#endif /* jsbool_h___ */
diff --git a/src/extension/script/js/jsclist.h b/src/extension/script/js/jsclist.h
deleted file mode 100644
index 2eafe8e40..000000000
--- a/src/extension/script/js/jsclist.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsclist_h___
-#define jsclist_h___
-
-#include "jstypes.h"
-
-/*
-** Circular linked list
-*/
-typedef struct JSCListStr {
- struct JSCListStr *next;
- struct JSCListStr *prev;
-} JSCList;
-
-/*
-** Insert element "_e" into the list, before "_l".
-*/
-#define JS_INSERT_BEFORE(_e,_l) \
- JS_BEGIN_MACRO \
- (_e)->next = (_l); \
- (_e)->prev = (_l)->prev; \
- (_l)->prev->next = (_e); \
- (_l)->prev = (_e); \
- JS_END_MACRO
-
-/*
-** Insert element "_e" into the list, after "_l".
-*/
-#define JS_INSERT_AFTER(_e,_l) \
- JS_BEGIN_MACRO \
- (_e)->next = (_l)->next; \
- (_e)->prev = (_l); \
- (_l)->next->prev = (_e); \
- (_l)->next = (_e); \
- JS_END_MACRO
-
-/*
-** Return the element following element "_e"
-*/
-#define JS_NEXT_LINK(_e) \
- ((_e)->next)
-/*
-** Return the element preceding element "_e"
-*/
-#define JS_PREV_LINK(_e) \
- ((_e)->prev)
-
-/*
-** Append an element "_e" to the end of the list "_l"
-*/
-#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l)
-
-/*
-** Insert an element "_e" at the head of the list "_l"
-*/
-#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l)
-
-/* Return the head/tail of the list */
-#define JS_LIST_HEAD(_l) (_l)->next
-#define JS_LIST_TAIL(_l) (_l)->prev
-
-/*
-** Remove the element "_e" from it's circular list.
-*/
-#define JS_REMOVE_LINK(_e) \
- JS_BEGIN_MACRO \
- (_e)->prev->next = (_e)->next; \
- (_e)->next->prev = (_e)->prev; \
- JS_END_MACRO
-
-/*
-** Remove the element "_e" from it's circular list. Also initializes the
-** linkage.
-*/
-#define JS_REMOVE_AND_INIT_LINK(_e) \
- JS_BEGIN_MACRO \
- (_e)->prev->next = (_e)->next; \
- (_e)->next->prev = (_e)->prev; \
- (_e)->next = (_e); \
- (_e)->prev = (_e); \
- JS_END_MACRO
-
-/*
-** Return non-zero if the given circular list "_l" is empty, zero if the
-** circular list is not empty
-*/
-#define JS_CLIST_IS_EMPTY(_l) \
- ((_l)->next == (_l))
-
-/*
-** Initialize a circular list
-*/
-#define JS_INIT_CLIST(_l) \
- JS_BEGIN_MACRO \
- (_l)->next = (_l); \
- (_l)->prev = (_l); \
- JS_END_MACRO
-
-#define JS_INIT_STATIC_CLIST(_l) \
- {(_l), (_l)}
-
-#endif /* jsclist_h___ */
diff --git a/src/extension/script/js/jscntxt.c b/src/extension/script/js/jscntxt.c
deleted file mode 100644
index 85496b89b..000000000
--- a/src/extension/script/js/jscntxt.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS execution context.
- */
-#include "jsstddef.h"
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsclist.h"
-#include "jsprf.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsexn.h"
-#include "jsgc.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsscan.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-JSContext *
-js_NewContext(JSRuntime *rt, size_t stackChunkSize)
-{
- JSContext *cx;
- JSBool ok, first;
-
- cx = (JSContext *) malloc(sizeof *cx);
- if (!cx)
- return NULL;
- memset(cx, 0, sizeof *cx);
-
- cx->runtime = rt;
-#if JS_STACK_GROWTH_DIRECTION > 0
- cx->stackLimit = (jsuword)-1;
-#endif
-#ifdef JS_THREADSAFE
- js_InitContextForLocking(cx);
-#endif
-
- JS_LOCK_GC(rt);
- for (;;) {
- first = (rt->contextList.next == &rt->contextList);
- if (rt->state == JSRTS_UP) {
- JS_ASSERT(!first);
- break;
- }
- if (rt->state == JSRTS_DOWN) {
- JS_ASSERT(first);
- rt->state = JSRTS_LAUNCHING;
- break;
- }
- JS_WAIT_CONDVAR(rt->stateChange, JS_NO_TIMEOUT);
- }
- JS_APPEND_LINK(&cx->links, &rt->contextList);
- JS_UNLOCK_GC(rt);
-
- /*
- * First we do the infallible, every-time per-context initializations.
- * Should a later, fallible initialization (js_InitRegExpStatics, e.g.,
- * or the stuff under 'if (first)' below) fail, at least the version
- * and arena-pools will be valid and safe to use (say, from the last GC
- * done by js_DestroyContext).
- */
- cx->version = JSVERSION_DEFAULT;
- cx->jsop_eq = JSOP_EQ;
- cx->jsop_ne = JSOP_NE;
- JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval));
- JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
-
-#if JS_HAS_REGEXPS
- if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
- js_DestroyContext(cx, JS_NO_GC);
- return NULL;
- }
-#endif
-#if JS_HAS_EXCEPTIONS
- cx->throwing = JS_FALSE;
-#endif
-
- /*
- * If cx is the first context on this runtime, initialize well-known atoms,
- * keywords, numbers, and strings. If one of these steps should fail, the
- * runtime will be left in a partially initialized state, with zeroes and
- * nulls stored in the default-initialized remainder of the struct. We'll
- * clean the runtime up under js_DestroyContext, because cx will be "last"
- * as well as "first".
- */
- if (first) {
- ok = (rt->atomState.liveAtoms == 0)
- ? js_InitAtomState(cx, &rt->atomState)
- : js_InitPinnedAtoms(cx, &rt->atomState);
- if (ok)
- ok = js_InitScanner(cx);
- if (ok)
- ok = js_InitRuntimeNumberState(cx);
- if (ok)
- ok = js_InitRuntimeStringState(cx);
- if (!ok) {
- js_DestroyContext(cx, JS_NO_GC);
- return NULL;
- }
-
- JS_LOCK_GC(rt);
- rt->state = JSRTS_UP;
- JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
- JS_UNLOCK_GC(rt);
- }
-
- return cx;
-}
-
-void
-js_DestroyContext(JSContext *cx, JSGCMode gcmode)
-{
- JSRuntime *rt;
- JSBool last;
- JSArgumentFormatMap *map;
-
- rt = cx->runtime;
-
- /* Remove cx from context list first. */
- JS_LOCK_GC(rt);
- JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);
- JS_REMOVE_LINK(&cx->links);
- last = (rt->contextList.next == &rt->contextList);
- if (last)
- rt->state = JSRTS_LANDING;
- JS_UNLOCK_GC(rt);
-
- if (last) {
-#ifdef JS_THREADSAFE
- /*
- * If cx is not in a request already, begin one now so that we wait
- * for any racing GC started on a not-last context to finish, before
- * we plow ahead and unpin atoms. Note that even though we begin a
- * request here if necessary, we end all requests on cx below before
- * forcing a final GC. This lets any not-last context destruction
- * racing in another thread try to force or maybe run the GC, but by
- * that point, rt->state will not be JSRTS_UP, and that GC attempt
- * will return early.
- */
- if (cx->requestDepth == 0)
- JS_BeginRequest(cx);
-#endif
-
- /* Unpin all pinned atoms before final GC. */
- js_UnpinPinnedAtoms(&rt->atomState);
-
- /* Unlock and clear GC things held by runtime pointers. */
- js_FinishRuntimeNumberState(cx);
- js_FinishRuntimeStringState(cx);
-
- /* Clear debugging state to remove GC roots. */
- JS_ClearAllTraps(cx);
- JS_ClearAllWatchPoints(cx);
- }
-
-#if JS_HAS_REGEXPS
- /*
- * Remove more GC roots in regExpStatics, then collect garbage.
- * XXX anti-modularity alert: we rely on the call to js_RemoveRoot within
- * XXX this function call to wait for any racing GC to complete, in the
- * XXX case where JS_DestroyContext is called outside of a request on cx
- */
- js_FreeRegExpStatics(cx, &cx->regExpStatics);
-#endif
-
-#ifdef JS_THREADSAFE
- /*
- * Destroying a context implicitly calls JS_EndRequest(). Also, we must
- * end our request here in case we are "last" -- in that event, another
- * js_DestroyContext that was not last might be waiting in the GC for our
- * request to end. We'll let it run below, just before we do the truly
- * final GC and then free atom state.
- *
- * At this point, cx must be inaccessible to other threads. It's off the
- * rt->contextList, and it should not be reachable via any object private
- * data structure.
- */
- while (cx->requestDepth != 0)
- JS_EndRequest(cx);
-#endif
-
- if (last) {
- /* Always force, so we wait for any racing GC to finish. */
- js_ForceGC(cx, GC_LAST_CONTEXT);
-
- /* Iterate until no finalizer removes a GC root or lock. */
- while (rt->gcPoke)
- js_GC(cx, GC_LAST_CONTEXT);
-
- /* Try to free atom state, now that no unrooted scripts survive. */
- if (rt->atomState.liveAtoms == 0)
- js_FreeAtomState(cx, &rt->atomState);
-
- /* Take the runtime down, now that it has no contexts or atoms. */
- JS_LOCK_GC(rt);
- rt->state = JSRTS_DOWN;
- JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
- JS_UNLOCK_GC(rt);
- } else {
- if (gcmode == JS_FORCE_GC)
- js_ForceGC(cx, 0);
- else if (gcmode == JS_MAYBE_GC)
- JS_MaybeGC(cx);
- }
-
- /* Free the stuff hanging off of cx. */
- JS_FinishArenaPool(&cx->stackPool);
- JS_FinishArenaPool(&cx->tempPool);
- if (cx->lastMessage)
- free(cx->lastMessage);
-
- /* Remove any argument formatters. */
- map = cx->argumentFormatMap;
- while (map) {
- JSArgumentFormatMap *temp = map;
- map = map->next;
- JS_free(cx, temp);
- }
-
- /* Destroy the resolve recursion damper. */
- if (cx->resolvingTable) {
- JS_DHashTableDestroy(cx->resolvingTable);
- cx->resolvingTable = NULL;
- }
-
- /* Finally, free cx itself. */
- free(cx);
-}
-
-JSBool
-js_ValidContextPointer(JSRuntime *rt, JSContext *cx)
-{
- JSCList *cl;
-
- for (cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next) {
- if (cl == &cx->links)
- return JS_TRUE;
- }
- JS_RUNTIME_METER(rt, deadContexts);
- return JS_FALSE;
-}
-
-JSContext *
-js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp)
-{
- JSContext *cx = *iterp;
-
- if (unlocked)
- JS_LOCK_GC(rt);
- if (!cx)
- cx = (JSContext *)&rt->contextList;
- cx = (JSContext *)cx->links.next;
- if (&cx->links == &rt->contextList)
- cx = NULL;
- *iterp = cx;
- if (unlocked)
- JS_UNLOCK_GC(rt);
- return cx;
-}
-
-static void
-ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
-{
- /*
- * 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.
- */
- if (reportp && reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
- reportp->flags |= JSREPORT_EXCEPTION;
-
-#if JS_HAS_ERROR_EXCEPTIONS
- /*
- * Call the error reporter only if an exception wasn't raised.
- *
- * If an exception was raised, then we call the debugErrorHook
- * (if present) to give it a chance to see the error before it
- * propagates out of scope. This is needed for compatability
- * with the old scheme.
- */
- if (!js_ErrorToException(cx, message, reportp)) {
- js_ReportErrorAgain(cx, message, reportp);
- } else if (cx->runtime->debugErrorHook && cx->errorReporter) {
- JSDebugErrorHook hook = cx->runtime->debugErrorHook;
- /* test local in case debugErrorHook changed on another thread */
- if (hook)
- hook(cx, message, reportp, cx->runtime->debugErrorHookData);
- }
-#else
- js_ReportErrorAgain(cx, message, reportp);
-#endif
-}
-
-/*
- * We don't post an exception in this case, since doing so runs into
- * complications of pre-allocating an exception object which required
- * running the Exception class initializer early etc.
- * Instead we just invoke the errorReporter with an "Out Of Memory"
- * type message, and then hope the process ends swiftly.
- */
-void
-js_ReportOutOfMemory(JSContext *cx, JSErrorCallback callback)
-{
- JSStackFrame *fp;
- JSErrorReport report;
- JSErrorReporter onError = cx->errorReporter;
-
- /* Get the message for this error, but we won't expand any arguments. */
- const JSErrorFormatString *efs = callback(NULL, NULL, JSMSG_OUT_OF_MEMORY);
- const char *msg = efs ? efs->format : "Out of memory";
-
- /* Fill out the report, but don't do anything that requires allocation. */
- memset(&report, 0, sizeof (struct JSErrorReport));
- report.flags = JSREPORT_ERROR;
- report.errorNumber = JSMSG_OUT_OF_MEMORY;
-
- /*
- * Walk stack until we find a frame that is associated with some script
- * rather than a native frame.
- */
- for (fp = cx->fp; fp; fp = fp->down) {
- if (fp->script && fp->pc) {
- report.filename = fp->script->filename;
- report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
- break;
- }
- }
-
- /*
- * If debugErrorHook is present then we give it a chance to veto
- * sending the error on to the regular ErrorReporter.
- */
- if (onError) {
- JSDebugErrorHook hook = cx->runtime->debugErrorHook;
- if (hook &&
- !hook(cx, msg, &report, cx->runtime->debugErrorHookData)) {
- onError = NULL;
- }
- }
-
- if (onError)
- onError(cx, msg, &report);
-}
-
-JSBool
-js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
-{
- char *last;
- JSStackFrame *fp;
- JSErrorReport report;
- JSBool warning;
-
- if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
- return JS_TRUE;
-
- last = JS_vsmprintf(format, ap);
- if (!last)
- return JS_FALSE;
-
- memset(&report, 0, sizeof (struct JSErrorReport));
- report.flags = flags;
-
- /* Find the top-most active script frame, for best line number blame. */
- for (fp = cx->fp; fp; fp = fp->down) {
- if (fp->script && fp->pc) {
- report.filename = fp->script->filename;
- report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
- break;
- }
- }
-
- warning = JSREPORT_IS_WARNING(report.flags);
- if (warning && JS_HAS_WERROR_OPTION(cx)) {
- report.flags &= ~JSREPORT_WARNING;
- warning = JS_FALSE;
- }
-
- ReportError(cx, last, &report);
- free(last);
- return warning;
-}
-
-/*
- * The arguments from ap need to be packaged up into an array and stored
- * into the report struct.
- *
- * The format string addressed by the error number may contain operands
- * identified by the format {N}, where N is a decimal digit. Each of these
- * is to be replaced by the Nth argument from the va_list. The complete
- * message is placed into reportp->ucmessage converted to a JSString.
- *
- * Returns true if the expansion succeeds (can fail if out of memory).
- */
-JSBool
-js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
- void *userRef, const uintN errorNumber,
- char **messagep, JSErrorReport *reportp,
- JSBool *warningp, JSBool charArgs, va_list ap)
-{
- const JSErrorFormatString *efs;
- int i;
- int argCount;
-
- *warningp = JSREPORT_IS_WARNING(reportp->flags);
- if (*warningp && JS_HAS_WERROR_OPTION(cx)) {
- reportp->flags &= ~JSREPORT_WARNING;
- *warningp = JS_FALSE;
- }
-
- *messagep = NULL;
- if (callback) {
- efs = callback(userRef, NULL, errorNumber);
- if (efs) {
- size_t totalArgsLength = 0;
- size_t argLengths[10]; /* only {0} thru {9} supported */
- argCount = efs->argCount;
- JS_ASSERT(argCount <= 10);
- if (argCount > 0) {
- /*
- * Gather the arguments into an array, and accumulate
- * their sizes. We allocate 1 more than necessary and
- * null it out to act as the caboose when we free the
- * pointers later.
- */
- reportp->messageArgs = (const jschar **)
- JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
- if (!reportp->messageArgs)
- return JS_FALSE;
- reportp->messageArgs[argCount] = NULL;
- for (i = 0; i < argCount; i++) {
- if (charArgs) {
- char *charArg = va_arg(ap, char *);
- reportp->messageArgs[i]
- = js_InflateString(cx, charArg, strlen(charArg));
- if (!reportp->messageArgs[i])
- goto error;
- }
- else
- reportp->messageArgs[i] = va_arg(ap, jschar *);
- argLengths[i] = js_strlen(reportp->messageArgs[i]);
- totalArgsLength += argLengths[i];
- }
- /* NULL-terminate for easy copying. */
- reportp->messageArgs[i] = NULL;
- }
- /*
- * Parse the error format, substituting the argument X
- * for {X} in the format.
- */
- if (argCount > 0) {
- if (efs->format) {
- const char *fmt;
- const jschar *arg;
- jschar *out;
- int expandedArgs = 0;
- size_t expandedLength
- = strlen(efs->format)
- - (3 * argCount) /* exclude the {n} */
- + totalArgsLength;
- /*
- * Note - the above calculation assumes that each argument
- * is used once and only once in the expansion !!!
- */
- reportp->ucmessage = out = (jschar *)
- JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
- if (!out)
- goto error;
- fmt = efs->format;
- while (*fmt) {
- if (*fmt == '{') {
- if (isdigit(fmt[1])) {
- int d = JS7_UNDEC(fmt[1]);
- JS_ASSERT(expandedArgs < argCount);
- arg = reportp->messageArgs[d];
- js_strncpy(out, arg, argLengths[d]);
- out += argLengths[d];
- fmt += 3;
- expandedArgs++;
- continue;
- }
- }
- /*
- * is this kosher?
- */
- *out++ = (unsigned char)(*fmt++);
- }
- JS_ASSERT(expandedArgs == argCount);
- *out = 0;
- *messagep =
- js_DeflateString(cx, reportp->ucmessage,
- (size_t)(out - reportp->ucmessage));
- if (!*messagep)
- goto error;
- }
- } else {
- /*
- * Zero arguments: the format string (if it exists) is the
- * entire message.
- */
- if (efs->format) {
- *messagep = JS_strdup(cx, efs->format);
- if (!*messagep)
- goto error;
- reportp->ucmessage
- = js_InflateString(cx, *messagep, strlen(*messagep));
- if (!reportp->ucmessage)
- goto error;
- }
- }
- }
- }
- if (*messagep == NULL) {
- /* where's the right place for this ??? */
- const char *defaultErrorMessage
- = "No error message available for error number %d";
- size_t nbytes = strlen(defaultErrorMessage) + 16;
- *messagep = (char *)JS_malloc(cx, nbytes);
- if (!*messagep)
- goto error;
- JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
- }
- return JS_TRUE;
-
-error:
- if (reportp->messageArgs) {
- i = 0;
- while (reportp->messageArgs[i])
- JS_free(cx, (void *)reportp->messageArgs[i++]);
- JS_free(cx, (void *)reportp->messageArgs);
- reportp->messageArgs = NULL;
- }
- if (reportp->ucmessage) {
- JS_free(cx, (void *)reportp->ucmessage);
- reportp->ucmessage = NULL;
- }
- if (*messagep) {
- JS_free(cx, (void *)*messagep);
- *messagep = NULL;
- }
- return JS_FALSE;
-}
-
-JSBool
-js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
- void *userRef, const uintN errorNumber,
- JSBool charArgs, va_list ap)
-{
- JSStackFrame *fp;
- JSErrorReport report;
- char *message;
- JSBool warning;
-
- if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
- return JS_TRUE;
-
- memset(&report, 0, sizeof (struct JSErrorReport));
- report.flags = flags;
- report.errorNumber = errorNumber;
-
- /*
- * If we can't find out where the error was based on the current frame,
- * see if the next frame has a script/pc combo we can use.
- */
- for (fp = cx->fp; fp; fp = fp->down) {
- if (fp->script && fp->pc) {
- report.filename = fp->script->filename;
- report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
- break;
- }
- }
-
- if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
- &message, &report, &warning, charArgs, ap)) {
- return JS_FALSE;
- }
-
- ReportError(cx, message, &report);
-
- if (message)
- JS_free(cx, message);
- if (report.messageArgs) {
- int i = 0;
- while (report.messageArgs[i])
- JS_free(cx, (void *)report.messageArgs[i++]);
- JS_free(cx, (void *)report.messageArgs);
- }
- if (report.ucmessage)
- JS_free(cx, (void *)report.ucmessage);
-
- return warning;
-}
-
-JS_FRIEND_API(void)
-js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
-{
- JSErrorReporter onError;
-
- if (!message)
- return;
-
- if (cx->lastMessage)
- free(cx->lastMessage);
- cx->lastMessage = JS_strdup(cx, message);
- if (!cx->lastMessage)
- return;
- onError = cx->errorReporter;
-
- /*
- * If debugErrorHook is present then we give it a chance to veto
- * sending the error on to the regular ErrorReporter.
- */
- if (onError) {
- JSDebugErrorHook hook = cx->runtime->debugErrorHook;
- if (hook &&
- !hook(cx, cx->lastMessage, reportp,
- cx->runtime->debugErrorHookData)) {
- onError = NULL;
- }
- }
- if (onError)
- onError(cx, cx->lastMessage, reportp);
-}
-
-void
-js_ReportIsNotDefined(JSContext *cx, const char *name)
-{
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name);
-}
-
-#if defined DEBUG && defined XP_UNIX
-/* For gdb usage. */
-void js_traceon(JSContext *cx) { cx->tracefp = stderr; }
-void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
-#endif
-
-JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
-#if JS_HAS_DFLT_MSG_STRINGS
-#define MSG_DEF(name, number, count, exception, format) \
- { format, count } ,
-#else
-#define MSG_DEF(name, number, count, exception, format) \
- { NULL, count } ,
-#endif
-#include "js.msg"
-#undef MSG_DEF
-};
-
-const JSErrorFormatString *
-js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
-{
- if ((errorNumber > 0) && (errorNumber < JSErr_Limit))
- return &js_ErrorFormatString[errorNumber];
- return NULL;
-}
diff --git a/src/extension/script/js/jscntxt.h b/src/extension/script/js/jscntxt.h
deleted file mode 100644
index f9aab41a8..000000000
--- a/src/extension/script/js/jscntxt.h
+++ /dev/null
@@ -1,496 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jscntxt_h___
-#define jscntxt_h___
-/*
- * JS execution context.
- */
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsclist.h"
-#include "jslong.h"
-#include "jsatom.h"
-#include "jsconfig.h"
-#include "jsdhash.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jsobj.h"
-#include "jsprvtd.h"
-#include "jspubtd.h"
-#include "jsregexp.h"
-
-JS_BEGIN_EXTERN_C
-
-typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
-
-typedef enum JSRuntimeState {
- JSRTS_DOWN,
- JSRTS_LAUNCHING,
- JSRTS_UP,
- JSRTS_LANDING
-} JSRuntimeState;
-
-typedef struct JSPropertyTreeEntry {
- JSDHashEntryHdr hdr;
- JSScopeProperty *child;
-} JSPropertyTreeEntry;
-
-struct JSRuntime {
- /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
- JSRuntimeState state;
-
- /* Garbage collector state, used by jsgc.c. */
- JSArenaPool gcArenaPool;
- JSDHashTable gcRootsHash;
- JSDHashTable *gcLocksHash;
- JSGCThing *gcFreeList;
- jsrefcount gcKeepAtoms;
- uint32 gcBytes;
- uint32 gcLastBytes;
- uint32 gcMaxBytes;
- uint32 gcLevel;
- uint32 gcNumber;
- JSPackedBool gcPoke;
- JSPackedBool gcRunning;
- JSGCCallback gcCallback;
- uint32 gcMallocBytes;
-#ifdef JS_GCMETER
- JSGCStats gcStats;
-#endif
-
- /* Literal table maintained by jsatom.c functions. */
- JSAtomState atomState;
-
- /* Random number generator state, used by jsmath.c. */
- JSBool rngInitialized;
- int64 rngMultiplier;
- int64 rngAddend;
- int64 rngMask;
- int64 rngSeed;
- jsdouble rngDscale;
-
- /* Well-known numbers held for use by this runtime's contexts. */
- jsdouble *jsNaN;
- jsdouble *jsNegativeInfinity;
- jsdouble *jsPositiveInfinity;
-
- /* Empty string held for use by this runtime's contexts. */
- JSString *emptyString;
-
- /* List of active contexts sharing this runtime; protected by gcLock. */
- JSCList contextList;
-
- /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
- JSTrapHandler interruptHandler;
- void *interruptHandlerData;
- JSNewScriptHook newScriptHook;
- void *newScriptHookData;
- JSDestroyScriptHook destroyScriptHook;
- void *destroyScriptHookData;
- JSTrapHandler debuggerHandler;
- void *debuggerHandlerData;
- JSSourceHandler sourceHandler;
- void *sourceHandlerData;
- JSInterpreterHook executeHook;
- void *executeHookData;
- JSInterpreterHook callHook;
- void *callHookData;
- JSObjectHook objectHook;
- void *objectHookData;
- JSTrapHandler throwHook;
- void *throwHookData;
- JSDebugErrorHook debugErrorHook;
- void *debugErrorHookData;
-
- /* More debugging state, see jsdbgapi.c. */
- JSCList trapList;
- JSCList watchPointList;
-
- /* Weak links to properties, indexed by quickened get/set opcodes. */
- /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
- JSPropertyCache propertyCache;
-
- /* Client opaque pointer */
- void *data;
-
-#ifdef JS_THREADSAFE
- /* These combine to interlock the GC and new requests. */
- PRLock *gcLock;
- PRCondVar *gcDone;
- PRCondVar *requestDone;
- uint32 requestCount;
- jsword gcThread;
-
- /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
- PRLock *rtLock;
-#ifdef DEBUG
- jsword rtLockOwner;
-#endif
-
- /* Used to synchronize down/up state change; protected by gcLock. */
- PRCondVar *stateChange;
-
- /* Used to serialize cycle checks when setting __proto__ or __parent__. */
- PRLock *setSlotLock;
- PRCondVar *setSlotDone;
- JSBool setSlotBusy;
- JSScope *setSlotScope; /* deadlock avoidance, see jslock.c */
-
- /*
- * State for sharing single-threaded scopes, once a second thread tries to
- * lock a scope. The scopeSharingDone condvar is protected by rt->gcLock,
- * to minimize number of locks taken in JS_EndRequest.
- *
- * The scopeSharingTodo linked list is likewise "global" per runtime, not
- * one-list-per-context, to conserve space over all contexts, optimizing
- * for the likely case that scopes become shared rarely, and among a very
- * small set of threads (contexts).
- */
- PRCondVar *scopeSharingDone;
- JSScope *scopeSharingTodo;
-
-/*
- * Magic terminator for the rt->scopeSharingTodo linked list, threaded through
- * scope->u.link. This hack allows us to test whether a scope is on the list
- * by asking whether scope->u.link is non-null. We use a large, likely bogus
- * pointer here to distinguish this value from any valid u.count (small int)
- * value.
- */
-#define NO_SCOPE_SHARING_TODO ((JSScope *) 0xfeedbeef)
-#endif /* JS_THREADSAFE */
-
- /*
- * Check property accessibility for objects of arbitrary class. Used at
- * present to check f.caller accessibility for any function object f.
- */
- JSCheckAccessOp checkObjectAccess;
-
- /* Security principals serialization support. */
- JSPrincipalsTranscoder principalsTranscoder;
-
- /* Shared scope property tree, and allocator for its nodes. */
- JSDHashTable propertyTreeHash;
- JSScopeProperty *propertyFreeList;
- JSArenaPool propertyArenaPool;
-
-#ifdef DEBUG
- /* Function invocation metering. */
- jsrefcount inlineCalls;
- jsrefcount nativeCalls;
- jsrefcount nonInlineCalls;
- jsrefcount constructs;
-
- /* Scope lock and property metering. */
- jsrefcount claimAttempts;
- jsrefcount claimedScopes;
- jsrefcount deadContexts;
- jsrefcount deadlocksAvoided;
- jsrefcount liveScopes;
- jsrefcount sharedScopes;
- jsrefcount totalScopes;
- jsrefcount badUndependStrings;
- jsrefcount liveScopeProps;
- jsrefcount totalScopeProps;
- jsrefcount livePropTreeNodes;
- jsrefcount duplicatePropTreeNodes;
- jsrefcount totalPropTreeNodes;
- jsrefcount propTreeKidsChunks;
- jsrefcount middleDeleteFixups;
-
- /* String instrumentation. */
- jsrefcount liveStrings;
- jsrefcount totalStrings;
- jsrefcount liveDependentStrings;
- jsrefcount totalDependentStrings;
- double lengthSum;
- double lengthSquaredSum;
- double strdepLengthSum;
- double strdepLengthSquaredSum;
-#endif
-};
-
-#ifdef DEBUG
-# define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which)
-# define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which)
-#else
-# define JS_RUNTIME_METER(rt, which) /* nothing */
-# define JS_RUNTIME_UNMETER(rt, which) /* nothing */
-#endif
-
-#define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
-#define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
-
-#ifdef JS_ARGUMENT_FORMATTER_DEFINED
-/*
- * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
- * formatter functions. Elements are sorted in non-increasing format string
- * length order.
- */
-struct JSArgumentFormatMap {
- const char *format;
- size_t length;
- JSArgumentFormatter formatter;
- JSArgumentFormatMap *next;
-};
-#endif
-
-struct JSStackHeader {
- uintN nslots;
- JSStackHeader *down;
-};
-
-#define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2)
-
-/*
- * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
- * here because all consumers need to see these declarations (and not just the
- * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
- * declaration), along with cx->resolvingTable.
- */
-typedef struct JSResolvingKey {
- JSObject *obj;
- jsid id;
-} JSResolvingKey;
-
-typedef struct JSResolvingEntry {
- JSDHashEntryHdr hdr;
- JSResolvingKey key;
- uint32 flags;
-} JSResolvingEntry;
-
-#define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */
-#define JSRESFLAG_WATCH 0x2 /* resolving id from watch */
-
-struct JSContext {
- JSCList links;
-
- /* Interpreter activation count. */
- uintN interpLevel;
-
- /* Limit pointer for checking stack consumption during recursion. */
- jsuword stackLimit;
-
- /* Runtime version control identifier and equality operators. */
- JSVersion version;
- jsbytecode jsop_eq;
- jsbytecode jsop_ne;
-
- /* Data shared by threads in an address space. */
- JSRuntime *runtime;
-
- /* Stack arena pool and frame pointer register. */
- JSArenaPool stackPool;
- JSStackFrame *fp;
-
- /* Temporary arena pool used while compiling and decompiling. */
- JSArenaPool tempPool;
-
- /* Top-level object and pointer to top stack frame's scope chain. */
- JSObject *globalObject;
-
- /* Most recently created things by type, members of the GC's root set. */
- JSGCThing *newborn[GCX_NTYPES];
-
- /* Atom root for the last-looked-up atom on this context. */
- JSAtom *lastAtom;
-
- /* Regular expression class statics (XXX not shared globally). */
- JSRegExpStatics regExpStatics;
-
- /* State for object and array toSource conversion. */
- JSSharpObjectMap sharpObjectMap;
-
- /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
- JSArgumentFormatMap *argumentFormatMap;
-
- /* Last message string and trace file for debugging. */
- char *lastMessage;
-#ifdef DEBUG
- void *tracefp;
-#endif
-
- /* Per-context optional user callbacks. */
- JSBranchCallback branchCallback;
- JSErrorReporter errorReporter;
-
- /* Client opaque pointer */
- void *data;
-
- /* GC and thread-safe state. */
- JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */
-#ifdef JS_THREADSAFE
- jsword thread;
- jsrefcount requestDepth;
- JSScope *scopeToShare; /* weak reference, see jslock.c */
- JSScope *lockedSealedScope; /* weak ref, for low-cost sealed
- scope locking */
-#endif
-
-#if JS_HAS_LVALUE_RETURN
- /*
- * Secondary return value from native method called on the left-hand side
- * of an assignment operator. The native should store the object in which
- * to set a property in *rval, and return the property's id expressed as a
- * jsval by calling JS_SetCallReturnValue2(cx, idval).
- */
- jsval rval2;
- JSPackedBool rval2set;
-#endif
-
- /*
- * True if creating an exception object, to prevent runaway recursion.
- * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN,
- * and with throwing, below.
- */
- JSPackedBool creatingException;
-
- /*
- * Exception state -- the exception member is a GC root by definition.
- * NB: throwing packs with creatingException and rval2set, above.
- */
- JSPackedBool throwing; /* is there a pending exception? */
- jsval exception; /* most-recently-thrown exception */
-
- /* Per-context options. */
- uint32 options; /* see jsapi.h for JSOPTION_* */
-
- /* Locale specific callbacks for string conversion. */
- JSLocaleCallbacks *localeCallbacks;
-
- /*
- * cx->resolvingTable is non-null and non-empty if we are initializing
- * standard classes lazily, or if we are otherwise recursing indirectly
- * from js_LookupProperty through a JSClass.resolve hook. It is used to
- * limit runaway recursion (see jsapi.c and jsobj.c).
- */
- JSDHashTable *resolvingTable;
-
- /* PDL of stack headers describing stack slots not rooted by argv, etc. */
- JSStackHeader *stackHeaders;
-
- /* Optional hook to find principals for an object being accessed on cx. */
- JSObjectPrincipalsFinder findObjectPrincipals;
-};
-
-/* Slightly more readable macros, also to hide bitset implementation detail. */
-#define JS_HAS_STRICT_OPTION(cx) ((cx)->options & JSOPTION_STRICT)
-#define JS_HAS_WERROR_OPTION(cx) ((cx)->options & JSOPTION_WERROR)
-
-extern JSContext *
-js_NewContext(JSRuntime *rt, size_t stackChunkSize);
-
-extern void
-js_DestroyContext(JSContext *cx, JSGCMode gcmode);
-
-/*
- * Return true if cx points to a context in rt->contextList, else return false.
- * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock.
- */
-extern JSBool
-js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
-
-/*
- * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
- * the caller must be holding rt->gcLock.
- */
-extern JSContext *
-js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
-
-/*
- * Report an exception, which is currently realized as a printf-style format
- * string and its arguments.
- */
-typedef enum JSErrNum {
-#define MSG_DEF(name, number, count, exception, format) \
- name = number,
-#include "js.msg"
-#undef MSG_DEF
- JSErr_Limit
-} JSErrNum;
-
-extern const JSErrorFormatString *
-js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
-
-#ifdef va_start
-extern JSBool
-js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
-
-extern JSBool
-js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
- void *userRef, const uintN errorNumber,
- JSBool charArgs, va_list ap);
-
-extern JSBool
-js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
- void *userRef, const uintN errorNumber,
- char **message, JSErrorReport *reportp,
- JSBool *warningp, JSBool charArgs, va_list ap);
-#endif
-
-extern void
-js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback);
-
-/*
- * Report an exception using a previously composed JSErrorReport.
- * XXXbe remove from "friend" API
- */
-extern JS_FRIEND_API(void)
-js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
-
-extern void
-js_ReportIsNotDefined(JSContext *cx, const char *name);
-
-extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
-
-/*
- * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
- * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
- * computed on the build host by jscpucfg.c and written into jsautocfg.h. The
- * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
- * reasons pre-dating autoconf usage).
- */
-#if JS_STACK_GROWTH_DIRECTION > 0
-# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit)
-#else
-# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit)
-#endif
-
-JS_END_EXTERN_C
-
-#endif /* jscntxt_h___ */
diff --git a/src/extension/script/js/jscompat.h b/src/extension/script/js/jscompat.h
deleted file mode 100644
index 6ba036a5e..000000000
--- a/src/extension/script/js/jscompat.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998-1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* -*- Mode: C; tab-width: 8 -*-
- * Copyright © 1996-1999 Netscape Communications Corporation, All Rights Reserved.
- */
-#ifndef jscompat_h___
-#define jscompat_h___
-/*
- * Compatibility glue for various NSPR versions. We must always define int8,
- * int16, jsword, and so on to minimize differences with js/ref, no matter what
- * the NSPR typedef names may be.
- */
-#include "jstypes.h"
-#include "jslong.h"
-
-typedef JSIntn intN;
-typedef JSUintn uintN;
-typedef JSUword jsuword;
-typedef JSWord jsword;
-typedef float float32;
-#define allocPriv allocPool
-#endif /* jscompat_h___ */
diff --git a/src/extension/script/js/jsconfig.h b/src/extension/script/js/jsconfig.h
deleted file mode 100644
index fae86d3a7..000000000
--- a/src/extension/script/js/jsconfig.h
+++ /dev/null
@@ -1,489 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS configuration macros.
- */
-#ifndef JS_VERSION
-#define JS_VERSION 150
-#endif
-
-/*
- * Compile-time JS version configuration. The JS version numbers lie on the
- * number line like so:
- *
- * 1.0 1.1 1.2 1.3 1.4 ECMAv3 1.5
- * ^ ^
- * | |
- * basis for ECMAv1 close to ECMAv2
- *
- * where ECMAv3 stands for ECMA-262 Edition 3. See the runtime version enum
- * JSVersion in jspubtd.h. Code in the engine can therefore count on version
- * <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and version
- * > JSVERSION_1_4 to mean "at or after the Third Edition".
- *
- * In the unlikely event that SpiderMonkey ever implements JavaScript 2.0, or
- * ECMA-262 Edition 4 (JS2 without certain extensions), the version number to
- * use would be near 200, or greater.
- *
- * The JS_VERSION_ECMA_3 version is the minimal configuration conforming to
- * the ECMA-262 Edition 3 specification. Use it for minimal embeddings, where
- * you're sure you don't need any of the extensions disabled in this version.
- * In order to facilitate testing, JS_HAS_OBJ_PROTO_PROP is defined as part of
- * the JS_VERSION_ECMA_3_TEST version.
- */
-#define JS_VERSION_ECMA_3 148
-#define JS_VERSION_ECMA_3_TEST 149
-
-#if JS_VERSION == JS_VERSION_ECMA_3 || \
- JS_VERSION == JS_VERSION_ECMA_3_TEST
-
-#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_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 0 /* with(o)function f(){} sets o.f */
-
-#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, array.pop, etc */
-#define JS_HAS_STR_HTML_HELPERS 0 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */
-#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 fun.apply(obj, argArray) */
-#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */
-#if JS_VERSION == JS_VERSION_ECMA_3_TEST
-#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */
-#else
-#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */
-#endif
-#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 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 1 /* has === and !== identity eqops */
-#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */
-#define JS_HAS_REPLACE_LAMBDA 1 /* 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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 1 /* has exception handling */
-#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 0 /* 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 0 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 1 /* has error object hierarchy */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 1 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 1 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 100
-
-#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_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_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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */
-#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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
-#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 110
-
-#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_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_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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */
-#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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
-#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 120
-
-#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_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_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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */
-#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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
-#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 130
-
-#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_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_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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */
-#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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
-#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 140
-
-#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_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_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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */
-#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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 1 /* has exception handling */
-#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 0 /* rt errors reflected as exceptions */
-#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */
-#define JS_HAS_CONST 0 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
-
-#elif JS_VERSION == 150
-
-#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_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 0 /* with(o)function f(){} sets o.f */
-
-#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_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */
-#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */
-#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 0 /* 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 internal support */
-#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */
-#define JS_HAS_EXCEPTIONS 1 /* has exception handling */
-#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
-#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
-#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */
-#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */
-#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */
-#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */
-#define JS_HAS_ERROR_EXCEPTIONS 1 /* rt errors reflected as exceptions */
-#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */
-#define JS_HAS_NEW_OBJ_METHODS 1 /* has Object.prototype query methods */
-#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */
-#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
-#define JS_HAS_NUMBER_FORMATS 1 /* numbers have formatting methods */
-#define JS_HAS_GETTER_SETTER 1 /* has JS2 getter/setter functions */
-#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */
-#define JS_HAS_CONST 1 /* has JS2 const as alternative var */
-#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */
-#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native item */
-#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */
-
-#else
-
-#error "unknown JS_VERSION"
-
-#endif
diff --git a/src/extension/script/js/jscpucfg.c b/src/extension/script/js/jscpucfg.c
deleted file mode 100644
index aa6c04c4d..000000000
--- a/src/extension/script/js/jscpucfg.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * Generate CPU-specific bit-size and similar #defines.
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef CROSS_COMPILE
-#include <prtypes.h>
-#define INT64 PRInt64
-#else
-
-#ifdef __MWERKS__
-#define XP_MAC 1
-#endif
-
-/************************************************************************/
-
-/* Generate cpucfg.h */
-#ifdef XP_MAC
-#include <Types.h>
-#define INT64 UnsignedWide
-#else
-#if defined(XP_WIN) || defined(XP_OS2)
-#ifdef WIN32
-#if defined(__GNUC__)
-#define INT64 long long
-#else
-#define INT64 _int64
-#endif /* __GNUC__ */
-#else
-#define INT64 long
-#endif
-#else
-#if defined(HPUX) || defined(__QNX__) || defined(_SCO_DS) || defined(UNIXWARE)
-#define INT64 long
-#else
-#define INT64 long long
-#endif
-#endif
-#endif
-
-#endif /* CROSS_COMPILE */
-
-typedef void *prword;
-
-struct align_short {
- char c;
- short a;
-};
-struct align_int {
- char c;
- int a;
-};
-struct align_long {
- char c;
- long a;
-};
-struct align_int64 {
- char c;
- INT64 a;
-};
-struct align_fakelonglong {
- char c;
- struct {
- long hi, lo;
- } a;
-};
-struct align_float {
- char c;
- float a;
-};
-struct align_double {
- char c;
- double a;
-};
-struct align_pointer {
- char c;
- void *a;
-};
-struct align_prword {
- char c;
- prword a;
-};
-
-#define ALIGN_OF(type) \
- (((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
-
-unsigned int bpb;
-
-static int Log2(unsigned int n)
-{
- int log2 = 0;
-
- if (n & (n-1))
- log2++;
- if (n >> 16)
- log2 += 16, n >>= 16;
- if (n >> 8)
- log2 += 8, n >>= 8;
- if (n >> 4)
- log2 += 4, n >>= 4;
- if (n >> 2)
- log2 += 2, n >>= 2;
- if (n >> 1)
- log2++;
- return log2;
-}
-
-/*
- * Conceivably this could actually be used, but there is lots of code out
- * there with ands and shifts in it that assumes a byte is exactly 8 bits,
- * so forget about porting THIS code to all those non 8 bit byte machines.
- */
-static void BitsPerByte(void)
-{
- bpb = 8;
-}
-
-static int StackGrowthDirection(int *dummy1addr)
-{
- int dummy2;
-
- return (&dummy2 < dummy1addr) ? -1 : 1;
-}
-
-int main(int argc, char **argv)
-{
- int sizeof_char, sizeof_short, sizeof_int, sizeof_int64, sizeof_long,
- sizeof_float, sizeof_double, sizeof_word, sizeof_dword;
- int bits_per_int64_log2, align_of_short, align_of_int, align_of_long,
- align_of_int64, align_of_float, align_of_double, align_of_pointer,
- align_of_word;
- int dummy1;
-
- BitsPerByte();
-
- printf("#ifndef js_cpucfg___\n");
- printf("#define js_cpucfg___\n\n");
-
- printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
-
-#ifdef CROSS_COMPILE
-#if defined(IS_LITTLE_ENDIAN)
- printf("#define IS_LITTLE_ENDIAN 1\n");
- printf("#undef IS_BIG_ENDIAN\n\n");
-#elif defined(IS_BIG_ENDIAN)
- printf("#undef IS_LITTLE_ENDIAN\n");
- printf("#define IS_BIG_ENDIAN 1\n\n");
-#else
-#error "Endianess not defined."
-#endif
-
- sizeof_char = PR_BYTES_PER_BYTE;
- sizeof_short = PR_BYTES_PER_SHORT;
- sizeof_int = PR_BYTES_PER_INT;
- sizeof_int64 = PR_BYTES_PER_INT64;
- sizeof_long = PR_BYTES_PER_LONG;
- sizeof_float = PR_BYTES_PER_FLOAT;
- sizeof_double = PR_BYTES_PER_DOUBLE;
- sizeof_word = PR_BYTES_PER_WORD;
- sizeof_dword = PR_BYTES_PER_DWORD;
-
- bits_per_int64_log2 = PR_BITS_PER_INT64_LOG2;
-
- align_of_short = PR_ALIGN_OF_SHORT;
- align_of_int = PR_ALIGN_OF_INT;
- align_of_long = PR_ALIGN_OF_LONG;
- align_of_int64 = PR_ALIGN_OF_INT64;
- align_of_float = PR_ALIGN_OF_FLOAT;
- align_of_double = PR_ALIGN_OF_DOUBLE;
- align_of_pointer = PR_ALIGN_OF_POINTER;
- align_of_word = PR_ALIGN_OF_WORD;
-
-#else /* !CROSS_COMPILE */
-
- /*
- * We don't handle PDP-endian or similar orders: if a short is big-endian,
- * so must int and long be big-endian for us to generate the IS_BIG_ENDIAN
- * #define and the IS_LITTLE_ENDIAN #undef.
- */
- {
- int big_endian = 0, little_endian = 0, ntests = 0;
-
- if (sizeof(short) == 2) {
- /* force |volatile| here to get rid of any compiler optimisations
- * (var in register etc.) which may be appiled to |auto| vars -
- * even those in |union|s...
- * (|static| is used to get the same functionality for compilers
- * which do not honor |volatile|...).
- */
- volatile static union {
- short i;
- char c[2];
- } u;
-
- u.i = 0x0102;
- big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02);
- little_endian += (u.c[0] == 0x02 && u.c[1] == 0x01);
- ntests++;
- }
-
- if (sizeof(int) == 4) {
- /* force |volatile| here ... */
- volatile static union {
- int i;
- char c[4];
- } u;
-
- u.i = 0x01020304;
- big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
- u.c[2] == 0x03 && u.c[3] == 0x04);
- little_endian += (u.c[0] == 0x04 && u.c[1] == 0x03 &&
- u.c[2] == 0x02 && u.c[3] == 0x01);
- ntests++;
- }
-
- if (sizeof(long) == 8) {
- /* force |volatile| here ... */
- volatile static union {
- long i;
- char c[8];
- } u;
-
- /*
- * Write this as portably as possible: avoid 0x0102030405060708L
- * and <<= 32.
- */
- u.i = 0x01020304;
- u.i <<= 16, u.i <<= 16;
- u.i |= 0x05060708;
- big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
- u.c[2] == 0x03 && u.c[3] == 0x04 &&
- u.c[4] == 0x05 && u.c[5] == 0x06 &&
- u.c[6] == 0x07 && u.c[7] == 0x08);
- little_endian += (u.c[0] == 0x08 && u.c[1] == 0x07 &&
- u.c[2] == 0x06 && u.c[3] == 0x05 &&
- u.c[4] == 0x04 && u.c[5] == 0x03 &&
- u.c[6] == 0x02 && u.c[7] == 0x01);
- ntests++;
- }
-
- if (big_endian && big_endian == ntests) {
- printf("#undef IS_LITTLE_ENDIAN\n");
- printf("#define IS_BIG_ENDIAN 1\n\n");
- } else if (little_endian && little_endian == ntests) {
- printf("#define IS_LITTLE_ENDIAN 1\n");
- printf("#undef IS_BIG_ENDIAN\n\n");
- } else {
- fprintf(stderr, "%s: unknown byte order"
- "(big_endian=%d, little_endian=%d, ntests=%d)!\n",
- argv[0], big_endian, little_endian, ntests);
- return EXIT_FAILURE;
- }
- }
-
- sizeof_char = sizeof(char);
- sizeof_short = sizeof(short);
- sizeof_int = sizeof(int);
- sizeof_int64 = 8;
- sizeof_long = sizeof(long);
- sizeof_float = sizeof(float);
- sizeof_double = sizeof(double);
- sizeof_word = sizeof(prword);
- sizeof_dword = 8;
-
- bits_per_int64_log2 = 6;
-
- align_of_short = ALIGN_OF(short);
- align_of_int = ALIGN_OF(int);
- align_of_long = ALIGN_OF(long);
- if (sizeof(INT64) < 8) {
- /* this machine doesn't actually support int64's */
- align_of_int64 = ALIGN_OF(fakelonglong);
- } else {
- align_of_int64 = ALIGN_OF(int64);
- }
- align_of_float = ALIGN_OF(float);
- align_of_double = ALIGN_OF(double);
- align_of_pointer = ALIGN_OF(pointer);
- align_of_word = ALIGN_OF(prword);
-
-#endif /* CROSS_COMPILE */
-
- printf("#define JS_BYTES_PER_BYTE %dL\n", sizeof_char);
- printf("#define JS_BYTES_PER_SHORT %dL\n", sizeof_short);
- printf("#define JS_BYTES_PER_INT %dL\n", sizeof_int);
- printf("#define JS_BYTES_PER_INT64 %dL\n", sizeof_int64);
- printf("#define JS_BYTES_PER_LONG %dL\n", sizeof_long);
- printf("#define JS_BYTES_PER_FLOAT %dL\n", sizeof_float);
- printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof_double);
- printf("#define JS_BYTES_PER_WORD %dL\n", sizeof_word);
- printf("#define JS_BYTES_PER_DWORD %dL\n", sizeof_dword);
- printf("\n");
-
- printf("#define JS_BITS_PER_BYTE %dL\n", bpb);
- printf("#define JS_BITS_PER_SHORT %dL\n", bpb * sizeof_short);
- printf("#define JS_BITS_PER_INT %dL\n", bpb * sizeof_int);
- printf("#define JS_BITS_PER_INT64 %dL\n", bpb * sizeof_int64);
- printf("#define JS_BITS_PER_LONG %dL\n", bpb * sizeof_long);
- printf("#define JS_BITS_PER_FLOAT %dL\n", bpb * sizeof_float);
- printf("#define JS_BITS_PER_DOUBLE %dL\n", bpb * sizeof_double);
- printf("#define JS_BITS_PER_WORD %dL\n", bpb * sizeof_word);
- printf("\n");
-
- printf("#define JS_BITS_PER_BYTE_LOG2 %dL\n", Log2(bpb));
- printf("#define JS_BITS_PER_SHORT_LOG2 %dL\n", Log2(bpb * sizeof_short));
- printf("#define JS_BITS_PER_INT_LOG2 %dL\n", Log2(bpb * sizeof_int));
- printf("#define JS_BITS_PER_INT64_LOG2 %dL\n", bits_per_int64_log2);
- printf("#define JS_BITS_PER_LONG_LOG2 %dL\n", Log2(bpb * sizeof_long));
- printf("#define JS_BITS_PER_FLOAT_LOG2 %dL\n", Log2(bpb * sizeof_float));
- printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof_double));
- printf("#define JS_BITS_PER_WORD_LOG2 %dL\n", Log2(bpb * sizeof_word));
- printf("\n");
-
- printf("#define JS_ALIGN_OF_SHORT %dL\n", align_of_short);
- printf("#define JS_ALIGN_OF_INT %dL\n", align_of_int);
- printf("#define JS_ALIGN_OF_LONG %dL\n", align_of_long);
- printf("#define JS_ALIGN_OF_INT64 %dL\n", align_of_int64);
- printf("#define JS_ALIGN_OF_FLOAT %dL\n", align_of_float);
- printf("#define JS_ALIGN_OF_DOUBLE %dL\n", align_of_double);
- printf("#define JS_ALIGN_OF_POINTER %dL\n", align_of_pointer);
- printf("#define JS_ALIGN_OF_WORD %dL\n", align_of_word);
- printf("\n");
-
- printf("#define JS_BYTES_PER_WORD_LOG2 %dL\n", Log2(sizeof_word));
- printf("#define JS_BYTES_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword));
- printf("#define JS_WORDS_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword/sizeof_word));
- printf("\n");
-
- printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1));
- printf("\n");
-
- printf("#endif /* js_cpucfg___ */\n");
-
- return EXIT_SUCCESS;
-}
-
diff --git a/src/extension/script/js/jscpucfg.h b/src/extension/script/js/jscpucfg.h
deleted file mode 100644
index e93f5531d..000000000
--- a/src/extension/script/js/jscpucfg.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef js_cpucfg___
-#define js_cpucfg___
-
-#include "jsosdep.h"
-
-#ifdef XP_MAC
-#undef IS_LITTLE_ENDIAN
-#define IS_BIG_ENDIAN 1
-
-#define JS_BYTES_PER_BYTE 1L
-#define JS_BYTES_PER_SHORT 2L
-#define JS_BYTES_PER_INT 4L
-#define JS_BYTES_PER_INT64 8L
-#define JS_BYTES_PER_LONG 4L
-#define JS_BYTES_PER_FLOAT 4L
-#define JS_BYTES_PER_DOUBLE 8L
-#define JS_BYTES_PER_WORD 4L
-#define JS_BYTES_PER_DWORD 8L
-
-#define JS_BITS_PER_BYTE 8L
-#define JS_BITS_PER_SHORT 16L
-#define JS_BITS_PER_INT 32L
-#define JS_BITS_PER_INT64 64L
-#define JS_BITS_PER_LONG 32L
-#define JS_BITS_PER_FLOAT 32L
-#define JS_BITS_PER_DOUBLE 64L
-#define JS_BITS_PER_WORD 32L
-
-#define JS_BITS_PER_BYTE_LOG2 3L
-#define JS_BITS_PER_SHORT_LOG2 4L
-#define JS_BITS_PER_INT_LOG2 5L
-#define JS_BITS_PER_INT64_LOG2 6L
-#define JS_BITS_PER_LONG_LOG2 5L
-#define JS_BITS_PER_FLOAT_LOG2 5L
-#define JS_BITS_PER_DOUBLE_LOG2 6L
-#define JS_BITS_PER_WORD_LOG2 5L
-
-#define JS_ALIGN_OF_SHORT 2L
-#define JS_ALIGN_OF_INT 4L
-#define JS_ALIGN_OF_LONG 4L
-#define JS_ALIGN_OF_INT64 2L
-#define JS_ALIGN_OF_FLOAT 4L
-#define JS_ALIGN_OF_DOUBLE 4L
-#define JS_ALIGN_OF_POINTER 4L
-#define JS_ALIGN_OF_WORD 4L
-
-#define JS_BYTES_PER_WORD_LOG2 2L
-#define JS_BYTES_PER_DWORD_LOG2 3L
-#define PR_WORDS_PER_DWORD_LOG2 1L
-
-#elif defined(XP_WIN) || defined(XP_OS2)
-
-#if defined( _WIN32) || defined(XP_OS2)
-#define IS_LITTLE_ENDIAN 1
-#undef IS_BIG_ENDIAN
-
-#define JS_BYTES_PER_BYTE 1L
-#define JS_BYTES_PER_SHORT 2L
-#define JS_BYTES_PER_INT 4L
-#define JS_BYTES_PER_INT64 8L
-#define JS_BYTES_PER_LONG 4L
-#define JS_BYTES_PER_FLOAT 4L
-#define JS_BYTES_PER_DOUBLE 8L
-#define JS_BYTES_PER_WORD 4L
-#define JS_BYTES_PER_DWORD 8L
-
-#define JS_BITS_PER_BYTE 8L
-#define JS_BITS_PER_SHORT 16L
-#define JS_BITS_PER_INT 32L
-#define JS_BITS_PER_INT64 64L
-#define JS_BITS_PER_LONG 32L
-#define JS_BITS_PER_FLOAT 32L
-#define JS_BITS_PER_DOUBLE 64L
-#define JS_BITS_PER_WORD 32L
-
-#define JS_BITS_PER_BYTE_LOG2 3L
-#define JS_BITS_PER_SHORT_LOG2 4L
-#define JS_BITS_PER_INT_LOG2 5L
-#define JS_BITS_PER_INT64_LOG2 6L
-#define JS_BITS_PER_LONG_LOG2 5L
-#define JS_BITS_PER_FLOAT_LOG2 5L
-#define JS_BITS_PER_DOUBLE_LOG2 6L
-#define JS_BITS_PER_WORD_LOG2 5L
-
-#define JS_ALIGN_OF_SHORT 2L
-#define JS_ALIGN_OF_INT 4L
-#define JS_ALIGN_OF_LONG 4L
-#define JS_ALIGN_OF_INT64 8L
-#define JS_ALIGN_OF_FLOAT 4L
-#define JS_ALIGN_OF_DOUBLE 4L
-#define JS_ALIGN_OF_POINTER 4L
-#define JS_ALIGN_OF_WORD 4L
-
-#define JS_BYTES_PER_WORD_LOG2 2L
-#define JS_BYTES_PER_DWORD_LOG2 3L
-#define PR_WORDS_PER_DWORD_LOG2 1L
-#endif /* _WIN32 || XP_OS2 */
-
-#if defined(_WINDOWS) && !defined(_WIN32) /* WIN16 */
-#define IS_LITTLE_ENDIAN 1
-#undef IS_BIG_ENDIAN
-
-#define JS_BYTES_PER_BYTE 1L
-#define JS_BYTES_PER_SHORT 2L
-#define JS_BYTES_PER_INT 2L
-#define JS_BYTES_PER_INT64 8L
-#define JS_BYTES_PER_LONG 4L
-#define JS_BYTES_PER_FLOAT 4L
-#define JS_BYTES_PER_DOUBLE 8L
-#define JS_BYTES_PER_WORD 4L
-#define JS_BYTES_PER_DWORD 8L
-
-#define JS_BITS_PER_BYTE 8L
-#define JS_BITS_PER_SHORT 16L
-#define JS_BITS_PER_INT 16L
-#define JS_BITS_PER_INT64 64L
-#define JS_BITS_PER_LONG 32L
-#define JS_BITS_PER_FLOAT 32L
-#define JS_BITS_PER_DOUBLE 64L
-#define JS_BITS_PER_WORD 32L
-
-#define JS_BITS_PER_BYTE_LOG2 3L
-#define JS_BITS_PER_SHORT_LOG2 4L
-#define JS_BITS_PER_INT_LOG2 4L
-#define JS_BITS_PER_INT64_LOG2 6L
-#define JS_BITS_PER_LONG_LOG2 5L
-#define JS_BITS_PER_FLOAT_LOG2 5L
-#define JS_BITS_PER_DOUBLE_LOG2 6L
-#define JS_BITS_PER_WORD_LOG2 5L
-
-#define JS_ALIGN_OF_SHORT 2L
-#define JS_ALIGN_OF_INT 2L
-#define JS_ALIGN_OF_LONG 2L
-#define JS_ALIGN_OF_INT64 2L
-#define JS_ALIGN_OF_FLOAT 2L
-#define JS_ALIGN_OF_DOUBLE 2L
-#define JS_ALIGN_OF_POINTER 2L
-#define JS_ALIGN_OF_WORD 2L
-
-#define JS_BYTES_PER_WORD_LOG2 2L
-#define JS_BYTES_PER_DWORD_LOG2 3L
-#define PR_WORDS_PER_DWORD_LOG2 1L
-#endif /* defined(_WINDOWS) && !defined(_WIN32) */
-
-#elif defined(XP_UNIX) || defined(XP_BEOS)
-
-#error "This file is supposed to be auto-generated on UNIX platforms, but the"
-#error "static version for Mac and Windows platforms is being used."
-#error "Something's probably wrong with paths/headers/dependencies/Makefiles."
-
-#else
-
-#error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN, or XP_UNIX"
-
-#endif
-
-#ifndef JS_STACK_GROWTH_DIRECTION
-#define JS_STACK_GROWTH_DIRECTION (-1)
-#endif
-
-#endif /* js_cpucfg___ */
diff --git a/src/extension/script/js/jsdate.c b/src/extension/script/js/jsdate.c
deleted file mode 100644
index a88df1830..000000000
--- a/src/extension/script/js/jsdate.c
+++ /dev/null
@@ -1,2234 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS date methods.
- */
-
-/*
- * "For example, OS/360 devotes 26 bytes of the permanently
- * resident date-turnover routine to the proper handling of
- * December 31 on leap years (when it is Day 366). That
- * might have been left to the operator."
- *
- * Frederick Brooks, 'The Second-System Effect'.
- */
-
-#include "jsstddef.h"
-#include <ctype.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsprf.h"
-#include "prmjtime.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsconfig.h"
-#include "jscntxt.h"
-#include "jsdate.h"
-#include "jsinterp.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsstr.h"
-
-/*
- * The JS 'Date' object is patterned after the Java 'Date' object.
- * Here is an script:
- *
- * today = new Date();
- *
- * print(today.toLocaleString());
- *
- * weekDay = today.getDay();
- *
- *
- * These Java (and ECMA-262) methods are supported:
- *
- * UTC
- * getDate (getUTCDate)
- * getDay (getUTCDay)
- * getHours (getUTCHours)
- * getMinutes (getUTCMinutes)
- * getMonth (getUTCMonth)
- * getSeconds (getUTCSeconds)
- * getMilliseconds (getUTCMilliseconds)
- * getTime
- * getTimezoneOffset
- * getYear
- * getFullYear (getUTCFullYear)
- * parse
- * setDate (setUTCDate)
- * setHours (setUTCHours)
- * setMinutes (setUTCMinutes)
- * setMonth (setUTCMonth)
- * setSeconds (setUTCSeconds)
- * setMilliseconds (setUTCMilliseconds)
- * setTime
- * setYear (setFullYear, setUTCFullYear)
- * toGMTString (toUTCString)
- * toLocaleString
- * toString
- *
- *
- * These Java methods are not supported
- *
- * setDay
- * before
- * after
- * equals
- * hashCode
- */
-
-/*
- * 11/97 - jsdate.c has been rewritten to conform to the ECMA-262 language
- * definition and reduce dependence on NSPR. NSPR is used to get the current
- * time in milliseconds, the time zone offset, and the daylight savings time
- * offset for a given time. NSPR is also used for Date.toLocaleString(), for
- * locale-specific formatting, and to get a string representing the timezone.
- * (Which turns out to be platform-dependent.)
- *
- * To do:
- * (I did some performance tests by timing how long it took to run what
- * I had of the js ECMA conformance tests.)
- *
- * - look at saving results across multiple calls to supporting
- * functions; the toString functions compute some of the same values
- * multiple times. Although - I took a quick stab at this, and I lost
- * rather than gained. (Fractionally.) Hard to tell what compilers/processors
- * are doing these days.
- *
- * - look at tweaking function return types to return double instead
- * of int; this seems to make things run slightly faster sometimes.
- * (though it could be architecture-dependent.) It'd be good to see
- * how this does on win32. (Tried it on irix.) Types could use a
- * general going-over.
- */
-
-/*
- * Supporting functions - ECMA 15.9.1.*
- */
-
-#define HalfTimeDomain 8.64e15
-#define HoursPerDay 24.0
-#define MinutesPerDay (HoursPerDay * MinutesPerHour)
-#define MinutesPerHour 60.0
-#define SecondsPerDay (MinutesPerDay * SecondsPerMinute)
-#define SecondsPerHour (MinutesPerHour * SecondsPerMinute)
-#define SecondsPerMinute 60.0
-
-#if defined(XP_WIN) || defined(XP_OS2)
-/* Work around msvc double optimization bug by making these runtime values; if
- * they're available at compile time, msvc optimizes division by them by
- * computing the reciprocal and multiplying instead of dividing - this loses
- * when the reciprocal isn't representable in a double.
- */
-static jsdouble msPerSecond = 1000.0;
-static jsdouble msPerDay = SecondsPerDay * 1000.0;
-static jsdouble msPerHour = SecondsPerHour * 1000.0;
-static jsdouble msPerMinute = SecondsPerMinute * 1000.0;
-#else
-#define msPerDay (SecondsPerDay * msPerSecond)
-#define msPerHour (SecondsPerHour * msPerSecond)
-#define msPerMinute (SecondsPerMinute * msPerSecond)
-#define msPerSecond 1000.0
-#endif
-
-#define Day(t) floor((t) / msPerDay)
-
-static jsdouble
-TimeWithinDay(jsdouble t)
-{
- jsdouble result;
- result = fmod(t, msPerDay);
- if (result < 0)
- result += msPerDay;
- return result;
-}
-
-#define DaysInYear(y) ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0)) \
- ? 366 : 365)
-
-/* math here has to be f.p, because we need
- * floor((1968 - 1969) / 4) == -1
- */
-#define DayFromYear(y) (365 * ((y)-1970) + floor(((y)-1969)/4.0) \
- - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
-#define TimeFromYear(y) (DayFromYear(y) * msPerDay)
-
-static jsint
-YearFromTime(jsdouble t)
-{
- jsint y = (jsint) floor(t /(msPerDay*365.2425)) + 1970;
- jsdouble t2 = (jsdouble) TimeFromYear(y);
-
- if (t2 > t) {
- y--;
- } else {
- if (t2 + msPerDay * DaysInYear(y) <= t)
- y++;
- }
- return y;
-}
-
-#define InLeapYear(t) (JSBool) (DaysInYear(YearFromTime(t)) == 366)
-
-#define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year)))
-
-/*
- * The following array contains the day of year for the first day of
- * each month, where index 0 is January, and day 0 is January 1.
- */
-static jsdouble firstDayOfMonth[2][12] = {
- {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0},
- {0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0}
-};
-
-#define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m];
-
-static intN
-MonthFromTime(jsdouble t)
-{
- intN d, step;
- jsint year = YearFromTime(t);
- d = DayWithinYear(t, year);
-
- if (d < (step = 31))
- return 0;
- step += (InLeapYear(t) ? 29 : 28);
- if (d < step)
- return 1;
- if (d < (step += 31))
- return 2;
- if (d < (step += 30))
- return 3;
- if (d < (step += 31))
- return 4;
- if (d < (step += 30))
- return 5;
- if (d < (step += 31))
- return 6;
- if (d < (step += 31))
- return 7;
- if (d < (step += 30))
- return 8;
- if (d < (step += 31))
- return 9;
- if (d < (step += 30))
- return 10;
- return 11;
-}
-
-static intN
-DateFromTime(jsdouble t)
-{
- intN d, step, next;
- jsint year = YearFromTime(t);
- d = DayWithinYear(t, year);
-
- if (d <= (next = 30))
- return d + 1;
- step = next;
- next += (InLeapYear(t) ? 29 : 28);
- if (d <= next)
- return d - step;
- step = next;
- if (d <= (next += 31))
- return d - step;
- step = next;
- if (d <= (next += 30))
- return d - step;
- step = next;
- if (d <= (next += 31))
- return d - step;
- step = next;
- if (d <= (next += 30))
- return d - step;
- step = next;
- if (d <= (next += 31))
- return d - step;
- step = next;
- if (d <= (next += 31))
- return d - step;
- step = next;
- if (d <= (next += 30))
- return d - step;
- step = next;
- if (d <= (next += 31))
- return d - step;
- step = next;
- if (d <= (next += 30))
- return d - step;
- step = next;
- return d - step;
-}
-
-static intN
-WeekDay(jsdouble t)
-{
- jsint result;
- result = (jsint) Day(t) + 4;
- result = result % 7;
- if (result < 0)
- result += 7;
- return (intN) result;
-}
-
-/* LocalTZA gets set by js_InitDateClass() */
-static jsdouble LocalTZA;
-
-static jsdouble
-DaylightSavingTA(jsdouble t)
-{
- volatile int64 PR_t;
- int64 ms2us;
- int64 offset;
- jsdouble result;
-
- /* abort if NaN */
- if (JSDOUBLE_IS_NaN(t))
- return t;
-
- /* put our t in an LL, and map it to usec for prtime */
- JSLL_D2L(PR_t, t);
- JSLL_I2L(ms2us, PRMJ_USEC_PER_MSEC);
- JSLL_MUL(PR_t, PR_t, ms2us);
-
- offset = PRMJ_DSTOffset(PR_t);
-
- JSLL_DIV(offset, offset, ms2us);
- JSLL_L2D(result, offset);
- return result;
-}
-
-
-#define AdjustTime(t) fmod(LocalTZA + DaylightSavingTA(t), msPerDay)
-
-#define LocalTime(t) ((t) + AdjustTime(t))
-
-static jsdouble
-UTC(jsdouble t)
-{
- return t - AdjustTime(t - LocalTZA);
-}
-
-static intN
-HourFromTime(jsdouble t)
-{
- intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);
- if (result < 0)
- result += (intN)HoursPerDay;
- return result;
-}
-
-static intN
-MinFromTime(jsdouble t)
-{
- intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour);
- if (result < 0)
- result += (intN)MinutesPerHour;
- return result;
-}
-
-static intN
-SecFromTime(jsdouble t)
-{
- intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute);
- if (result < 0)
- result += (intN)SecondsPerMinute;
- return result;
-}
-
-static intN
-msFromTime(jsdouble t)
-{
- intN result = (intN) fmod(t, msPerSecond);
- if (result < 0)
- result += (intN)msPerSecond;
- return result;
-}
-
-#define MakeTime(hour, min, sec, ms) \
-(((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms)
-
-static jsdouble
-MakeDay(jsdouble year, jsdouble month, jsdouble date)
-{
- jsdouble result;
- JSBool leap;
- jsdouble yearday;
- jsdouble monthday;
-
- year += floor(month / 12);
-
- month = fmod(month, 12.0);
- if (month < 0)
- month += 12;
-
- leap = (DaysInYear((jsint) year) == 366);
-
- yearday = floor(TimeFromYear(year) / msPerDay);
- monthday = DayFromMonth(month, leap);
-
- result = yearday
- + monthday
- + date - 1;
- return result;
-}
-
-#define MakeDate(day, time) (day * msPerDay + time)
-
-#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
- && !((d < 0 ? -d : d) > HalfTimeDomain)) \
- ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN)
-
-/**
- * end of ECMA 'support' functions
- */
-
-/*
- * Other Support routines and definitions
- */
-
-static JSClass date_class = {
- js_Date_str,
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-/* for use by date_parse */
-
-static const char* wtb[] = {
- "am", "pm",
- "monday", "tuesday", "wednesday", "thursday", "friday",
- "saturday", "sunday",
- "january", "february", "march", "april", "may", "june",
- "july", "august", "september", "october", "november", "december",
- "gmt", "ut", "utc",
- "est", "edt",
- "cst", "cdt",
- "mst", "mdt",
- "pst", "pdt"
- /* time zone table needs to be expanded */
-};
-
-static int ttb[] = {
- -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */
- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 10000 + 0, 10000 + 0, 10000 + 0, /* GMT/UT/UTC */
- 10000 + 5 * 60, 10000 + 4 * 60, /* EST/EDT */
- 10000 + 6 * 60, 10000 + 5 * 60, /* CST/CDT */
- 10000 + 7 * 60, 10000 + 6 * 60, /* MST/MDT */
- 10000 + 8 * 60, 10000 + 7 * 60 /* PST/PDT */
-};
-
-/* helper for date_parse */
-static JSBool
-date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off,
- int count, int ignoreCase)
-{
- JSBool result = JS_FALSE;
- /* return true if matches, otherwise, false */
-
- while (count > 0 && s1[s1off] && s2[s2off]) {
- if (ignoreCase) {
- if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
- break;
- }
- } else {
- if ((jschar)s1[s1off] != s2[s2off]) {
- break;
- }
- }
- s1off++;
- s2off++;
- count--;
- }
-
- if (count == 0) {
- result = JS_TRUE;
- }
-
- return result;
-}
-
-/* find UTC time from given date... no 1900 correction! */
-static jsdouble
-date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,
- jsdouble min, jsdouble sec, jsdouble msec)
-{
- jsdouble day;
- jsdouble msec_time;
- jsdouble result;
-
- day = MakeDay(year, mon, mday);
- msec_time = MakeTime(hour, min, sec, msec);
- result = MakeDate(day, msec_time);
- return result;
-}
-
-/*
- * See ECMA 15.9.4.[3-10];
- */
-/* XXX this function must be above date_parseString to avoid a
- horrid bug in the Win16 1.52 compiler */
-#define MAXARGS 7
-static JSBool
-date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble array[MAXARGS];
- uintN loop;
- jsdouble d;
-
- for (loop = 0; loop < MAXARGS; loop++) {
- if (loop < argc) {
- if (!js_ValueToNumber(cx, argv[loop], &d))
- return JS_FALSE;
- /* return NaN if any arg is NaN */
- if (!JSDOUBLE_IS_FINITE(d)) {
- return js_NewNumberValue(cx, d, rval);
- }
- array[loop] = floor(d);
- } else {
- array[loop] = 0;
- }
- }
-
- /* adjust 2-digit years into the 20th century */
- if (array[0] >= 0 && array[0] <= 99)
- array[0] += 1900;
-
- /* if we got a 0 for 'date' (which is out of range)
- * pretend it's a 1. (So Date.UTC(1972, 5) works) */
- if (array[2] < 1)
- array[2] = 1;
-
- d = date_msecFromDate(array[0], array[1], array[2],
- array[3], array[4], array[5], array[6]);
- d = TIMECLIP(d);
-
- return js_NewNumberValue(cx, d, rval);
-}
-
-static JSBool
-date_parseString(JSString *str, jsdouble *result)
-{
- jsdouble msec;
-
- const jschar *s = JSSTRING_CHARS(str);
- size_t limit = JSSTRING_LENGTH(str);
- size_t i = 0;
- int year = -1;
- int mon = -1;
- int mday = -1;
- int hour = -1;
- int min = -1;
- int sec = -1;
- int c = -1;
- int n = -1;
- jsdouble tzoffset = -1; /* was an int, overflowed on win16!!! */
- int prevc = 0;
- JSBool seenplusminus = JS_FALSE;
-
- if (limit == 0)
- goto syntax;
- while (i < limit) {
- c = s[i];
- i++;
- if (c <= ' ' || c == ',' || c == '-') {
- if (c == '-' && '0' <= s[i] && s[i] <= '9') {
- prevc = c;
- }
- continue;
- }
- if (c == '(') { /* comments) */
- int depth = 1;
- while (i < limit) {
- c = s[i];
- i++;
- if (c == '(') depth++;
- else if (c == ')')
- if (--depth <= 0)
- break;
- }
- continue;
- }
- if ('0' <= c && c <= '9') {
- n = c - '0';
- while (i < limit && '0' <= (c = s[i]) && c <= '9') {
- n = n * 10 + c - '0';
- i++;
- }
-
- /* allow TZA before the year, so
- * 'Wed Nov 05 21:49:11 GMT-0800 1997'
- * works */
-
- /* uses of seenplusminus allow : in TZA, so Java
- * no-timezone style of GMT+4:30 works
- */
-
- if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
- /* make ':' case below change tzoffset */
- seenplusminus = JS_TRUE;
-
- /* offset */
- if (n < 24)
- n = n * 60; /* EG. "GMT-3" */
- else
- n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
- if (prevc == '+') /* plus means east of GMT */
- n = -n;
- if (tzoffset != 0 && tzoffset != -1)
- goto syntax;
- tzoffset = n;
- } else if (n >= 70 ||
- (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
- if (year >= 0)
- goto syntax;
- else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
- year = n < 100 ? n + 1900 : n;
- else
- goto syntax;
- } else if (c == ':') {
- if (hour < 0)
- hour = /*byte*/ n;
- else if (min < 0)
- min = /*byte*/ n;
- else
- goto syntax;
- } else if (c == '/') {
- if (mon < 0)
- mon = /*byte*/ n-1;
- else if (mday < 0)
- mday = /*byte*/ n;
- else
- goto syntax;
- } else if (i < limit && c != ',' && c > ' ' && c != '-') {
- goto syntax;
- } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
- if (tzoffset < 0)
- tzoffset -= n;
- else
- tzoffset += n;
- } else if (hour >= 0 && min < 0) {
- min = /*byte*/ n;
- } else if (min >= 0 && sec < 0) {
- sec = /*byte*/ n;
- } else if (mday < 0) {
- mday = /*byte*/ n;
- } else {
- goto syntax;
- }
- prevc = 0;
- } else if (c == '/' || c == ':' || c == '+' || c == '-') {
- prevc = c;
- } else {
- size_t st = i - 1;
- int k;
- while (i < limit) {
- c = s[i];
- if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
- break;
- i++;
- }
- if (i <= st + 1)
- goto syntax;
- for (k = (sizeof(wtb)/sizeof(char*)); --k >= 0;)
- if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
- int action = ttb[k];
- if (action != 0) {
- if (action < 0) {
- /*
- * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
- * 12:30, instead of blindly adding 12 if PM.
- */
- JS_ASSERT(action == -1 || action == -2);
- if (hour > 12 || hour < 0) {
- goto syntax;
- } else {
- if (action == -1 && hour == 12) { /* am */
- hour = 0;
- } else if (action == -2 && hour != 12) { /* pm */
- hour += 12;
- }
- }
- } else if (action <= 13) { /* month! */
- if (mon < 0) {
- mon = /*byte*/ (action - 2);
- } else {
- goto syntax;
- }
- } else {
- tzoffset = action - 10000;
- }
- }
- break;
- }
- if (k < 0)
- goto syntax;
- prevc = 0;
- }
- }
- if (year < 0 || mon < 0 || mday < 0)
- goto syntax;
- if (sec < 0)
- sec = 0;
- if (min < 0)
- min = 0;
- if (hour < 0)
- hour = 0;
- if (tzoffset == -1) { /* no time zone specified, have to use local */
- jsdouble msec_time;
- msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
-
- *result = UTC(msec_time);
- return JS_TRUE;
- }
-
- msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
- msec += tzoffset * msPerMinute;
- *result = msec;
- return JS_TRUE;
-
-syntax:
- /* syntax error */
- *result = 0;
- return JS_FALSE;
-}
-
-static JSBool
-date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsdouble result;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- if (!date_parseString(str, &result)) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
-
- result = TIMECLIP(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_now(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- int64 us, ms, us2ms;
- jsdouble msec_time;
-
- us = PRMJ_Now();
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
- JSLL_DIV(ms, us, us2ms);
- JSLL_L2D(msec_time, ms);
-
- return js_NewDoubleValue(cx, msec_time, rval);
-}
-
-/*
- * Check that obj is an object of class Date, and get the date value.
- * Return NULL on failure.
- */
-static jsdouble *
-date_getProlog(JSContext *cx, JSObject *obj, jsval *argv)
-{
- if (!JS_InstanceOf(cx, obj, &date_class, argv))
- return NULL;
- return JSVAL_TO_DOUBLE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
-}
-
-/*
- * See ECMA 15.9.5.4 thru 15.9.5.23
- */
-static JSBool
-date_getTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- return js_NewNumberValue(cx, *date, rval);
-}
-
-static JSBool
-date_getYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = YearFromTime(LocalTime(result));
-
- /*
- * During the great date rewrite of 1.3, we tried to track the evolving ECMA
- * standard, which then had a definition of getYear which always subtracted
- * 1900. Which we implemented, not realizing that it was incompatible with
- * the old behavior... now, rather than thrash the behavior yet again,
- * we've decided to leave it with the - 1900 behavior and point people to
- * the getFullYear method. But we try to protect existing scripts that
- * have specified a version...
- */
- if (cx->version == JSVERSION_1_0 ||
- cx->version == JSVERSION_1_1 ||
- cx->version == JSVERSION_1_2)
- {
- if (result >= 1900 && result < 2000)
- result -= 1900;
- } else {
- result -= 1900;
- }
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = YearFromTime(LocalTime(result));
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = YearFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = MonthFromTime(LocalTime(result));
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = MonthFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = LocalTime(result);
- result = DateFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = DateFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = LocalTime(result);
- result = WeekDay(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = WeekDay(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = HourFromTime(LocalTime(result));
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = HourFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = MinFromTime(LocalTime(result));
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = MinFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-/* Date.getSeconds is mapped to getUTCSeconds */
-
-static JSBool
-date_getUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = SecFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-/* Date.getMilliseconds is mapped to getUTCMilliseconds */
-
-static JSBool
-date_getUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- result = msFromTime(result);
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_getTimezoneOffset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- result = *date;
-
- /*
- * Return the time zone offset in minutes for the current locale
- * that is appropriate for this time. This value would be a
- * constant except for daylight savings time.
- */
- result = (result - LocalTime(result)) / msPerMinute;
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_setTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble result;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- if (!js_ValueToNumber(cx, argv[0], &result))
- return JS_FALSE;
-
- result = TIMECLIP(result);
-
- *date = result;
- return js_NewNumberValue(cx, result, rval);
-}
-
-static JSBool
-date_makeTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- uintN maxargs, JSBool local, jsval *rval)
-{
- uintN i;
- jsdouble args[4], *argp, *stop;
- jsdouble hour, min, sec, msec;
- jsdouble lorutime; /* Local or UTC version of *date */
-
- jsdouble msec_time;
- jsdouble result;
-
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- result = *date;
-
- /* just return NaN if the date is already NaN */
- if (!JSDOUBLE_IS_FINITE(result))
- return js_NewNumberValue(cx, result, rval);
-
- /* Satisfy the ECMA rule that if a function is called with
- * fewer arguments than the specified formal arguments, the
- * remaining arguments are set to undefined. Seems like all
- * the Date.setWhatever functions in ECMA are only varargs
- * beyond the first argument; this should be set to undefined
- * if it's not given. This means that "d = new Date();
- * d.setMilliseconds()" returns NaN. Blech.
- */
- if (argc == 0)
- argc = 1; /* should be safe, because length of all setters is 1 */
- else if (argc > maxargs)
- argc = maxargs; /* clamp argc */
-
- for (i = 0; i < argc; i++) {
- if (!js_ValueToNumber(cx, argv[i], &args[i]))
- return JS_FALSE;
- if (!JSDOUBLE_IS_FINITE(args[i])) {
- *date = *cx->runtime->jsNaN;
- return js_NewNumberValue(cx, *date, rval);
- }
- args[i] = js_DoubleToInteger(args[i]);
- }
-
- if (local)
- lorutime = LocalTime(result);
- else
- lorutime = result;
-
- argp = args;
- stop = argp + argc;
- if (maxargs >= 4 && argp < stop)
- hour = *argp++;
- else
- hour = HourFromTime(lorutime);
-
- if (maxargs >= 3 && argp < stop)
- min = *argp++;
- else
- min = MinFromTime(lorutime);
-
- if (maxargs >= 2 && argp < stop)
- sec = *argp++;
- else
- sec = SecFromTime(lorutime);
-
- if (maxargs >= 1 && argp < stop)
- msec = *argp;
- else
- msec = msFromTime(lorutime);
-
- msec_time = MakeTime(hour, min, sec, msec);
- result = MakeDate(Day(lorutime), msec_time);
-
-/* fprintf(stderr, "%f\n", result); */
-
- if (local)
- result = UTC(result);
-
-/* fprintf(stderr, "%f\n", result); */
-
- *date = TIMECLIP(result);
- return js_NewNumberValue(cx, *date, rval);
-}
-
-static JSBool
-date_setMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 1, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 1, JS_FALSE, rval);
-}
-
-static JSBool
-date_setSeconds(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 2, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCSeconds(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 2, JS_FALSE, rval);
-}
-
-static JSBool
-date_setMinutes(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 3, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCMinutes(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 3, JS_FALSE, rval);
-}
-
-static JSBool
-date_setHours(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 4, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCHours(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeTime(cx, obj, argc, argv, 4, JS_FALSE, rval);
-}
-
-static JSBool
-date_makeDate(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, uintN maxargs, JSBool local, jsval *rval)
-{
- uintN i;
- jsdouble lorutime; /* local or UTC version of *date */
- jsdouble args[3], *argp, *stop;
- jsdouble year, month, day;
- jsdouble result;
-
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- result = *date;
-
- /* see complaint about ECMA in date_MakeTime */
- if (argc == 0)
- argc = 1; /* should be safe, because length of all setters is 1 */
- else if (argc > maxargs)
- argc = maxargs; /* clamp argc */
-
- for (i = 0; i < argc; i++) {
- if (!js_ValueToNumber(cx, argv[i], &args[i]))
- return JS_FALSE;
- if (!JSDOUBLE_IS_FINITE(args[i])) {
- *date = *cx->runtime->jsNaN;
- return js_NewNumberValue(cx, *date, rval);
- }
- args[i] = js_DoubleToInteger(args[i]);
- }
-
- /* return NaN if date is NaN and we're not setting the year,
- * If we are, use 0 as the time. */
- if (!(JSDOUBLE_IS_FINITE(result))) {
- if (argc < 3)
- return js_NewNumberValue(cx, result, rval);
- else
- lorutime = +0.;
- } else {
- if (local)
- lorutime = LocalTime(result);
- else
- lorutime = result;
- }
-
- argp = args;
- stop = argp + argc;
- if (maxargs >= 3 && argp < stop)
- year = *argp++;
- else
- year = YearFromTime(lorutime);
-
- if (maxargs >= 2 && argp < stop)
- month = *argp++;
- else
- month = MonthFromTime(lorutime);
-
- if (maxargs >= 1 && argp < stop)
- day = *argp++;
- else
- day = DateFromTime(lorutime);
-
- day = MakeDay(year, month, day); /* day within year */
- result = MakeDate(day, TimeWithinDay(lorutime));
-
- if (local)
- result = UTC(result);
-
- *date = TIMECLIP(result);
- return js_NewNumberValue(cx, *date, rval);
-}
-
-static JSBool
-date_setDate(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 1, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCDate(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 1, JS_FALSE, rval);
-}
-
-static JSBool
-date_setMonth(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 2, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCMonth(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 2, JS_FALSE, rval);
-}
-
-static JSBool
-date_setFullYear(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 3, JS_TRUE, rval);
-}
-
-static JSBool
-date_setUTCFullYear(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_makeDate(cx, obj, argc, argv, 3, JS_FALSE, rval);
-}
-
-static JSBool
-date_setYear(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- jsdouble t;
- jsdouble year;
- jsdouble day;
- jsdouble result;
-
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- result = *date;
-
- if (!js_ValueToNumber(cx, argv[0], &year))
- return JS_FALSE;
- if (!JSDOUBLE_IS_FINITE(year)) {
- *date = *cx->runtime->jsNaN;
- return js_NewNumberValue(cx, *date, rval);
- }
-
- year = js_DoubleToInteger(year);
-
- if (!JSDOUBLE_IS_FINITE(result)) {
- t = +0.0;
- } else {
- t = LocalTime(result);
- }
-
- if (year >= 0 && year <= 99)
- year += 1900;
-
- day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
- result = MakeDate(day, TimeWithinDay(t));
- result = UTC(result);
-
- *date = TIMECLIP(result);
- return js_NewNumberValue(cx, *date, rval);
-}
-
-/* constants for toString, toUTCString */
-static char js_NaN_date_str[] = "Invalid Date";
-static const char* days[] =
-{
- "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
-};
-static const char* months[] =
-{
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static JSBool
-date_toGMTString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- char buf[100];
- JSString *str;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- if (!JSDOUBLE_IS_FINITE(*date)) {
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
- } else {
- jsdouble temp = *date;
-
- /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
- * requires a PRMJTime... which only has 16-bit years. Sub-ECMA.
- */
- JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
- days[WeekDay(temp)],
- DateFromTime(temp),
- months[MonthFromTime(temp)],
- YearFromTime(temp),
- HourFromTime(temp),
- MinFromTime(temp),
- SecFromTime(temp));
- }
- str = JS_NewStringCopyZ(cx, buf);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-/* for Date.toLocaleString; interface to PRMJTime date struct.
- * If findEquivalent is true, then try to map the year to an equivalent year
- * that's in range.
- */
-static void
-new_explode(jsdouble timeval, PRMJTime *split, JSBool findEquivalent)
-{
- jsint year = YearFromTime(timeval);
- int16 adjustedYear;
-
- /* If the year doesn't fit in a PRMJTime, find something to do about it. */
- if (year > 32767 || year < -32768) {
- if (findEquivalent) {
- /* We're really just trying to get a timezone string; map the year
- * to some equivalent year in the range 0 to 2800. Borrowed from
- * A. D. Olsen.
- */
- jsint cycles;
-#define CYCLE_YEARS 2800L
- cycles = (year >= 0) ? year / CYCLE_YEARS
- : -1 - (-1 - year) / CYCLE_YEARS;
- adjustedYear = (int16)(year - cycles * CYCLE_YEARS);
- } else {
- /* Clamp it to the nearest representable year. */
- adjustedYear = (int16)((year > 0) ? 32767 : - 32768);
- }
- } else {
- adjustedYear = (int16)year;
- }
-
- split->tm_usec = (int32) msFromTime(timeval) * 1000;
- split->tm_sec = (int8) SecFromTime(timeval);
- split->tm_min = (int8) MinFromTime(timeval);
- split->tm_hour = (int8) HourFromTime(timeval);
- split->tm_mday = (int8) DateFromTime(timeval);
- split->tm_mon = (int8) MonthFromTime(timeval);
- split->tm_wday = (int8) WeekDay(timeval);
- split->tm_year = (int16) adjustedYear;
- split->tm_yday = (int16) DayWithinYear(timeval, year);
-
- /* not sure how this affects things, but it doesn't seem
- to matter. */
- split->tm_isdst = (DaylightSavingTA(timeval) != 0);
-}
-
-typedef enum formatspec {
- FORMATSPEC_FULL, FORMATSPEC_DATE, FORMATSPEC_TIME
-} formatspec;
-
-/* helper function */
-static JSBool
-date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval)
-{
- char buf[100];
- JSString *str;
- char tzbuf[100];
- JSBool usetz;
- size_t i, tzlen;
- PRMJTime split;
-
- if (!JSDOUBLE_IS_FINITE(date)) {
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
- } else {
- jsdouble local = LocalTime(date);
-
- /* offset from GMT in minutes. The offset includes daylight savings,
- if it applies. */
- jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
-
- /* map 510 minutes to 0830 hours */
- intN offset = (minutes / 60) * 100 + minutes % 60;
-
- /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
- * printed as 'GMT-0800' rather than as 'PST' to avoid
- * operating-system dependence on strftime (which
- * PRMJ_FormatTimeUSEnglish calls, for %Z only.) win32 prints
- * PST as 'Pacific Standard Time.' This way we always know
- * what we're getting, and can parse it if we produce it.
- * The OS TZA string is included as a comment.
- */
-
- /* get a timezone string from the OS to include as a
- comment. */
- new_explode(date, &split, JS_TRUE);
- if (PRMJ_FormatTime(tzbuf, sizeof tzbuf, "(%Z)", &split) != 0) {
-
- /* Decide whether to use the resulting timezone string.
- *
- * Reject it if it contains any non-ASCII, non-alphanumeric
- * characters. It's then likely in some other character
- * encoding, and we probably won't display it correctly.
- */
- usetz = JS_TRUE;
- tzlen = strlen(tzbuf);
- if (tzlen > 100) {
- usetz = JS_FALSE;
- } else {
- for (i = 0; i < tzlen; i++) {
- jschar c = tzbuf[i];
- if (c > 127 ||
- !(isalpha(c) || isdigit(c) ||
- c == ' ' || c == '(' || c == ')')) {
- usetz = JS_FALSE;
- }
- }
- }
-
- /* Also reject it if it's not parenthesized or if it's '()'. */
- if (tzbuf[0] != '(' || tzbuf[1] == ')')
- usetz = JS_FALSE;
- } else
- usetz = JS_FALSE;
-
- switch (format) {
- case FORMATSPEC_FULL:
- /*
- * Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
- * requires a PRMJTime... which only has 16-bit years. Sub-ECMA.
- */
- /* Tue Oct 31 2000 09:41:40 GMT-0800 (PST) */
- JS_snprintf(buf, sizeof buf,
- "%s %s %.2d %.4d %.2d:%.2d:%.2d GMT%+.4d%s%s",
- days[WeekDay(local)],
- months[MonthFromTime(local)],
- DateFromTime(local),
- YearFromTime(local),
- HourFromTime(local),
- MinFromTime(local),
- SecFromTime(local),
- offset,
- usetz ? " " : "",
- usetz ? tzbuf : "");
- break;
- case FORMATSPEC_DATE:
- /* Tue Oct 31 2000 */
- JS_snprintf(buf, sizeof buf,
- "%s %s %.2d %.4d",
- days[WeekDay(local)],
- months[MonthFromTime(local)],
- DateFromTime(local),
- YearFromTime(local));
- break;
- case FORMATSPEC_TIME:
- /* 09:41:40 GMT-0800 (PST) */
- JS_snprintf(buf, sizeof buf,
- "%.2d:%.2d:%.2d GMT%+.4d%s%s",
- HourFromTime(local),
- MinFromTime(local),
- SecFromTime(local),
- offset,
- usetz ? " " : "",
- usetz ? tzbuf : "");
- break;
- }
- }
-
- str = JS_NewStringCopyZ(cx, buf);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-date_toLocaleHelper(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval, char *format)
-{
- char buf[100];
- JSString *str;
- PRMJTime split;
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- if (!JSDOUBLE_IS_FINITE(*date)) {
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
- } else {
- intN result_len;
- jsdouble local = LocalTime(*date);
- new_explode(local, &split, JS_FALSE);
-
- /* let PRMJTime format it. */
- result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
-
- /* If it failed, default to toString. */
- if (result_len == 0)
- return date_format(cx, *date, FORMATSPEC_FULL, rval);
-
- /* Hacked check against undesired 2-digit year 00/00/00 form. */
- if (buf[result_len - 3] == '/' &&
- isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1])) {
- JS_snprintf(buf + (result_len - 2), (sizeof buf) - (result_len - 2),
- "%d", js_DateGetYear(cx, obj));
- }
-
- }
-
- str = JS_NewStringCopyZ(cx, buf);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-date_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- /* Use '%#c' for windows, because '%c' is
- * backward-compatible and non-y2k with msvc; '%#c' requests that a
- * full year be used in the result string.
- */
- return date_toLocaleHelper(cx, obj, argc, argv, rval,
-#if defined(_WIN32) && !defined(__MWERKS__)
- "%#c"
-#else
- "%c"
-#endif
- );
-}
-
-static JSBool
-date_toLocaleDateString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- /* Use '%#x' for windows, because '%x' is
- * backward-compatible and non-y2k with msvc; '%#x' requests that a
- * full year be used in the result string.
- */
- return date_toLocaleHelper(cx, obj, argc, argv, rval,
-#if defined(_WIN32) && !defined(__MWERKS__)
- "%#x"
-#else
- "%x"
-#endif
- );
-}
-
-static JSBool
-date_toLocaleTimeString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- return date_toLocaleHelper(cx, obj, argc, argv, rval, "%X");
-}
-
-static JSBool
-date_toTimeString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- return date_format(cx, *date, FORMATSPEC_TIME, rval);
-}
-
-static JSBool
-date_toDateString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- return date_format(cx, *date, FORMATSPEC_DATE, rval);
-}
-
-#if JS_HAS_TOSOURCE
-#include <string.h>
-#include "jsdtoa.h"
-
-static JSBool
-date_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble *date;
- char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
- JSString *str;
-
- date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
-
- numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, *date);
- if (!numStr) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- bytes = JS_smprintf("(new %s(%s))", date_class.name, numStr);
- if (!bytes) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- str = JS_NewString(cx, bytes, strlen(bytes));
- if (!str) {
- free(bytes);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif
-
-static JSBool
-date_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsdouble *date = date_getProlog(cx, obj, argv);
- if (!date)
- return JS_FALSE;
- return date_format(cx, *date, FORMATSPEC_FULL, rval);
-}
-
-#if JS_HAS_VALUEOF_HINT
-static JSBool
-date_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- /* It is an error to call date_valueOf on a non-date object, but we don't
- * need to check for that explicitly here because every path calls
- * date_getProlog, which does the check.
- */
-
- /* If called directly with no arguments, convert to a time number. */
- if (argc == 0)
- return date_getTime(cx, obj, argc, argv, rval);
-
- /* Convert to number only if the hint was given, otherwise favor string. */
- if (argc == 1) {
- JSString *str, *str2;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
- if (!js_CompareStrings(str, str2))
- return date_getTime(cx, obj, argc, argv, rval);
- }
- return date_toString(cx, obj, argc, argv, rval);
-}
-#else
-#define date_valueOf date_getTime
-#endif
-
-
-/*
- * creation and destruction
- */
-
-static JSFunctionSpec date_static_methods[] = {
- {"UTC", date_UTC, MAXARGS,0,0 },
- {"parse", date_parse, 1,0,0 },
- {"now", date_now, 0,0,0 },
- {0,0,0,0,0}
-};
-
-static JSFunctionSpec date_methods[] = {
- {"getTime", date_getTime, 0,0,0 },
- {"getTimezoneOffset", date_getTimezoneOffset, 0,0,0 },
- {"getYear", date_getYear, 0,0,0 },
- {"getFullYear", date_getFullYear, 0,0,0 },
- {"getUTCFullYear", date_getUTCFullYear, 0,0,0 },
- {"getMonth", date_getMonth, 0,0,0 },
- {"getUTCMonth", date_getUTCMonth, 0,0,0 },
- {"getDate", date_getDate, 0,0,0 },
- {"getUTCDate", date_getUTCDate, 0,0,0 },
- {"getDay", date_getDay, 0,0,0 },
- {"getUTCDay", date_getUTCDay, 0,0,0 },
- {"getHours", date_getHours, 0,0,0 },
- {"getUTCHours", date_getUTCHours, 0,0,0 },
- {"getMinutes", date_getMinutes, 0,0,0 },
- {"getUTCMinutes", date_getUTCMinutes, 0,0,0 },
- {"getSeconds", date_getUTCSeconds, 0,0,0 },
- {"getUTCSeconds", date_getUTCSeconds, 0,0,0 },
- {"getMilliseconds", date_getUTCMilliseconds,0,0,0 },
- {"getUTCMilliseconds", date_getUTCMilliseconds,0,0,0 },
- {"setTime", date_setTime, 1,0,0 },
- {"setYear", date_setYear, 1,0,0 },
- {"setFullYear", date_setFullYear, 3,0,0 },
- {"setUTCFullYear", date_setUTCFullYear, 3,0,0 },
- {"setMonth", date_setMonth, 2,0,0 },
- {"setUTCMonth", date_setUTCMonth, 2,0,0 },
- {"setDate", date_setDate, 1,0,0 },
- {"setUTCDate", date_setUTCDate, 1,0,0 },
- {"setHours", date_setHours, 4,0,0 },
- {"setUTCHours", date_setUTCHours, 4,0,0 },
- {"setMinutes", date_setMinutes, 3,0,0 },
- {"setUTCMinutes", date_setUTCMinutes, 3,0,0 },
- {"setSeconds", date_setSeconds, 2,0,0 },
- {"setUTCSeconds", date_setUTCSeconds, 2,0,0 },
- {"setMilliseconds", date_setMilliseconds, 1,0,0 },
- {"setUTCMilliseconds", date_setUTCMilliseconds,1,0,0 },
- {"toUTCString", date_toGMTString, 0,0,0 },
- {js_toLocaleString_str, date_toLocaleString, 0,0,0 },
- {"toLocaleDateString", date_toLocaleDateString,0,0,0 },
- {"toLocaleTimeString", date_toLocaleTimeString,0,0,0 },
- {"toDateString", date_toDateString, 0,0,0 },
- {"toTimeString", date_toTimeString, 0,0,0 },
-#if JS_HAS_TOSOURCE
- {js_toSource_str, date_toSource, 0,0,0 },
-#endif
- {js_toString_str, date_toString, 0,0,0 },
- {js_valueOf_str, date_valueOf, 0,0,0 },
- {0,0,0,0,0}
-};
-
-static jsdouble *
-date_constructor(JSContext *cx, JSObject* obj)
-{
- jsdouble *date;
-
- date = js_NewDouble(cx, 0.0);
- if (!date)
- return NULL;
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, DOUBLE_TO_JSVAL(date));
- return date;
-}
-
-static JSBool
-Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble *date;
- JSString *str;
- jsdouble d;
-
- /* Date called as function */
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- int64 us, ms, us2ms;
- jsdouble msec_time;
-
- /* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
- * so compute ms from PRMJ_Now.
- */
- us = PRMJ_Now();
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
- JSLL_DIV(ms, us, us2ms);
- JSLL_L2D(msec_time, ms);
-
- return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
- }
-
- /* Date called as constructor */
- if (argc == 0) {
- int64 us, ms, us2ms;
- jsdouble msec_time;
-
- date = date_constructor(cx, obj);
- if (!date)
- return JS_FALSE;
-
- us = PRMJ_Now();
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
- JSLL_DIV(ms, us, us2ms);
- JSLL_L2D(msec_time, ms);
-
- *date = msec_time;
- } else if (argc == 1) {
- if (!JSVAL_IS_STRING(argv[0])) {
- /* the argument is a millisecond number */
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- date = date_constructor(cx, obj);
- if (!date)
- return JS_FALSE;
- *date = TIMECLIP(d);
- } else {
- /* the argument is a string; parse it. */
- date = date_constructor(cx, obj);
- if (!date)
- return JS_FALSE;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
-
- if (!date_parseString(str, date))
- *date = *cx->runtime->jsNaN;
- *date = TIMECLIP(*date);
- }
- } else {
- jsdouble array[MAXARGS];
- uintN loop;
- jsdouble double_arg;
- jsdouble day;
- jsdouble msec_time;
-
- for (loop = 0; loop < MAXARGS; loop++) {
- if (loop < argc) {
- if (!js_ValueToNumber(cx, argv[loop], &double_arg))
- return JS_FALSE;
- /* if any arg is NaN, make a NaN date object
- and return */
- if (!JSDOUBLE_IS_FINITE(double_arg)) {
- date = date_constructor(cx, obj);
- if (!date)
- return JS_FALSE;
- *date = *cx->runtime->jsNaN;
- return JS_TRUE;
- }
- array[loop] = js_DoubleToInteger(double_arg);
- } else {
- if (loop == 2) {
- array[loop] = 1; /* Default the date argument to 1. */
- } else {
- array[loop] = 0;
- }
- }
- }
-
- date = date_constructor(cx, obj);
- if (!date)
- return JS_FALSE;
-
- /* adjust 2-digit years into the 20th century */
- if (array[0] >= 0 && array[0] <= 99)
- array[0] += 1900;
-
- day = MakeDay(array[0], array[1], array[2]);
- msec_time = MakeTime(array[3], array[4], array[5], array[6]);
- msec_time = MakeDate(day, msec_time);
- msec_time = UTC(msec_time);
- *date = TIMECLIP(msec_time);
- }
- return JS_TRUE;
-}
-
-JSObject *
-js_InitDateClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
- jsdouble *proto_date;
-
- /* set static LocalTZA */
- LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
- proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS,
- NULL, date_methods, NULL, date_static_methods);
- if (!proto)
- return NULL;
-
- /* Alias toUTCString with toGMTString. (ECMA B.2.6) */
- if (!JS_AliasProperty(cx, proto, "toUTCString", "toGMTString"))
- return NULL;
-
- /* Set the value of the Date.prototype date to NaN */
- proto_date = date_constructor(cx, proto);
- if (!proto_date)
- return NULL;
- *proto_date = *cx->runtime->jsNaN;
-
- return proto;
-}
-
-JS_FRIEND_API(JSObject *)
-js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time)
-{
- JSObject *obj;
- jsdouble *date;
-
- obj = js_NewObject(cx, &date_class, NULL, NULL);
- if (!obj)
- return NULL;
-
- date = date_constructor(cx, obj);
- if (!date)
- return NULL;
-
- *date = msec_time;
- return obj;
-}
-
-JS_FRIEND_API(JSObject *)
-js_NewDateObject(JSContext* cx, int year, int mon, int mday,
- int hour, int min, int sec)
-{
- JSObject *obj;
- jsdouble msec_time;
-
- msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
- obj = js_NewDateObjectMsec(cx, UTC(msec_time));
- return obj;
-}
-
-JS_FRIEND_API(JSBool)
-js_DateIsValid(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return JS_FALSE;
- else
- return JS_TRUE;
-}
-
-JS_FRIEND_API(int)
-js_DateGetYear(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- /* Preserve legacy API behavior of returning 0 for invalid dates. */
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) YearFromTime(LocalTime(*date));
-}
-
-JS_FRIEND_API(int)
-js_DateGetMonth(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) MonthFromTime(LocalTime(*date));
-}
-
-JS_FRIEND_API(int)
-js_DateGetDate(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) DateFromTime(LocalTime(*date));
-}
-
-JS_FRIEND_API(int)
-js_DateGetHours(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) HourFromTime(LocalTime(*date));
-}
-
-JS_FRIEND_API(int)
-js_DateGetMinutes(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) MinFromTime(LocalTime(*date));
-}
-
-JS_FRIEND_API(int)
-js_DateGetSeconds(JSContext *cx, JSObject* obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
-
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (int) SecFromTime(*date);
-}
-
-JS_FRIEND_API(void)
-js_DateSetYear(JSContext *cx, JSObject *obj, int year)
-{
- jsdouble local;
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date)
- return;
- local = LocalTime(*date);
- /* reset date if it was NaN */
- if (JSDOUBLE_IS_NaN(local))
- local = 0;
- local = date_msecFromDate(year,
- MonthFromTime(local),
- DateFromTime(local),
- HourFromTime(local),
- MinFromTime(local),
- SecFromTime(local),
- msFromTime(local));
- *date = UTC(local);
-}
-
-JS_FRIEND_API(void)
-js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
-{
- jsdouble local;
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date)
- return;
- local = LocalTime(*date);
- /* bail if date was NaN */
- if (JSDOUBLE_IS_NaN(local))
- return;
- local = date_msecFromDate(YearFromTime(local),
- month,
- DateFromTime(local),
- HourFromTime(local),
- MinFromTime(local),
- SecFromTime(local),
- msFromTime(local));
- *date = UTC(local);
-}
-
-JS_FRIEND_API(void)
-js_DateSetDate(JSContext *cx, JSObject *obj, int date)
-{
- jsdouble local;
- jsdouble *datep = date_getProlog(cx, obj, NULL);
- if (!datep)
- return;
- local = LocalTime(*datep);
- if (JSDOUBLE_IS_NaN(local))
- return;
- local = date_msecFromDate(YearFromTime(local),
- MonthFromTime(local),
- date,
- HourFromTime(local),
- MinFromTime(local),
- SecFromTime(local),
- msFromTime(local));
- *datep = UTC(local);
-}
-
-JS_FRIEND_API(void)
-js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
-{
- jsdouble local;
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date)
- return;
- local = LocalTime(*date);
- if (JSDOUBLE_IS_NaN(local))
- return;
- local = date_msecFromDate(YearFromTime(local),
- MonthFromTime(local),
- DateFromTime(local),
- hours,
- MinFromTime(local),
- SecFromTime(local),
- msFromTime(local));
- *date = UTC(local);
-}
-
-JS_FRIEND_API(void)
-js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
-{
- jsdouble local;
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date)
- return;
- local = LocalTime(*date);
- if (JSDOUBLE_IS_NaN(local))
- return;
- local = date_msecFromDate(YearFromTime(local),
- MonthFromTime(local),
- DateFromTime(local),
- HourFromTime(local),
- minutes,
- SecFromTime(local),
- msFromTime(local));
- *date = UTC(local);
-}
-
-JS_FRIEND_API(void)
-js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
-{
- jsdouble local;
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date)
- return;
- local = LocalTime(*date);
- if (JSDOUBLE_IS_NaN(local))
- return;
- local = date_msecFromDate(YearFromTime(local),
- MonthFromTime(local),
- DateFromTime(local),
- HourFromTime(local),
- MinFromTime(local),
- seconds,
- msFromTime(local));
- *date = UTC(local);
-}
-
-JS_FRIEND_API(jsdouble)
-js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
-{
- jsdouble *date = date_getProlog(cx, obj, NULL);
- if (!date || JSDOUBLE_IS_NaN(*date))
- return 0;
- return (*date);
-}
diff --git a/src/extension/script/js/jsdate.h b/src/extension/script/js/jsdate.h
deleted file mode 100644
index 790b4daf6..000000000
--- a/src/extension/script/js/jsdate.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS Date class interface.
- */
-
-#ifndef jsdate_h___
-#define jsdate_h___
-
-JS_BEGIN_EXTERN_C
-
-extern JSObject *
-js_InitDateClass(JSContext *cx, JSObject *obj);
-
-/*
- * These functions provide a C interface to the date/time object
- */
-
-/*
- * Construct a new Date Object from a time value given in milliseconds UTC
- * since the epoch.
- */
-extern JS_FRIEND_API(JSObject*)
-js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time);
-
-/*
- * Construct a new Date Object from an exploded local time value.
- */
-extern JS_FRIEND_API(JSObject*)
-js_NewDateObject(JSContext* cx, int year, int mon, int mday,
- int hour, int min, int sec);
-
-/*
- * Detect whether the internal date value is NaN. (Because failure is
- * out-of-band for js_DateGet*)
- */
-extern JS_FRIEND_API(JSBool)
-js_DateIsValid(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetYear(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetMonth(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetDate(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetHours(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetMinutes(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(int)
-js_DateGetSeconds(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(void)
-js_DateSetYear(JSContext *cx, JSObject *obj, int year);
-
-extern JS_FRIEND_API(void)
-js_DateSetMonth(JSContext *cx, JSObject *obj, int year);
-
-extern JS_FRIEND_API(void)
-js_DateSetDate(JSContext *cx, JSObject *obj, int date);
-
-extern JS_FRIEND_API(void)
-js_DateSetHours(JSContext *cx, JSObject *obj, int hours);
-
-extern JS_FRIEND_API(void)
-js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes);
-
-extern JS_FRIEND_API(void)
-js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds);
-
-extern JS_FRIEND_API(jsdouble)
-js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj);
-
-JS_END_EXTERN_C
-
-#endif /* jsdate_h___ */
diff --git a/src/extension/script/js/jsdbgapi.c b/src/extension/script/js/jsdbgapi.c
deleted file mode 100644
index 2aa684941..000000000
--- a/src/extension/script/js/jsdbgapi.c
+++ /dev/null
@@ -1,1240 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS debugging API.
- */
-#include "jsstddef.h"
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsclist.h"
-#include "jsapi.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-typedef struct JSTrap {
- JSCList links;
- JSScript *script;
- jsbytecode *pc;
- JSOp op;
- JSTrapHandler handler;
- void *closure;
-} JSTrap;
-
-static JSTrap *
-FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc)
-{
- JSTrap *trap;
-
- for (trap = (JSTrap *)rt->trapList.next;
- trap != (JSTrap *)&rt->trapList;
- trap = (JSTrap *)trap->links.next) {
- if (trap->script == script && trap->pc == pc)
- return trap;
- }
- return NULL;
-}
-
-void
-js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
-{
- JSTrap *trap;
-
- trap = FindTrap(cx->runtime, script, pc);
- if (trap)
- trap->op = op;
- else
- *pc = (jsbytecode)op;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
- JSTrapHandler handler, void *closure)
-{
- JSRuntime *rt;
- JSTrap *trap;
-
- rt = cx->runtime;
- trap = FindTrap(rt, script, pc);
- if (trap) {
- JS_ASSERT(trap->script == script && trap->pc == pc);
- JS_ASSERT(*pc == JSOP_TRAP);
- } else {
- trap = (JSTrap *) JS_malloc(cx, sizeof *trap);
- if (!trap || !js_AddRoot(cx, &trap->closure, "trap->closure")) {
- if (trap)
- JS_free(cx, trap);
- return JS_FALSE;
- }
- JS_APPEND_LINK(&trap->links, &rt->trapList);
- trap->script = script;
- trap->pc = pc;
- trap->op = (JSOp)*pc;
- *pc = JSOP_TRAP;
- }
- trap->handler = handler;
- trap->closure = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSOp)
-JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
-{
- JSTrap *trap;
-
- trap = FindTrap(cx->runtime, script, pc);
- if (!trap) {
- JS_ASSERT(0); /* XXX can't happen */
- return JSOP_LIMIT;
- }
- return trap->op;
-}
-
-static void
-DestroyTrap(JSContext *cx, JSTrap *trap)
-{
- JS_REMOVE_LINK(&trap->links);
- *trap->pc = (jsbytecode)trap->op;
- js_RemoveRoot(cx->runtime, &trap->closure);
- JS_free(cx, trap);
-}
-
-JS_PUBLIC_API(void)
-JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
- JSTrapHandler *handlerp, void **closurep)
-{
- JSTrap *trap;
-
- trap = FindTrap(cx->runtime, script, pc);
- if (handlerp)
- *handlerp = trap ? trap->handler : NULL;
- if (closurep)
- *closurep = trap ? trap->closure : NULL;
- if (trap)
- DestroyTrap(cx, trap);
-}
-
-JS_PUBLIC_API(void)
-JS_ClearScriptTraps(JSContext *cx, JSScript *script)
-{
- JSRuntime *rt;
- JSTrap *trap, *next;
-
- rt = cx->runtime;
- for (trap = (JSTrap *)rt->trapList.next;
- trap != (JSTrap *)&rt->trapList;
- trap = next) {
- next = (JSTrap *)trap->links.next;
- if (trap->script == script)
- DestroyTrap(cx, trap);
- }
-}
-
-JS_PUBLIC_API(void)
-JS_ClearAllTraps(JSContext *cx)
-{
- JSRuntime *rt;
- JSTrap *trap, *next;
-
- rt = cx->runtime;
- for (trap = (JSTrap *)rt->trapList.next;
- trap != (JSTrap *)&rt->trapList;
- trap = next) {
- next = (JSTrap *)trap->links.next;
- DestroyTrap(cx, trap);
- }
-}
-
-JS_PUBLIC_API(JSTrapStatus)
-JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
-{
- JSTrap *trap;
- JSTrapStatus status;
- jsint op;
-
- trap = FindTrap(cx->runtime, script, pc);
- if (!trap) {
- JS_ASSERT(0); /* XXX can't happen */
- return JSTRAP_ERROR;
- }
- /*
- * It's important that we not use 'trap->' after calling the callback --
- * the callback might remove the trap!
- */
- op = (jsint)trap->op;
- status = trap->handler(cx, script, pc, rval, trap->closure);
- if (status == JSTRAP_CONTINUE) {
- /* By convention, return the true op to the interpreter in rval. */
- *rval = INT_TO_JSVAL(op);
- }
- return status;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
-{
- rt->interruptHandler = handler;
- rt->interruptHandlerData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
-{
- if (handlerp)
- *handlerp = (JSTrapHandler)rt->interruptHandler;
- if (closurep)
- *closurep = rt->interruptHandlerData;
- rt->interruptHandler = 0;
- rt->interruptHandlerData = 0;
- return JS_TRUE;
-}
-
-/************************************************************************/
-
-typedef struct JSWatchPoint {
- JSCList links;
- JSObject *object; /* weak link, see js_FinalizeObject */
- JSScopeProperty *sprop;
- JSPropertyOp setter;
- JSWatchPointHandler handler;
- void *closure;
- jsrefcount nrefs;
-} JSWatchPoint;
-
-#define HoldWatchPoint(wp) ((wp)->nrefs++)
-
-static JSBool
-DropWatchPoint(JSContext *cx, JSWatchPoint *wp)
-{
- JSScopeProperty *sprop;
-
- if (--wp->nrefs != 0)
- return JS_TRUE;
-
- /*
- * Remove wp from the list, then if there are no other watchpoints for
- * wp->sprop in any scope, restore wp->sprop->setter from wp.
- */
- JS_REMOVE_LINK(&wp->links);
- sprop = wp->sprop;
- if (!js_GetWatchedSetter(cx->runtime, NULL, sprop)) {
- sprop = js_ChangeNativePropertyAttrs(cx, wp->object, sprop,
- 0, sprop->attrs,
- sprop->getter, wp->setter);
- if (!sprop)
- return JS_FALSE;
- }
- js_RemoveRoot(cx->runtime, &wp->closure);
- JS_free(cx, wp);
- return JS_TRUE;
-}
-
-void
-js_MarkWatchPoints(JSRuntime *rt)
-{
- JSWatchPoint *wp;
-
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = (JSWatchPoint *)wp->links.next) {
- MARK_SCOPE_PROPERTY(wp->sprop);
- }
-}
-
-static JSWatchPoint *
-FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
-{
- JSWatchPoint *wp;
-
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = (JSWatchPoint *)wp->links.next) {
- if (wp->object == scope->object && wp->sprop->id == id)
- return wp;
- }
- return NULL;
-}
-
-JSScopeProperty *
-js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
-{
- JSWatchPoint *wp;
-
- wp = FindWatchPoint(rt, scope, id);
- if (!wp)
- return NULL;
- return wp->sprop;
-}
-
-JSPropertyOp
-js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
- const JSScopeProperty *sprop)
-{
- JSWatchPoint *wp;
-
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = (JSWatchPoint *)wp->links.next) {
- if ((!scope || wp->object == scope->object) && wp->sprop == sprop)
- return wp->setter;
- }
- return NULL;
-}
-
-JSBool JS_DLL_CALLBACK
-js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSRuntime *rt;
- JSWatchPoint *wp;
- JSScopeProperty *sprop;
- jsval userid;
- JSScope *scope;
- JSBool ok;
-
- rt = cx->runtime;
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = (JSWatchPoint *)wp->links.next) {
- sprop = wp->sprop;
- if (wp->object == obj && SPROP_USERID(sprop) == id) {
- JS_LOCK_OBJ(cx, obj);
- userid = SPROP_USERID(sprop);
- scope = OBJ_SCOPE(obj);
- JS_UNLOCK_OBJ(cx, obj);
- HoldWatchPoint(wp);
- ok = wp->handler(cx, obj, userid,
- SPROP_HAS_VALID_SLOT(sprop, scope)
- ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot)
- : JSVAL_VOID,
- vp, wp->closure);
- if (ok) {
- /*
- * Create pseudo-frame for call to setter so that any
- * stack-walking security code in the setter will correctly
- * identify the guilty party.
- */
- JSObject *funobj = (JSObject *) wp->closure;
- JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj);
- JSStackFrame frame;
-
- memset(&frame, 0, sizeof(frame));
- frame.script = fun->script;
- frame.fun = fun;
- frame.down = cx->fp;
- cx->fp = &frame;
- ok = !wp->setter ||
- ((sprop->attrs & JSPROP_SETTER)
- ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),
- 1, vp, vp)
- : wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp));
- cx->fp = frame.down;
- }
- return DropWatchPoint(cx, wp);
- }
- }
- JS_ASSERT(0); /* XXX can't happen */
- return JS_FALSE;
-}
-
-JSBool JS_DLL_CALLBACK
-js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSObject *funobj;
- JSFunction *wrapper;
- jsval userid;
-
- funobj = JSVAL_TO_OBJECT(argv[-2]);
- wrapper = (JSFunction *) JS_GetPrivate(cx, funobj);
- userid = ATOM_KEY(wrapper->atom);
- *rval = argv[0];
- return js_watch_set(cx, obj, userid, rval);
-}
-
-JSPropertyOp
-js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
-{
- JSAtom *atom;
- JSFunction *wrapper;
-
- if (!(attrs & JSPROP_SETTER))
- return &js_watch_set; /* & to silence schoolmarmish MSVC */
-
- if (!JSVAL_IS_INT(id)) {
- atom = (JSAtom *)id;
- } else {
- atom = js_AtomizeInt(cx, JSVAL_TO_INT(id), 0);
- if (!atom)
- return NULL;
- }
- wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0,
- OBJ_GET_PARENT(cx, (JSObject *)setter),
- atom);
- if (!wrapper)
- return NULL;
- return (JSPropertyOp) wrapper->object;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
- JSWatchPointHandler handler, void *closure)
-{
- JSAtom *atom;
- jsid propid;
- JSObject *pobj;
- JSScopeProperty *sprop;
- JSRuntime *rt;
- JSWatchPoint *wp;
- JSPropertyOp watcher;
-
- if (!OBJ_IS_NATIVE(obj)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
- OBJ_GET_CLASS(cx, obj)->name);
- return JS_FALSE;
- }
-
- if (JSVAL_IS_INT(id)) {
- propid = (jsid)id;
- atom = NULL;
- } else {
- atom = js_ValueToStringAtom(cx, id);
- if (!atom)
- return JS_FALSE;
- propid = (jsid)atom;
- }
-
- if (!js_LookupProperty(cx, obj, propid, &pobj, (JSProperty **)&sprop))
- return JS_FALSE;
- rt = cx->runtime;
- if (!sprop) {
- /* Check for a deleted symbol watchpoint, which holds its property. */
- sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
- if (!sprop) {
- /* Make a new property in obj so we can watch for the first set. */
- if (!js_DefineProperty(cx, obj, propid, JSVAL_VOID,
- NULL, NULL, JSPROP_ENUMERATE,
- (JSProperty **)&sprop)) {
- sprop = NULL;
- }
- }
- } else if (pobj != obj) {
- /* Clone the prototype property so we can watch the right object. */
- jsval value;
- JSPropertyOp getter, setter;
- uintN attrs;
-
- if (OBJ_IS_NATIVE(pobj)) {
- value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))
- ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
- : JSVAL_VOID;
- getter = sprop->getter;
- setter = sprop->setter;
- attrs = sprop->attrs;
- } else {
- if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) {
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- return JS_FALSE;
- }
- getter = setter = JS_PropertyStub;
- attrs = JSPROP_ENUMERATE;
- }
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
-
- if (!js_DefineProperty(cx, obj, propid, value, getter, setter, attrs,
- (JSProperty **)&sprop)) {
- sprop = NULL;
- }
- }
- if (!sprop)
- return JS_FALSE;
-
- wp = FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
- if (!wp) {
- watcher = js_WrapWatchedSetter(cx, propid, sprop->attrs, sprop->setter);
- if (!watcher)
- return JS_FALSE;
-
- wp = (JSWatchPoint *) JS_malloc(cx, sizeof *wp);
- if (!wp)
- return JS_FALSE;
- wp->handler = NULL;
- wp->closure = NULL;
- if (!js_AddRoot(cx, &wp->closure, "wp->closure")) {
- JS_free(cx, wp);
- return JS_FALSE;
- }
- JS_APPEND_LINK(&wp->links, &rt->watchPointList);
- wp->object = obj;
- wp->sprop = sprop;
- JS_ASSERT(sprop->setter != js_watch_set);
- wp->setter = sprop->setter;
- wp->nrefs = 1;
- sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, 0, sprop->attrs,
- sprop->getter, watcher);
- if (!sprop)
- return DropWatchPoint(cx, wp);
- }
- wp->handler = handler;
- wp->closure = closure;
- OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
- JSWatchPointHandler *handlerp, void **closurep)
-{
- JSRuntime *rt;
- JSWatchPoint *wp;
-
- rt = cx->runtime;
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = (JSWatchPoint *)wp->links.next) {
- if (wp->object == obj && SPROP_USERID(wp->sprop) == id) {
- if (handlerp)
- *handlerp = wp->handler;
- if (closurep)
- *closurep = wp->closure;
- return DropWatchPoint(cx, wp);
- }
- }
- if (handlerp)
- *handlerp = NULL;
- if (closurep)
- *closurep = NULL;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
-{
- JSRuntime *rt;
- JSWatchPoint *wp, *next;
-
- rt = cx->runtime;
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = next) {
- next = (JSWatchPoint *)wp->links.next;
- if (wp->object == obj && !DropWatchPoint(cx, wp))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_ClearAllWatchPoints(JSContext *cx)
-{
- JSRuntime *rt;
- JSWatchPoint *wp, *next;
-
- rt = cx->runtime;
- for (wp = (JSWatchPoint *)rt->watchPointList.next;
- wp != (JSWatchPoint *)&rt->watchPointList;
- wp = next) {
- next = (JSWatchPoint *)wp->links.next;
- if (!DropWatchPoint(cx, wp))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(uintN)
-JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
-{
- return js_PCToLineNumber(cx, script, pc);
-}
-
-JS_PUBLIC_API(jsbytecode *)
-JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno)
-{
- return js_LineNumberToPC(script, lineno);
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
-{
- return fun->script;
-}
-
-JS_PUBLIC_API(JSPrincipals *)
-JS_GetScriptPrincipals(JSContext *cx, JSScript *script)
-{
- return script->principals;
-}
-
-/************************************************************************/
-
-/*
- * Stack Frame Iterator
- */
-JS_PUBLIC_API(JSStackFrame *)
-JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp)
-{
- *iteratorp = (*iteratorp == NULL) ? cx->fp : (*iteratorp)->down;
- return *iteratorp;
-}
-
-JS_PUBLIC_API(JSScript *)
-JS_GetFrameScript(JSContext *cx, JSStackFrame *fp)
-{
- return fp->script;
-}
-
-JS_PUBLIC_API(jsbytecode *)
-JS_GetFramePC(JSContext *cx, JSStackFrame *fp)
-{
- return fp->pc;
-}
-
-JS_PUBLIC_API(JSStackFrame *)
-JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
-{
- if (!fp)
- fp = cx->fp;
- while ((fp = fp->down) != NULL) {
- if (fp->script)
- return fp;
- }
- return NULL;
-}
-
-JS_PUBLIC_API(JSPrincipals *)
-JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
-{
- if (fp->fun && cx->findObjectPrincipals) {
- JSObject *callee = JSVAL_TO_OBJECT(fp->argv[-2]);
-
- if (fp->fun->object != callee)
- return cx->findObjectPrincipals(cx, callee);
- /* FALL THROUGH */
- }
- if (fp->script)
- return fp->script->principals;
- return NULL;
-}
-
-JS_PUBLIC_API(JSPrincipals *)
-JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
-{
- if (cx->findObjectPrincipals)
- return cx->findObjectPrincipals(cx, JSVAL_TO_OBJECT(fp->argv[-2]));
- if (!caller)
- return NULL;
- return JS_StackFramePrincipals(cx, caller);
-}
-
-JS_PUBLIC_API(void *)
-JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
-{
- if (fp->annotation && fp->script) {
- JSPrincipals *principals = JS_StackFramePrincipals(cx, fp);
-
- if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
- /*
- * Give out an annotation only if privileges have not been revoked
- * or disabled globally.
- */
- return fp->annotation;
- }
- }
-
- return NULL;
-}
-
-JS_PUBLIC_API(void)
-JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation)
-{
- fp->annotation = annotation;
-}
-
-JS_PUBLIC_API(void *)
-JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp)
-{
- JSPrincipals *principals;
-
- principals = JS_StackFramePrincipals(cx, fp);
- if (!principals)
- return NULL;
- return principals->getPrincipalArray(cx, principals);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
-{
- return !fp->script;
-}
-
-/* this is deprecated, use JS_GetFrameScopeChain instead */
-JS_PUBLIC_API(JSObject *)
-JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
-{
- return fp->scopeChain;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
-{
- /* Force creation of argument and call objects if not yet created */
- (void) JS_GetFrameCallObject(cx, fp);
- return fp->scopeChain;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
-{
- if (! fp->fun)
- return NULL;
-#if JS_HAS_ARGS_OBJECT
- /* Force creation of argument object if not yet created */
- (void) js_GetArgsObject(cx, fp);
-#endif
-#if JS_HAS_CALL_OBJECT
- /*
- * XXX ill-defined: null return here means error was reported, unlike a
- * null returned above or in the #else
- */
- return js_GetCallObject(cx, fp, NULL);
-#else
- return NULL;
-#endif /* JS_HAS_CALL_OBJECT */
-}
-
-
-JS_PUBLIC_API(JSObject *)
-JS_GetFrameThis(JSContext *cx, JSStackFrame *fp)
-{
- return fp->thisp;
-}
-
-JS_PUBLIC_API(JSFunction *)
-JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
-{
- return fp->fun;
-}
-
-JS_PUBLIC_API(JSObject *)
-JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
-{
- return fp->argv && fp->fun ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp)
-{
- return (fp->flags & JSFRAME_CONSTRUCTING) != 0;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
-{
- return (fp->flags & JSFRAME_DEBUGGER) != 0;
-}
-
-JS_PUBLIC_API(jsval)
-JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
-{
- return fp->rval;
-}
-
-JS_PUBLIC_API(void)
-JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
-{
- fp->rval = rval;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(const char *)
-JS_GetScriptFilename(JSContext *cx, JSScript *script)
-{
- return script->filename;
-}
-
-JS_PUBLIC_API(uintN)
-JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
-{
- return script->lineno;
-}
-
-JS_PUBLIC_API(uintN)
-JS_GetScriptLineExtent(JSContext *cx, JSScript *script)
-{
- return js_GetScriptLineExtent(script);
-}
-
-JS_PUBLIC_API(JSVersion)
-JS_GetScriptVersion(JSContext *cx, JSScript *script)
-{
- return script->version;
-}
-
-/***************************************************************************/
-
-JS_PUBLIC_API(void)
-JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
-{
- rt->newScriptHook = hook;
- rt->newScriptHookData = callerdata;
-}
-
-JS_PUBLIC_API(void)
-JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
- void *callerdata)
-{
- rt->destroyScriptHook = hook;
- rt->destroyScriptHookData = callerdata;
-}
-
-/***************************************************************************/
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
- const jschar *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- uint32 flags;
- JSScript *script;
- JSBool ok;
-
- /*
- * XXX Hack around ancient compiler API to propagate the JSFRAME_SPECIAL
- * flags to the code generator (see js_EmitTree's TOK_SEMI case).
- */
- flags = fp->flags;
- fp->flags |= JSFRAME_DEBUGGER | JSFRAME_EVAL;
- script = JS_CompileUCScriptForPrincipals(cx, fp->scopeChain,
- JS_StackFramePrincipals(cx, fp),
- bytes, length, filename, lineno);
- fp->flags = flags;
- if (!script)
- return JS_FALSE;
-
- ok = js_Execute(cx, fp->scopeChain, script, fp,
- JSFRAME_DEBUGGER | JSFRAME_EVAL, rval);
- js_DestroyScript(cx, script);
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval)
-{
- jschar *chars;
- JSBool ok;
-
- chars = js_InflateString(cx, bytes, length);
- if (!chars)
- return JS_FALSE;
- ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
- rval);
- JS_free(cx, chars);
-
- return ok;
-}
-
-/************************************************************************/
-
-/* XXXbe this all needs to be reworked to avoid requiring JSScope types. */
-
-JS_PUBLIC_API(JSScopeProperty *)
-JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
-{
- JSScopeProperty *sprop;
- JSScope *scope;
-
- sprop = *iteratorp;
- scope = OBJ_SCOPE(obj);
-
- /* XXXbe minor(?) incompatibility: iterate in reverse definition order */
- if (!sprop) {
- sprop = SCOPE_LAST_PROP(scope);
- } else {
- while ((sprop = sprop->parent) != NULL) {
- if (!SCOPE_HAD_MIDDLE_DELETE(scope))
- break;
- if (SCOPE_HAS_PROPERTY(scope, sprop))
- break;
- }
- }
- *iteratorp = sprop;
- return sprop;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
- JSPropertyDesc *pd)
-{
- JSPropertyOp getter;
- JSScope *scope;
- JSScopeProperty *aprop;
- jsval lastException;
- JSBool wasThrowing;
-
- pd->id = ID_TO_VALUE(sprop->id);
-
- wasThrowing = cx->throwing;
- if (wasThrowing) {
- lastException = cx->exception;
- if (JSVAL_IS_GCTHING(lastException) &&
- !js_AddRoot(cx, &lastException, "lastException")) {
- return JS_FALSE;
- }
- cx->throwing = JS_FALSE;
- }
-
- if (!js_GetProperty(cx, obj, sprop->id, &pd->value)) {
- if (!cx->throwing) {
- pd->flags = JSPD_ERROR;
- pd->value = JSVAL_VOID;
- } else {
- pd->flags = JSPD_EXCEPTION;
- pd->value = cx->exception;
- }
- } else {
- pd->flags = 0;
- }
-
- cx->throwing = wasThrowing;
- if (wasThrowing) {
- cx->exception = lastException;
- if (JSVAL_IS_GCTHING(lastException))
- js_RemoveRoot(cx->runtime, &lastException);
- }
-
- getter = sprop->getter;
- pd->flags |= ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
- | ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0)
- | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
-#if JS_HAS_CALL_OBJECT
- | ((getter == js_GetCallVariable) ? JSPD_VARIABLE : 0)
-#endif /* JS_HAS_CALL_OBJECT */
- | ((getter == js_GetArgument) ? JSPD_ARGUMENT : 0)
- | ((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 &&
- getter == js_CallClass.getProperty) {
- /*
- * Property of a heavyweight function's variable object having the
- * class-default getter. It's either an argument if permanent, or a
- * nested function if impermanent. Local variables have a special
- * getter (js_GetCallVariable, tested above) and setter, and not the
- * class default.
- */
- pd->flags |= (sprop->attrs & JSPROP_PERMANENT)
- ? JSPD_ARGUMENT
- : JSPD_VARIABLE;
- }
-#endif /* JS_HAS_CALL_OBJECT */
- pd->spare = 0;
- pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
- ? sprop->shortid
- : 0;
- pd->alias = JSVAL_VOID;
- scope = OBJ_SCOPE(obj);
- if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
- for (aprop = SCOPE_LAST_PROP(scope); aprop; aprop = aprop->parent) {
- if (aprop != sprop && aprop->slot == sprop->slot) {
- pd->alias = ID_TO_VALUE(aprop->id);
- break;
- }
- }
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
-{
- JSClass *clasp;
- JSScope *scope;
- uint32 i, n;
- JSPropertyDesc *pd;
- JSScopeProperty *sprop;
-
- clasp = OBJ_GET_CLASS(cx, obj);
- if (!OBJ_IS_NATIVE(obj) || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
- return JS_FALSE;
- }
- if (!clasp->enumerate(cx, obj))
- return JS_FALSE;
-
- /* have no props, or object's scope has not mutated from that of proto */
- scope = OBJ_SCOPE(obj);
- if (scope->object != obj || scope->entryCount == 0) {
- pda->length = 0;
- pda->array = NULL;
- return JS_TRUE;
- }
-
- n = scope->entryCount;
- if (n > scope->map.nslots)
- n = scope->map.nslots;
- pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc));
- if (!pd)
- return JS_FALSE;
- i = 0;
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
- continue;
- if (!js_AddRoot(cx, &pd[i].id, NULL))
- goto bad;
- if (!js_AddRoot(cx, &pd[i].value, NULL))
- goto bad;
- if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i]))
- goto bad;
- if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
- goto bad;
- if (++i == n)
- break;
- }
- pda->length = i;
- pda->array = pd;
- return JS_TRUE;
-
-bad:
- pda->length = i + 1;
- pda->array = pd;
- JS_PutPropertyDescArray(cx, pda);
- return JS_FALSE;
-}
-
-JS_PUBLIC_API(void)
-JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
-{
- JSPropertyDesc *pd;
- uint32 i;
-
- pd = pda->array;
- for (i = 0; i < pda->length; i++) {
- js_RemoveRoot(cx->runtime, &pd[i].id);
- js_RemoveRoot(cx->runtime, &pd[i].value);
- if (pd[i].flags & JSPD_ALIAS)
- js_RemoveRoot(cx->runtime, &pd[i].alias);
- }
- JS_free(cx, pd);
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(JSBool)
-JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
-{
- rt->debuggerHandler = handler;
- rt->debuggerHandlerData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
-{
- rt->sourceHandler = handler;
- rt->sourceHandlerData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
-{
- rt->executeHook = hook;
- rt->executeHookData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
-{
- rt->callHook = hook;
- rt->callHookData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
-{
- rt->objectHook = hook;
- rt->objectHookData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
-{
- rt->throwHook = hook;
- rt->throwHookData = closure;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
-{
- rt->debugErrorHook = hook;
- rt->debugErrorHookData = closure;
- return JS_TRUE;
-}
-
-/************************************************************************/
-
-JS_PUBLIC_API(size_t)
-JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
-{
- size_t nbytes;
- JSScope *scope;
-
- nbytes = sizeof *obj + obj->map->nslots * sizeof obj->slots[0];
- if (OBJ_IS_NATIVE(obj)) {
- scope = OBJ_SCOPE(obj);
- if (scope->object == obj) {
- nbytes += sizeof *scope;
- nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);
- }
- }
- return nbytes;
-}
-
-static size_t
-GetAtomTotalSize(JSContext *cx, JSAtom *atom)
-{
- size_t nbytes;
-
- nbytes = sizeof *atom;
- if (ATOM_IS_STRING(atom)) {
- nbytes += sizeof(JSString);
- nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar);
- } else if (ATOM_IS_DOUBLE(atom)) {
- nbytes += sizeof(jsdouble);
- } else if (ATOM_IS_OBJECT(atom)) {
- nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom));
- }
- return nbytes;
-}
-
-JS_PUBLIC_API(size_t)
-JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
-{
- size_t nbytes, obytes;
- JSObject *obj;
- JSAtom *atom;
-
- nbytes = sizeof *fun;
- JS_ASSERT(fun->nrefs);
- obj = fun->object;
- if (obj) {
- obytes = JS_GetObjectTotalSize(cx, obj);
- if (fun->nrefs > 1)
- obytes = JS_HOWMANY(obytes, fun->nrefs);
- nbytes += obytes;
- }
- if (fun->script)
- nbytes += JS_GetScriptTotalSize(cx, fun->script);
- atom = fun->atom;
- if (atom)
- nbytes += GetAtomTotalSize(cx, atom);
- return nbytes;
-}
-
-#include "jsemit.h"
-
-JS_PUBLIC_API(size_t)
-JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
-{
- size_t nbytes, pbytes;
- JSObject *obj;
- jsatomid i;
- jssrcnote *sn, *notes;
- JSTryNote *tn, *tnotes;
- JSPrincipals *principals;
-
- nbytes = sizeof *script;
- obj = script->object;
- if (obj)
- nbytes += JS_GetObjectTotalSize(cx, obj);
-
- nbytes += script->length * sizeof script->code[0];
- nbytes += script->atomMap.length * sizeof script->atomMap.vector[0];
- for (i = 0; i < script->atomMap.length; i++)
- nbytes += GetAtomTotalSize(cx, script->atomMap.vector[i]);
-
- if (script->filename)
- nbytes += strlen(script->filename) + 1;
-
- notes = SCRIPT_NOTES(script);
- for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
- continue;
- nbytes += (sn - notes + 1) * sizeof *sn;
-
- tnotes = script->trynotes;
- if (tnotes) {
- for (tn = tnotes; tn->catchStart; tn++)
- continue;
- nbytes += (tn - tnotes + 1) * sizeof *tn;
- }
-
- principals = script->principals;
- if (principals) {
- JS_ASSERT(principals->refcount);
- pbytes = sizeof *principals;
- if (principals->refcount > 1)
- pbytes = JS_HOWMANY(pbytes, principals->refcount);
- nbytes += pbytes;
- }
-
- return nbytes;
-}
diff --git a/src/extension/script/js/jsdbgapi.h b/src/extension/script/js/jsdbgapi.h
deleted file mode 100644
index 90215a275..000000000
--- a/src/extension/script/js/jsdbgapi.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsdbgapi_h___
-#define jsdbgapi_h___
-/*
- * JS debugger API.
- */
-#include "jsapi.h"
-#include "jsopcode.h"
-#include "jsprvtd.h"
-
-JS_BEGIN_EXTERN_C
-
-extern void
-js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
- JSTrapHandler handler, void *closure);
-
-extern JS_PUBLIC_API(JSOp)
-JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc);
-
-extern JS_PUBLIC_API(void)
-JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
- JSTrapHandler *handlerp, void **closurep);
-
-extern JS_PUBLIC_API(void)
-JS_ClearScriptTraps(JSContext *cx, JSScript *script);
-
-extern JS_PUBLIC_API(void)
-JS_ClearAllTraps(JSContext *cx);
-
-extern JS_PUBLIC_API(JSTrapStatus)
-JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep);
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
- JSWatchPointHandler handler, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
- JSWatchPointHandler *handlerp, void **closurep);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(JSBool)
-JS_ClearAllWatchPoints(JSContext *cx);
-
-#ifdef JS_HAS_OBJ_WATCHPOINT
-/*
- * Hide these non-API function prototypes by testing whether the internal
- * header file "jsconfig.h" has been included.
- */
-extern void
-js_MarkWatchPoints(JSRuntime *rt);
-
-extern JSScopeProperty *
-js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id);
-
-extern JSPropertyOp
-js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
- const JSScopeProperty *sprop);
-
-extern JSBool JS_DLL_CALLBACK
-js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
-
-extern JSBool JS_DLL_CALLBACK
-js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-extern JSPropertyOp
-js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter);
-
-#endif /* JS_HAS_OBJ_WATCHPOINT */
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(uintN)
-JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
-
-extern JS_PUBLIC_API(jsbytecode *)
-JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_GetFunctionScript(JSContext *cx, JSFunction *fun);
-
-extern JS_PUBLIC_API(JSPrincipals *)
-JS_GetScriptPrincipals(JSContext *cx, JSScript *script);
-
-/*
- * Stack Frame Iterator
- *
- * Used to iterate through the JS stack frames to extract
- * information from the frames.
- */
-
-extern JS_PUBLIC_API(JSStackFrame *)
-JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp);
-
-extern JS_PUBLIC_API(JSScript *)
-JS_GetFrameScript(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(jsbytecode *)
-JS_GetFramePC(JSContext *cx, JSStackFrame *fp);
-
-/*
- * Get the closest scripted frame below fp. If fp is null, start from cx->fp.
- */
-extern JS_PUBLIC_API(JSStackFrame *)
-JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
-
-/*
- * Return a weak reference to fp's principals. A null return does not denote
- * an error, it means there are no principals.
- */
-extern JS_PUBLIC_API(JSPrincipals *)
-JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp);
-
-/*
- * Like JS_StackFramePrincipals(cx, caller), but if cx->findObjectPrincipals
- * is non-null, return the object principals for fp's callee function object
- * (fp->argv[-2]), which is eval, Function, or a similar eval-like method.
- * The caller parameter should be the result of JS_GetScriptedCaller(cx, fp).
- *
- * All eval-like methods must use JS_EvalFramePrincipals to acquire a weak
- * reference to the correct principals for the eval call to be secure, given
- * an embedding that calls JS_SetObjectPrincipalsFinder (see jsapi.h).
- */
-extern JS_PUBLIC_API(JSPrincipals *)
-JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller);
-
-extern JS_PUBLIC_API(void *)
-JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(void)
-JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
-
-extern JS_PUBLIC_API(void *)
-JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp);
-
-/* this is deprecated, use JS_GetFrameScopeChain instead */
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFrameObject(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFrameThis(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSFunction *)
-JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSObject *)
-JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp);
-
-/* XXXrginda Initially published with typo */
-#define JS_IsContructorFrame JS_IsConstructorFrame
-extern JS_PUBLIC_API(JSBool)
-JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(jsval)
-JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp);
-
-extern JS_PUBLIC_API(void)
-JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval);
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(const char *)
-JS_GetScriptFilename(JSContext *cx, JSScript *script);
-
-extern JS_PUBLIC_API(uintN)
-JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
-
-extern JS_PUBLIC_API(uintN)
-JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
-
-extern JS_PUBLIC_API(JSVersion)
-JS_GetScriptVersion(JSContext *cx, JSScript *script);
-
-/************************************************************************/
-
-/*
- * Hook setters for script creation and destruction, see jsprvtd.h for the
- * typedefs. These macros provide binary compatibility and newer, shorter
- * synonyms.
- */
-#define JS_SetNewScriptHook JS_SetNewScriptHookProc
-#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc
-
-extern JS_PUBLIC_API(void)
-JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata);
-
-extern JS_PUBLIC_API(void)
-JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
- void *callerdata);
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
- const jschar *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
-JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
- const char *bytes, uintN length,
- const char *filename, uintN lineno,
- jsval *rval);
-
-/************************************************************************/
-
-typedef struct JSPropertyDesc {
- jsval id; /* primary id, a string or int */
- jsval value; /* property value */
- uint8 flags; /* flags, see below */
- uint8 spare; /* unused */
- uint16 slot; /* argument/variable slot */
- jsval alias; /* alias id if JSPD_ALIAS flag */
-} JSPropertyDesc;
-
-#define JSPD_ENUMERATE 0x01 /* visible to for/in loop */
-#define JSPD_READONLY 0x02 /* assignment is error */
-#define JSPD_PERMANENT 0x04 /* property cannot be deleted */
-#define JSPD_ALIAS 0x08 /* property has an alias id */
-#define JSPD_ARGUMENT 0x10 /* argument to function */
-#define JSPD_VARIABLE 0x20 /* local variable in function */
-#define JSPD_EXCEPTION 0x40 /* exception occurred fetching the property, */
- /* value is exception */
-#define JSPD_ERROR 0x80 /* native getter returned JS_FALSE without */
- /* throwing an exception */
-
-typedef struct JSPropertyDescArray {
- uint32 length; /* number of elements in array */
- JSPropertyDesc *array; /* alloc'd by Get, freed by Put */
-} JSPropertyDescArray;
-
-extern JS_PUBLIC_API(JSScopeProperty *)
-JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
- JSPropertyDesc *pd);
-
-extern JS_PUBLIC_API(JSBool)
-JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda);
-
-extern JS_PUBLIC_API(void)
-JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
-JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
-
-/************************************************************************/
-
-extern JS_PUBLIC_API(size_t)
-JS_GetObjectTotalSize(JSContext *cx, JSObject *obj);
-
-extern JS_PUBLIC_API(size_t)
-JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun);
-
-extern JS_PUBLIC_API(size_t)
-JS_GetScriptTotalSize(JSContext *cx, JSScript *script);
-
-JS_END_EXTERN_C
-
-#endif /* jsdbgapi_h___ */
diff --git a/src/extension/script/js/jsdhash.c b/src/extension/script/js/jsdhash.c
deleted file mode 100644
index 736de04ad..000000000
--- a/src/extension/script/js/jsdhash.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla JavaScript code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999-2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Brendan Eich <brendan@mozilla.org> (Original Author)
- * Chris Waterson <waterson@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * Double hashing implementation.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jsbit.h"
-#include "jsdhash.h"
-#include "jsutil.h" /* for JS_ASSERT */
-
-#ifdef JS_DHASHMETER
-# if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan
-# include "nsTraceMalloc.h"
-# endif
-# define METER(x) x
-#else
-# define METER(x) /* nothing */
-#endif
-
-JS_PUBLIC_API(void *)
-JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes)
-{
- return malloc(nbytes);
-}
-
-JS_PUBLIC_API(void)
-JS_DHashFreeTable(JSDHashTable *table, void *ptr)
-{
- free(ptr);
-}
-
-JS_PUBLIC_API(JSDHashNumber)
-JS_DHashStringKey(JSDHashTable *table, const void *key)
-{
- JSDHashNumber h;
- const unsigned char *s;
-
- h = 0;
- for (s = key; *s != '\0'; s++)
- h = (h >> (JS_DHASH_BITS - 4)) ^ (h << 4) ^ *s;
- return h;
-}
-
-JS_PUBLIC_API(const void *)
-JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry)
-{
- JSDHashEntryStub *stub = (JSDHashEntryStub *)entry;
-
- return stub->key;
-}
-
-JS_PUBLIC_API(JSDHashNumber)
-JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key)
-{
- return (JSDHashNumber)key >> 2;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DHashMatchEntryStub(JSDHashTable *table,
- const JSDHashEntryHdr *entry,
- const void *key)
-{
- const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
-
- return stub->key == key;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DHashMatchStringKey(JSDHashTable *table,
- const JSDHashEntryHdr *entry,
- const void *key)
-{
- const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
-
- /* XXX tolerate null keys on account of sloppy Mozilla callers. */
- return stub->key == key ||
- (stub->key && key && strcmp(stub->key, key) == 0);
-}
-
-JS_PUBLIC_API(void)
-JS_DHashMoveEntryStub(JSDHashTable *table,
- const JSDHashEntryHdr *from,
- JSDHashEntryHdr *to)
-{
- memcpy(to, from, table->entrySize);
-}
-
-JS_PUBLIC_API(void)
-JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry)
-{
- memset(entry, 0, table->entrySize);
-}
-
-JS_PUBLIC_API(void)
-JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry)
-{
- const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
-
- free((void *) stub->key);
- memset(entry, 0, table->entrySize);
-}
-
-JS_PUBLIC_API(void)
-JS_DHashFinalizeStub(JSDHashTable *table)
-{
-}
-
-static const JSDHashTableOps stub_ops = {
- JS_DHashAllocTable,
- JS_DHashFreeTable,
- JS_DHashGetKeyStub,
- JS_DHashVoidPtrKeyStub,
- JS_DHashMatchEntryStub,
- JS_DHashMoveEntryStub,
- JS_DHashClearEntryStub,
- JS_DHashFinalizeStub,
- NULL
-};
-
-JS_PUBLIC_API(const JSDHashTableOps *)
-JS_DHashGetStubOps(void)
-{
- return &stub_ops;
-}
-
-JS_PUBLIC_API(JSDHashTable *)
-JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize,
- uint32 capacity)
-{
- JSDHashTable *table;
-
- table = (JSDHashTable *) malloc(sizeof *table);
- if (!table)
- return NULL;
- if (!JS_DHashTableInit(table, ops, data, entrySize, capacity)) {
- free(table);
- return NULL;
- }
- return table;
-}
-
-JS_PUBLIC_API(void)
-JS_DHashTableDestroy(JSDHashTable *table)
-{
- JS_DHashTableFinish(table);
- free(table);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data,
- uint32 entrySize, uint32 capacity)
-{
- int log2;
- uint32 nbytes;
-
-#ifdef DEBUG
- if (entrySize > 10 * sizeof(void *)) {
- fprintf(stderr,
- "jsdhash: for the table at address %p, the given entrySize"
- " of %lu %s favors chaining over double hashing.\n",
- (void *)table,
- (unsigned long) entrySize,
- (entrySize > 16 * sizeof(void*)) ? "definitely" : "probably");
- }
-#endif
-
- table->ops = ops;
- table->data = data;
- if (capacity < JS_DHASH_MIN_SIZE)
- capacity = JS_DHASH_MIN_SIZE;
- log2 = JS_CeilingLog2(capacity);
- capacity = JS_BIT(log2);
- if (capacity >= JS_DHASH_SIZE_LIMIT)
- return JS_FALSE;
- table->hashShift = JS_DHASH_BITS - log2;
- table->maxAlphaFrac = 0xC0; /* .75 */
- table->minAlphaFrac = 0x40; /* .25 */
- table->entrySize = entrySize;
- table->entryCount = table->removedCount = 0;
- table->generation = 0;
- nbytes = capacity * entrySize;
-
- table->entryStore = ops->allocTable(table, nbytes);
- if (!table->entryStore)
- return JS_FALSE;
- memset(table->entryStore, 0, nbytes);
- METER(memset(&table->stats, 0, sizeof table->stats));
- return JS_TRUE;
-}
-
-/*
- * Compute max and min load numbers (entry counts) from table params.
- */
-#define MAX_LOAD(table, size) (((table)->maxAlphaFrac * (size)) >> 8)
-#define MIN_LOAD(table, size) (((table)->minAlphaFrac * (size)) >> 8)
-
-JS_PUBLIC_API(void)
-JS_DHashTableSetAlphaBounds(JSDHashTable *table,
- float maxAlpha,
- float minAlpha)
-{
- uint32 size;
-
- /*
- * Reject obviously insane bounds, rather than trying to guess what the
- * buggy caller intended.
- */
- JS_ASSERT(0.5 <= maxAlpha && maxAlpha < 1 && 0 <= minAlpha);
- if (maxAlpha < 0.5 || 1 <= maxAlpha || minAlpha < 0)
- return;
-
- /*
- * Ensure that at least one entry will always be free. If maxAlpha at
- * minimum size leaves no entries free, reduce maxAlpha based on minimum
- * size and the precision limit of maxAlphaFrac's fixed point format.
- */
- JS_ASSERT(JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) >= 1);
- if (JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) < 1) {
- maxAlpha = (float)
- (JS_DHASH_MIN_SIZE - JS_MAX(JS_DHASH_MIN_SIZE / 256, 1))
- / JS_DHASH_MIN_SIZE;
- }
-
- /*
- * Ensure that minAlpha is strictly less than half maxAlpha. Take care
- * not to truncate an entry's worth of alpha when storing in minAlphaFrac
- * (8-bit fixed point format).
- */
- JS_ASSERT(minAlpha < maxAlpha / 2);
- if (minAlpha >= maxAlpha / 2) {
- size = JS_DHASH_TABLE_SIZE(table);
- minAlpha = (size * maxAlpha - JS_MAX(size / 256, 1)) / (2 * size);
- }
-
- table->maxAlphaFrac = (uint8)(maxAlpha * 256);
- table->minAlphaFrac = (uint8)(minAlpha * 256);
-}
-
-/*
- * Double hashing needs the second hash code to be relatively prime to table
- * size, so we simply make hash2 odd.
- */
-#define HASH1(hash0, shift) ((hash0) >> (shift))
-#define HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1)
-
-/*
- * Reserve keyHash 0 for free entries and 1 for removed-entry sentinels. Note
- * that a removed-entry sentinel need be stored only if the removed entry had
- * a colliding entry added after it. Therefore we can use 1 as the collision
- * flag in addition to the removed-entry sentinel value. Multiplicative hash
- * uses the high order bits of keyHash, so this least-significant reservation
- * should not hurt the hash function's effectiveness much.
- *
- * If you change any of these magic numbers, also update JS_DHASH_ENTRY_IS_LIVE
- * in jsdhash.h. It used to be private to jsdhash.c, but then became public to
- * assist iterator writers who inspect table->entryStore directly.
- */
-#define COLLISION_FLAG ((JSDHashNumber) 1)
-#define MARK_ENTRY_FREE(entry) ((entry)->keyHash = 0)
-#define MARK_ENTRY_REMOVED(entry) ((entry)->keyHash = 1)
-#define ENTRY_IS_REMOVED(entry) ((entry)->keyHash == 1)
-#define ENTRY_IS_LIVE(entry) JS_DHASH_ENTRY_IS_LIVE(entry)
-#define ENSURE_LIVE_KEYHASH(hash0) if (hash0 < 2) hash0 -= 2; else (void)0
-
-/* Match an entry's keyHash against an unstored one computed from a key. */
-#define MATCH_ENTRY_KEYHASH(entry,hash0) \
- (((entry)->keyHash & ~COLLISION_FLAG) == (hash0))
-
-/* Compute the address of the indexed entry in table. */
-#define ADDRESS_ENTRY(table, index) \
- ((JSDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize))
-
-JS_PUBLIC_API(void)
-JS_DHashTableFinish(JSDHashTable *table)
-{
- char *entryAddr, *entryLimit;
- uint32 entrySize;
- JSDHashEntryHdr *entry;
-
-#ifdef DEBUG_XXXbrendan
- static FILE *dumpfp = NULL;
- if (!dumpfp) dumpfp = fopen("/tmp/jsdhash.bigdump", "w");
- if (dumpfp) {
-#ifdef MOZILLA_CLIENT
- NS_TraceStack(1, dumpfp);
-#endif
- JS_DHashTableDumpMeter(table, NULL, dumpfp);
- fputc('\n', dumpfp);
- }
-#endif
-
- /* Call finalize before clearing entries, so it can enumerate them. */
- table->ops->finalize(table);
-
- /* Clear any remaining live entries. */
- entryAddr = table->entryStore;
- entrySize = table->entrySize;
- entryLimit = entryAddr + JS_DHASH_TABLE_SIZE(table) * entrySize;
- while (entryAddr < entryLimit) {
- entry = (JSDHashEntryHdr *)entryAddr;
- if (ENTRY_IS_LIVE(entry)) {
- METER(table->stats.removeEnums++);
- table->ops->clearEntry(table, entry);
- }
- entryAddr += entrySize;
- }
-
- /* Free entry storage last. */
- table->ops->freeTable(table, table->entryStore);
-}
-
-static JSDHashEntryHdr *
-SearchTable(JSDHashTable *table, const void *key, JSDHashNumber keyHash,
- JSDHashOperator op)
-{
- JSDHashNumber hash1, hash2;
- int hashShift, sizeLog2;
- JSDHashEntryHdr *entry, *firstRemoved;
- JSDHashMatchEntry matchEntry;
- uint32 sizeMask;
-
- METER(table->stats.searches++);
- JS_ASSERT(!(keyHash & COLLISION_FLAG));
-
- /* Compute the primary hash address. */
- hashShift = table->hashShift;
- hash1 = HASH1(keyHash, hashShift);
- entry = ADDRESS_ENTRY(table, hash1);
-
- /* Miss: return space for a new entry. */
- if (JS_DHASH_ENTRY_IS_FREE(entry)) {
- METER(table->stats.misses++);
- return entry;
- }
-
- /* Hit: return entry. */
- matchEntry = table->ops->matchEntry;
- if (MATCH_ENTRY_KEYHASH(entry, keyHash) && matchEntry(table, entry, key)) {
- METER(table->stats.hits++);
- return entry;
- }
-
- /* Collision: double hash. */
- sizeLog2 = JS_DHASH_BITS - table->hashShift;
- hash2 = HASH2(keyHash, sizeLog2, hashShift);
- sizeMask = JS_BITMASK(sizeLog2);
-
- /* Save the first removed entry pointer so JS_DHASH_ADD can recycle it. */
- if (ENTRY_IS_REMOVED(entry)) {
- firstRemoved = entry;
- } else {
- firstRemoved = NULL;
- if (op == JS_DHASH_ADD)
- entry->keyHash |= COLLISION_FLAG;
- }
-
- for (;;) {
- METER(table->stats.steps++);
- hash1 -= hash2;
- hash1 &= sizeMask;
-
- entry = ADDRESS_ENTRY(table, hash1);
- if (JS_DHASH_ENTRY_IS_FREE(entry)) {
- METER(table->stats.misses++);
- return (firstRemoved && op == JS_DHASH_ADD) ? firstRemoved : entry;
- }
-
- if (MATCH_ENTRY_KEYHASH(entry, keyHash) &&
- matchEntry(table, entry, key)) {
- METER(table->stats.hits++);
- return entry;
- }
-
- if (ENTRY_IS_REMOVED(entry)) {
- if (!firstRemoved)
- firstRemoved = entry;
- } else {
- if (op == JS_DHASH_ADD)
- entry->keyHash |= COLLISION_FLAG;
- }
- }
-
- /* NOTREACHED */
- return NULL;
-}
-
-static JSBool
-ChangeTable(JSDHashTable *table, int deltaLog2)
-{
- int oldLog2, newLog2;
- uint32 oldCapacity, newCapacity;
- char *newEntryStore, *oldEntryStore, *oldEntryAddr;
- uint32 entrySize, i, nbytes;
- JSDHashEntryHdr *oldEntry, *newEntry;
- JSDHashGetKey getKey;
- JSDHashMoveEntry moveEntry;
-
- /* Look, but don't touch, until we succeed in getting new entry store. */
- oldLog2 = JS_DHASH_BITS - table->hashShift;
- newLog2 = oldLog2 + deltaLog2;
- oldCapacity = JS_BIT(oldLog2);
- newCapacity = JS_BIT(newLog2);
- if (newCapacity >= JS_DHASH_SIZE_LIMIT)
- return JS_FALSE;
- entrySize = table->entrySize;
- nbytes = newCapacity * entrySize;
-
- newEntryStore = table->ops->allocTable(table, nbytes);
- if (!newEntryStore)
- return JS_FALSE;
-
- /* We can't fail from here on, so update table parameters. */
- table->hashShift = JS_DHASH_BITS - newLog2;
- table->removedCount = 0;
- table->generation++;
-
- /* Assign the new entry store to table. */
- memset(newEntryStore, 0, nbytes);
- oldEntryAddr = oldEntryStore = table->entryStore;
- table->entryStore = newEntryStore;
- getKey = table->ops->getKey;
- moveEntry = table->ops->moveEntry;
-
- /* Copy only live entries, leaving removed ones behind. */
- for (i = 0; i < oldCapacity; i++) {
- oldEntry = (JSDHashEntryHdr *)oldEntryAddr;
- if (ENTRY_IS_LIVE(oldEntry)) {
- oldEntry->keyHash &= ~COLLISION_FLAG;
- newEntry = SearchTable(table, getKey(table, oldEntry),
- oldEntry->keyHash, JS_DHASH_ADD);
- JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(newEntry));
- moveEntry(table, oldEntry, newEntry);
- newEntry->keyHash = oldEntry->keyHash;
- }
- oldEntryAddr += entrySize;
- }
-
- table->ops->freeTable(table, oldEntryStore);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSDHashEntryHdr *)
-JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op)
-{
- JSDHashNumber keyHash;
- JSDHashEntryHdr *entry;
- uint32 size;
- int deltaLog2;
-
- keyHash = table->ops->hashKey(table, key);
- keyHash *= JS_DHASH_GOLDEN_RATIO;
-
- /* Avoid 0 and 1 hash codes, they indicate free and removed entries. */
- ENSURE_LIVE_KEYHASH(keyHash);
- keyHash &= ~COLLISION_FLAG;
-
- switch (op) {
- case JS_DHASH_LOOKUP:
- METER(table->stats.lookups++);
- entry = SearchTable(table, key, keyHash, op);
- break;
-
- case JS_DHASH_ADD:
- /*
- * If alpha is >= .75, grow or compress the table. If key is already
- * in the table, we may grow once more than necessary, but only if we
- * are on the edge of being overloaded.
- */
- size = JS_DHASH_TABLE_SIZE(table);
- if (table->entryCount + table->removedCount >= MAX_LOAD(table, size)) {
- /* Compress if a quarter or more of all entries are removed. */
- if (table->removedCount >= size >> 2) {
- METER(table->stats.compresses++);
- deltaLog2 = 0;
- } else {
- METER(table->stats.grows++);
- deltaLog2 = 1;
- }
-
- /*
- * Grow or compress table, returning null if ChangeTable fails and
- * falling through might claim the last free entry.
- */
- if (!ChangeTable(table, deltaLog2) &&
- table->entryCount + table->removedCount == size - 1) {
- METER(table->stats.addFailures++);
- return NULL;
- }
- }
-
- /*
- * Look for entry after possibly growing, so we don't have to add it,
- * then skip it while growing the table and re-add it after.
- */
- entry = SearchTable(table, key, keyHash, op);
- if (!ENTRY_IS_LIVE(entry)) {
- /* Initialize the entry, indicating that it's no longer free. */
- METER(table->stats.addMisses++);
- if (ENTRY_IS_REMOVED(entry)) {
- METER(table->stats.addOverRemoved++);
- table->removedCount--;
- keyHash |= COLLISION_FLAG;
- }
- if (table->ops->initEntry &&
- !table->ops->initEntry(table, entry, key)) {
- /* We haven't claimed entry yet; fail with null return. */
- memset(entry + 1, 0, table->entrySize - sizeof *entry);
- return NULL;
- }
- entry->keyHash = keyHash;
- table->entryCount++;
- }
- METER(else table->stats.addHits++);
- break;
-
- case JS_DHASH_REMOVE:
- entry = SearchTable(table, key, keyHash, op);
- if (ENTRY_IS_LIVE(entry)) {
- /* Clear this entry and mark it as "removed". */
- METER(table->stats.removeHits++);
- JS_DHashTableRawRemove(table, entry);
-
- /* Shrink if alpha is <= .25 and table isn't too small already. */
- size = JS_DHASH_TABLE_SIZE(table);
- if (size > JS_DHASH_MIN_SIZE &&
- table->entryCount <= MIN_LOAD(table, size)) {
- METER(table->stats.shrinks++);
- (void) ChangeTable(table, -1);
- }
- }
- METER(else table->stats.removeMisses++);
- entry = NULL;
- break;
-
- default:
- JS_ASSERT(0);
- entry = NULL;
- }
-
- return entry;
-}
-
-JS_PUBLIC_API(void)
-JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry)
-{
- JSDHashNumber keyHash; /* load first in case clearEntry goofs it */
-
- JS_ASSERT(JS_DHASH_ENTRY_IS_LIVE(entry));
- keyHash = entry->keyHash;
- table->ops->clearEntry(table, entry);
- if (keyHash & COLLISION_FLAG) {
- MARK_ENTRY_REMOVED(entry);
- table->removedCount++;
- } else {
- METER(table->stats.removeFrees++);
- MARK_ENTRY_FREE(entry);
- }
- table->entryCount--;
-}
-
-JS_PUBLIC_API(uint32)
-JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg)
-{
- char *entryAddr, *entryLimit;
- uint32 i, capacity, entrySize;
- JSBool didRemove;
- JSDHashEntryHdr *entry;
- JSDHashOperator op;
-
- entryAddr = table->entryStore;
- entrySize = table->entrySize;
- capacity = JS_DHASH_TABLE_SIZE(table);
- entryLimit = entryAddr + capacity * entrySize;
- i = 0;
- didRemove = JS_FALSE;
- while (entryAddr < entryLimit) {
- entry = (JSDHashEntryHdr *)entryAddr;
- if (ENTRY_IS_LIVE(entry)) {
- op = etor(table, entry, i++, arg);
- if (op & JS_DHASH_REMOVE) {
- METER(table->stats.removeEnums++);
- JS_DHashTableRawRemove(table, entry);
- didRemove = JS_TRUE;
- }
- if (op & JS_DHASH_STOP)
- break;
- }
- entryAddr += entrySize;
- }
-
- /*
- * Shrink or compress if a quarter or more of all entries are removed, or
- * if the table is underloaded according to the configured minimum alpha,
- * and is not minimal-size already. Do this only if we removed above, so
- * non-removing enumerations can count on stable table->entryStore until
- * the next non-lookup-Operate or removing-Enumerate.
- */
- if (didRemove &&
- (table->removedCount >= capacity >> 2 ||
- (capacity > JS_DHASH_MIN_SIZE &&
- table->entryCount <= MIN_LOAD(table, capacity)))) {
- METER(table->stats.enumShrinks++);
- capacity = table->entryCount;
- capacity += capacity >> 1;
- if (capacity < JS_DHASH_MIN_SIZE)
- capacity = JS_DHASH_MIN_SIZE;
- (void) ChangeTable(table,
- JS_CeilingLog2(capacity)
- - (JS_DHASH_BITS - table->hashShift));
- }
- return i;
-}
-
-#ifdef JS_DHASHMETER
-#include <math.h>
-
-JS_PUBLIC_API(void)
-JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp)
-{
- char *entryAddr;
- uint32 entrySize, entryCount;
- int hashShift, sizeLog2;
- uint32 i, tableSize, sizeMask, chainLen, maxChainLen, chainCount;
- JSDHashNumber hash1, hash2, saveHash1, maxChainHash1, maxChainHash2;
- double sqsum, mean, variance, sigma;
- JSDHashEntryHdr *entry, *probe;
-
- entryAddr = table->entryStore;
- entrySize = table->entrySize;
- hashShift = table->hashShift;
- sizeLog2 = JS_DHASH_BITS - hashShift;
- tableSize = JS_DHASH_TABLE_SIZE(table);
- sizeMask = JS_BITMASK(sizeLog2);
- chainCount = maxChainLen = 0;
- hash2 = 0;
- sqsum = 0;
-
- for (i = 0; i < tableSize; i++) {
- entry = (JSDHashEntryHdr *)entryAddr;
- entryAddr += entrySize;
- if (!ENTRY_IS_LIVE(entry))
- continue;
- hash1 = HASH1(entry->keyHash & ~COLLISION_FLAG, hashShift);
- saveHash1 = hash1;
- probe = ADDRESS_ENTRY(table, hash1);
- chainLen = 1;
- if (probe == entry) {
- /* Start of a (possibly unit-length) chain. */
- chainCount++;
- } else {
- hash2 = HASH2(entry->keyHash & ~COLLISION_FLAG, sizeLog2,
- hashShift);
- do {
- chainLen++;
- hash1 -= hash2;
- hash1 &= sizeMask;
- probe = ADDRESS_ENTRY(table, hash1);
- } while (probe != entry);
- }
- sqsum += chainLen * chainLen;
- if (chainLen > maxChainLen) {
- maxChainLen = chainLen;
- maxChainHash1 = saveHash1;
- maxChainHash2 = hash2;
- }
- }
-
- entryCount = table->entryCount;
- if (entryCount && chainCount) {
- mean = (double)entryCount / chainCount;
- variance = chainCount * sqsum - entryCount * entryCount;
- if (variance < 0 || chainCount == 1)
- variance = 0;
- else
- variance /= chainCount * (chainCount - 1);
- sigma = sqrt(variance);
- } else {
- mean = sigma = 0;
- }
-
- fprintf(fp, "Double hashing statistics:\n");
- fprintf(fp, " table size (in entries): %u\n", tableSize);
- fprintf(fp, " number of entries: %u\n", table->entryCount);
- fprintf(fp, " number of removed entries: %u\n", table->removedCount);
- fprintf(fp, " number of searches: %u\n", table->stats.searches);
- fprintf(fp, " number of hits: %u\n", table->stats.hits);
- fprintf(fp, " number of misses: %u\n", table->stats.misses);
- fprintf(fp, " mean steps per search: %g\n", table->stats.searches ?
- (double)table->stats.steps
- / table->stats.searches :
- 0.);
- fprintf(fp, " mean hash chain length: %g\n", mean);
- fprintf(fp, " standard deviation: %g\n", sigma);
- fprintf(fp, " maximum hash chain length: %u\n", maxChainLen);
- fprintf(fp, " number of lookups: %u\n", table->stats.lookups);
- fprintf(fp, " adds that made a new entry: %u\n", table->stats.addMisses);
- fprintf(fp, "adds that recycled removeds: %u\n", table->stats.addOverRemoved);
- fprintf(fp, " adds that found an entry: %u\n", table->stats.addHits);
- fprintf(fp, " add failures: %u\n", table->stats.addFailures);
- fprintf(fp, " useful removes: %u\n", table->stats.removeHits);
- fprintf(fp, " useless removes: %u\n", table->stats.removeMisses);
- fprintf(fp, "removes that freed an entry: %u\n", table->stats.removeFrees);
- fprintf(fp, " removes while enumerating: %u\n", table->stats.removeEnums);
- fprintf(fp, " number of grows: %u\n", table->stats.grows);
- fprintf(fp, " number of shrinks: %u\n", table->stats.shrinks);
- fprintf(fp, " number of compresses: %u\n", table->stats.compresses);
- fprintf(fp, "number of enumerate shrinks: %u\n", table->stats.enumShrinks);
-
- if (dump && maxChainLen && hash2) {
- fputs("Maximum hash chain:\n", fp);
- hash1 = maxChainHash1;
- hash2 = maxChainHash2;
- entry = ADDRESS_ENTRY(table, hash1);
- i = 0;
- do {
- if (dump(table, entry, i++, fp) != JS_DHASH_NEXT)
- break;
- hash1 -= hash2;
- hash1 &= sizeMask;
- entry = ADDRESS_ENTRY(table, hash1);
- } while (JS_DHASH_ENTRY_IS_BUSY(entry));
- }
-}
-#endif /* JS_DHASHMETER */
diff --git a/src/extension/script/js/jsdhash.h b/src/extension/script/js/jsdhash.h
deleted file mode 100644
index 39982ce05..000000000
--- a/src/extension/script/js/jsdhash.h
+++ /dev/null
@@ -1,573 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla JavaScript code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999-2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Brendan Eich <brendan@mozilla.org> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsdhash_h___
-#define jsdhash_h___
-/*
- * Double hashing, a la Knuth 6.
- */
-#include "jstypes.h"
-
-JS_BEGIN_EXTERN_C
-
-#ifdef DEBUG_XXXbrendan
-#define JS_DHASHMETER 1
-#endif
-
-/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */
-#undef JS_DHASH_SIZE_LIMIT
-#define JS_DHASH_SIZE_LIMIT JS_BIT(24)
-
-/* Minimum table size, or gross entry count (net is at most .75 loaded). */
-#ifndef JS_DHASH_MIN_SIZE
-#define JS_DHASH_MIN_SIZE 16
-#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0
-#error "JS_DHASH_MIN_SIZE must be a power of two!"
-#endif
-
-/*
- * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio,
- * expressed as a fixed-point 32-bit fraction.
- */
-#define JS_DHASH_BITS 32
-#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U
-
-/* Primitive and forward-struct typedefs. */
-typedef uint32 JSDHashNumber;
-typedef struct JSDHashEntryHdr JSDHashEntryHdr;
-typedef struct JSDHashEntryStub JSDHashEntryStub;
-typedef struct JSDHashTable JSDHashTable;
-typedef struct JSDHashTableOps JSDHashTableOps;
-
-/*
- * Table entry header structure.
- *
- * In order to allow in-line allocation of key and value, we do not declare
- * either here. Instead, the API uses const void *key as a formal parameter,
- * and asks each entry for its key when necessary via a getKey callback, used
- * when growing or shrinking the table. Other callback types are defined
- * below and grouped into the JSDHashTableOps structure, for single static
- * initialization per hash table sub-type.
- *
- * Each hash table sub-type should nest the JSDHashEntryHdr structure at the
- * front of its particular entry type. The keyHash member contains the result
- * of multiplying the hash code returned from the hashKey callback (see below)
- * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0
- * and 1 values. The stored keyHash value is table size invariant, and it is
- * maintained automatically by JS_DHashTableOperate -- users should never set
- * it, and its only uses should be via the entry macros below.
- *
- * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor
- * removed. An entry may be either busy or free; if busy, it may be live or
- * removed. Consumers of this API should not access members of entries that
- * are not live.
- *
- * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries
- * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a
- * non-live, busy (i.e., removed) entry pointer to its caller. See below for
- * more details on JS_DHashTableOperate's calling rules.
- */
-struct JSDHashEntryHdr {
- JSDHashNumber keyHash; /* every entry must begin like this */
-};
-
-#define JS_DHASH_ENTRY_IS_FREE(entry) ((entry)->keyHash == 0)
-#define JS_DHASH_ENTRY_IS_BUSY(entry) (!JS_DHASH_ENTRY_IS_FREE(entry))
-#define JS_DHASH_ENTRY_IS_LIVE(entry) ((entry)->keyHash >= 2)
-
-/*
- * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead)
- * on most architectures, and may be allocated on the stack or within another
- * structure or class (see below for the Init and Finish functions to use).
- *
- * To decide whether to use double hashing vs. chaining, we need to develop a
- * trade-off relation, as follows:
- *
- * Let alpha be the load factor, esize the entry size in words, count the
- * entry count, and pow2 the power-of-two table size in entries.
- *
- * (JSDHashTable overhead) > (JSHashTable overhead)
- * (unused table entry space) > (malloc and .next overhead per entry) +
- * (buckets overhead)
- * (1 - alpha) * esize * pow2 > 2 * count + pow2
- *
- * Notice that alpha is by definition (count / pow2):
- *
- * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2
- * (1 - alpha) * esize > 2 * alpha + 1
- *
- * esize > (1 + 2 * alpha) / (1 - alpha)
- *
- * This assumes both tables must keep keyHash, key, and value for each entry,
- * where key and value point to separately allocated strings or structures.
- * If key and value can be combined into one pointer, then the trade-off is:
- *
- * esize > (1 + 3 * alpha) / (1 - alpha)
- *
- * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type
- * that must be allocated separately and referenced by an entry.value pointer
- * member, and provided key's allocation can be fused with its entry's, then
- * k (the words wasted per entry with chaining) is 4.
- *
- * To see these curves, feed gnuplot input like so:
- *
- * gnuplot> f(x,k) = (1 + k * x) / (1 - x)
- * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4)
- *
- * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4
- * words for chaining to be more space-efficient than double hashing.
- *
- * Solving for alpha helps us decide when to shrink an underloaded table:
- *
- * esize > (1 + k * alpha) / (1 - alpha)
- * esize - alpha * esize > 1 + k * alpha
- * esize - 1 > (k + esize) * alpha
- * (esize - 1) / (k + esize) > alpha
- *
- * alpha < (esize - 1) / (esize + k)
- *
- * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k),
- * assuming esize is not too large (in which case, chaining should probably be
- * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3
- * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5
- * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below.
- *
- * The current implementation uses a configurable lower bound on alpha, which
- * defaults to .25, when deciding to shrink the table (while still respecting
- * JS_DHASH_MIN_SIZE).
- *
- * Note a qualitative difference between chaining and double hashing: under
- * chaining, entry addresses are stable across table shrinks and grows. With
- * double hashing, you can't safely hold an entry pointer and use it after an
- * ADD or REMOVE operation, unless you sample table->generation before adding
- * or removing, and compare the sample after, dereferencing the entry pointer
- * only if table->generation has not changed.
- *
- * The moral of this story: there is no one-size-fits-all hash table scheme,
- * but for small table entry size, and assuming entry address stability is not
- * required, double hashing wins.
- */
-struct JSDHashTable {
- const JSDHashTableOps *ops; /* virtual operations, see below */
- void *data; /* ops- and instance-specific data */
- int16 hashShift; /* multiplicative hash shift */
- uint8 maxAlphaFrac; /* 8-bit fixed point max alpha */
- uint8 minAlphaFrac; /* 8-bit fixed point min alpha */
- uint32 entrySize; /* number of bytes in an entry */
- uint32 entryCount; /* number of entries in table */
- uint32 removedCount; /* removed entry sentinels in table */
- uint32 generation; /* entry storage generation number */
- char *entryStore; /* entry storage */
-#ifdef JS_DHASHMETER
- struct JSDHashStats {
- uint32 searches; /* total number of table searches */
- uint32 steps; /* hash chain links traversed */
- uint32 hits; /* searches that found key */
- uint32 misses; /* searches that didn't find key */
- uint32 lookups; /* number of JS_DHASH_LOOKUPs */
- uint32 addMisses; /* adds that miss, and do work */
- uint32 addOverRemoved; /* adds that recycled a removed entry */
- uint32 addHits; /* adds that hit an existing entry */
- uint32 addFailures; /* out-of-memory during add growth */
- uint32 removeHits; /* removes that hit, and do work */
- uint32 removeMisses; /* useless removes that miss */
- uint32 removeFrees; /* removes that freed entry directly */
- uint32 removeEnums; /* removes done by Enumerate */
- uint32 grows; /* table expansions */
- uint32 shrinks; /* table contractions */
- uint32 compresses; /* table compressions */
- uint32 enumShrinks; /* contractions after Enumerate */
- } stats;
-#endif
-};
-
-/*
- * Size in entries (gross, not net of free and removed sentinels) for table.
- * We store hashShift rather than sizeLog2 to optimize the collision-free case
- * in SearchTable.
- */
-#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift)
-
-/*
- * Table space at entryStore is allocated and freed using these callbacks.
- * The allocator should return null on error only (not if called with nbytes
- * equal to 0; but note that jsdhash.c code will never call with 0 nbytes).
- */
-typedef void *
-(* JS_DLL_CALLBACK JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes);
-
-typedef void
-(* JS_DLL_CALLBACK JSDHashFreeTable) (JSDHashTable *table, void *ptr);
-
-/*
- * When a table grows or shrinks, each entry is queried for its key using this
- * callback. NB: in that event, entry is not in table any longer; it's in the
- * old entryStore vector, which is due to be freed once all entries have been
- * moved via moveEntry callbacks.
- */
-typedef const void *
-(* JS_DLL_CALLBACK JSDHashGetKey) (JSDHashTable *table,
- JSDHashEntryHdr *entry);
-
-/*
- * Compute the hash code for a given key to be looked up, added, or removed
- * from table. A hash code may have any JSDHashNumber value.
- */
-typedef JSDHashNumber
-(* JS_DLL_CALLBACK JSDHashHashKey) (JSDHashTable *table, const void *key);
-
-/*
- * Compare the key identifying entry in table with the provided key parameter.
- * Return JS_TRUE if keys match, JS_FALSE otherwise.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSDHashMatchEntry)(JSDHashTable *table,
- const JSDHashEntryHdr *entry,
- const void *key);
-
-/*
- * Copy the data starting at from to the new entry storage at to. Do not add
- * reference counts for any strong references in the entry, however, as this
- * is a "move" operation: the old entry storage at from will be freed without
- * any reference-decrementing callback shortly.
- */
-typedef void
-(* JS_DLL_CALLBACK JSDHashMoveEntry)(JSDHashTable *table,
- const JSDHashEntryHdr *from,
- JSDHashEntryHdr *to);
-
-/*
- * Clear the entry and drop any strong references it holds. This callback is
- * invoked during a JS_DHASH_REMOVE operation (see below for operation codes),
- * but only if the given key is found in the table.
- */
-typedef void
-(* JS_DLL_CALLBACK JSDHashClearEntry)(JSDHashTable *table,
- JSDHashEntryHdr *entry);
-
-/*
- * Called when a table (whether allocated dynamically by itself, or nested in
- * a larger structure, or allocated on the stack) is finished. This callback
- * allows table->ops-specific code to finalize table->data.
- */
-typedef void
-(* JS_DLL_CALLBACK JSDHashFinalize) (JSDHashTable *table);
-
-/*
- * Initialize a new entry, apart from keyHash. This function is called when
- * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the
- * given key, and must add a new one. At that point, entry->keyHash is not
- * set yet, to avoid claiming the last free entry in a severely overloaded
- * table.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSDHashInitEntry)(JSDHashTable *table,
- JSDHashEntryHdr *entry,
- const void *key);
-
-/*
- * Finally, the "vtable" structure for JSDHashTable. The first eight hooks
- * must be provided by implementations; they're called unconditionally by the
- * generic jsdhash.c code. Hooks after these may be null.
- *
- * Summary of allocation-related hook usage with C++ placement new emphasis:
- * allocTable Allocate raw bytes with malloc, no ctors run.
- * freeTable Free raw bytes with free, no dtors run.
- * initEntry Call placement new using default key-based ctor.
- * Return JS_TRUE on success, JS_FALSE on error.
- * moveEntry Call placement new using copy ctor, run dtor on old
- * entry storage.
- * clearEntry Run dtor on entry.
- * finalize Stub unless table->data was initialized and needs to
- * be finalized.
- *
- * Note the reason why initEntry is optional: the default hooks (stubs) clear
- * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD),
- * the returned entry pointer addresses an entry struct whose keyHash member
- * has been set non-zero, but all other entry members are still clear (null).
- * JS_DHASH_ADD callers can test such members to see whether the entry was
- * newly created by the JS_DHASH_ADD call that just succeeded. If placement
- * new or similar initialization is required, define an initEntry hook. Of
- * course, the clearEntry hook must zero or null appropriately.
- *
- * XXX assumes 0 is null for pointer types.
- */
-struct JSDHashTableOps {
- /* Mandatory hooks. All implementations must provide these. */
- JSDHashAllocTable allocTable;
- JSDHashFreeTable freeTable;
- JSDHashGetKey getKey;
- JSDHashHashKey hashKey;
- JSDHashMatchEntry matchEntry;
- JSDHashMoveEntry moveEntry;
- JSDHashClearEntry clearEntry;
- JSDHashFinalize finalize;
-
- /* Optional hooks start here. If null, these are not called. */
- JSDHashInitEntry initEntry;
-};
-
-/*
- * Default implementations for the above ops.
- */
-extern JS_PUBLIC_API(void *)
-JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes);
-
-extern JS_PUBLIC_API(void)
-JS_DHashFreeTable(JSDHashTable *table, void *ptr);
-
-extern JS_PUBLIC_API(JSDHashNumber)
-JS_DHashStringKey(JSDHashTable *table, const void *key);
-
-/* A minimal entry contains a keyHash header and a void key pointer. */
-struct JSDHashEntryStub {
- JSDHashEntryHdr hdr;
- const void *key;
-};
-
-extern JS_PUBLIC_API(const void *)
-JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry);
-
-extern JS_PUBLIC_API(JSDHashNumber)
-JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DHashMatchEntryStub(JSDHashTable *table,
- const JSDHashEntryHdr *entry,
- const void *key);
-
-extern JS_PUBLIC_API(JSBool)
-JS_DHashMatchStringKey(JSDHashTable *table,
- const JSDHashEntryHdr *entry,
- const void *key);
-
-extern JS_PUBLIC_API(void)
-JS_DHashMoveEntryStub(JSDHashTable *table,
- const JSDHashEntryHdr *from,
- JSDHashEntryHdr *to);
-
-extern JS_PUBLIC_API(void)
-JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry);
-
-extern JS_PUBLIC_API(void)
-JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry);
-
-extern JS_PUBLIC_API(void)
-JS_DHashFinalizeStub(JSDHashTable *table);
-
-/*
- * If you use JSDHashEntryStub or a subclass of it as your entry struct, and
- * if your entries move via memcpy and clear via memset(0), you can use these
- * stub operations.
- */
-extern JS_PUBLIC_API(const JSDHashTableOps *)
-JS_DHashGetStubOps(void);
-
-/*
- * Dynamically allocate a new JSDHashTable using malloc, initialize it using
- * JS_DHashTableInit, and return its address. Return null on malloc failure.
- * Note that the entry storage at table->entryStore will be allocated using
- * the ops->allocTable callback.
- */
-extern JS_PUBLIC_API(JSDHashTable *)
-JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize,
- uint32 capacity);
-
-/*
- * Finalize table's data, free its entry storage (via table->ops->freeTable),
- * and return the memory starting at table to the malloc heap.
- */
-extern JS_PUBLIC_API(void)
-JS_DHashTableDestroy(JSDHashTable *table);
-
-/*
- * Initialize table with ops, data, entrySize, and capacity. Capacity is a
- * guess for the smallest table size at which the table will usually be less
- * than 75% loaded (the table will grow or shrink as needed; capacity serves
- * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE).
- */
-extern JS_PUBLIC_API(JSBool)
-JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data,
- uint32 entrySize, uint32 capacity);
-
-/*
- * Set maximum and minimum alpha for table. The defaults are 0.75 and .25.
- * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if
- * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or
- * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that
- * we don't shrink on the very next remove after growing a table upon adding
- * an entry that brings entryCount past maxAlpha * tableSize.
- */
-JS_PUBLIC_API(void)
-JS_DHashTableSetAlphaBounds(JSDHashTable *table,
- float maxAlpha,
- float minAlpha);
-
-/*
- * Call this macro with k, the number of pointer-sized words wasted per entry
- * under chaining, to compute the minimum alpha at which double hashing still
- * beats chaining.
- */
-#define JS_DHASH_MIN_ALPHA(table, k) \
- ((float)((table)->entrySize / sizeof(void *) - 1) \
- / ((table)->entrySize / sizeof(void *) + (k)))
-
-/*
- * Finalize table's data, free its entry storage using table->ops->freeTable,
- * and leave its members unchanged from their last live values (which leaves
- * pointers dangling). If you want to burn cycles clearing table, it's up to
- * your code to call memset.
- */
-extern JS_PUBLIC_API(void)
-JS_DHashTableFinish(JSDHashTable *table);
-
-/*
- * To consolidate keyHash computation and table grow/shrink code, we use a
- * single entry point for lookup, add, and remove operations. The operation
- * codes are declared here, along with codes returned by JSDHashEnumerator
- * functions, which control JS_DHashTableEnumerate's behavior.
- */
-typedef enum JSDHashOperator {
- JS_DHASH_LOOKUP = 0, /* lookup entry */
- JS_DHASH_ADD = 1, /* add entry */
- JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */
- JS_DHASH_NEXT = 0, /* enumerator says continue */
- JS_DHASH_STOP = 1 /* enumerator says stop */
-} JSDHashOperator;
-
-/*
- * To lookup a key in table, call:
- *
- * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP);
- *
- * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies
- * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found.
- *
- * To add an entry identified by key to table, call:
- *
- * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD);
- *
- * If entry is null upon return, then either the table is severely overloaded,
- * and memory can't be allocated for entry storage via table->ops->allocTable;
- * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may
- * have returned false.
- *
- * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry)
- * is true, and it is up to the caller to initialize the key and value parts
- * of the entry sub-type, if they have not been set already (i.e. if entry was
- * not already in the table, and if the optional initEntry hook was not used).
- *
- * To remove an entry identified by key from table, call:
- *
- * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE);
- *
- * If key's entry is found, it is cleared (via table->ops->clearEntry) and
- * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation
- * returns null unconditionally; you should ignore its return value.
- */
-extern JS_PUBLIC_API(JSDHashEntryHdr *)
-JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op);
-
-/*
- * Remove an entry already accessed via LOOKUP or ADD.
- *
- * NB: this is a "raw" or low-level routine, intended to be used only where
- * the inefficiency of a full JS_DHashTableOperate (which rehashes in order
- * to find the entry given its key) is not tolerable. This function does not
- * shrink the table if it is underloaded. It does not update stats #ifdef
- * JS_DHASHMETER, either.
- */
-extern JS_PUBLIC_API(void)
-JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry);
-
-/*
- * Enumerate entries in table using etor:
- *
- * count = JS_DHashTableEnumerate(table, etor, arg);
- *
- * JS_DHashTableEnumerate calls etor like so:
- *
- * op = etor(table, entry, number, arg);
- *
- * where number is a zero-based ordinal assigned to live entries according to
- * their order in table->entryStore.
- *
- * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT,
- * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via
- * table->ops->clearEntry) and free entry. Then we check whether op contains
- * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries
- * that were enumerated so far. Return the total number of live entries when
- * enumeration completes normally.
- *
- * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it
- * must return JS_DHASH_STOP; otherwise undefined behavior results.
- *
- * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk
- * or compressed after enumeration, but before JS_DHashTableEnumerate returns.
- * Such an enumerator therefore can't safely set aside entry pointers, but an
- * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries
- * aside, e.g., to avoid copying live entries into an array of the entry type.
- * Copying entry pointers is cheaper, and safe so long as the caller of such a
- * "stable" Enumerate doesn't use the set-aside pointers after any call either
- * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might
- * grow or shrink entryStore.
- *
- * If your enumerator wants to remove certain entries, but set aside pointers
- * to other entries that it retains, it can use JS_DHashTableRawRemove on the
- * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if
- * you want to remove entries, but for some reason you do not want entryStore
- * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on
- * the entry being enumerated, rather than returning JS_DHASH_REMOVE.
- */
-typedef JSDHashOperator
-(* JS_DLL_CALLBACK JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr,
- uint32 number, void *arg);
-
-extern JS_PUBLIC_API(uint32)
-JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg);
-
-#ifdef JS_DHASHMETER
-#include <stdio.h>
-
-extern JS_PUBLIC_API(void)
-JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp);
-#endif
-
-JS_END_EXTERN_C
-
-#endif /* jsdhash_h___ */
diff --git a/src/extension/script/js/jsdtoa.c b/src/extension/script/js/jsdtoa.c
deleted file mode 100644
index 2bd163d75..000000000
--- a/src/extension/script/js/jsdtoa.c
+++ /dev/null
@@ -1,3155 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * Portable double to alphanumeric string and back converters.
- */
-#include "jsstddef.h"
-#include "jslibmath.h"
-#include "jstypes.h"
-#include "jsdtoa.h"
-#include "jsprf.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jspubtd.h"
-#include "jsnum.h"
-
-#ifdef JS_THREADSAFE
-#include "prlock.h"
-#endif
-
-/****************************************************************
- *
- * The author of this software is David M. Gay.
- *
- * Copyright (c) 1991 by Lucent Technologies.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- ***************************************************************/
-
-/* Please send bug reports to
- David M. Gay
- Bell Laboratories, Room 2C-463
- 600 Mountain Avenue
- Murray Hill, NJ 07974-0636
- U.S.A.
- dmg@bell-labs.com
- */
-
-/* On a machine with IEEE extended-precision registers, it is
- * necessary to specify double-precision (53-bit) rounding precision
- * before invoking strtod or dtoa. If the machine uses (the equivalent
- * of) Intel 80x87 arithmetic, the call
- * _control87(PC_53, MCW_PC);
- * does this with many compilers. Whether this or another call is
- * appropriate depends on the compiler; for this to work, it may be
- * necessary to #include "float.h" or another system-dependent header
- * file.
- */
-
-/* strtod for IEEE-arithmetic machines.
- *
- * This strtod returns a nearest machine number to the input decimal
- * string (or sets err to JS_DTOA_ERANGE or JS_DTOA_ENOMEM). With IEEE
- * arithmetic, ties are broken by the IEEE round-even rule. Otherwise
- * ties are broken by biased rounding (add half and chop).
- *
- * Inspired loosely by William D. Clinger's paper "How to Read Floating
- * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- *
- * 1. We only require IEEE double-precision
- * arithmetic (not IEEE double-extended).
- * 2. We get by with floating-point arithmetic in a case that
- * Clinger missed -- when we're computing d * 10^n
- * for a small integer d and the integer n is not too
- * much larger than 22 (the maximum integer k for which
- * we can represent 10^k exactly), we may be able to
- * compute (d*10^k) * 10^(e-k) with just one roundoff.
- * 3. Rather than a bit-at-a-time adjustment of the binary
- * result in the hard case, we use floating-point
- * arithmetic to determine the adjustment to within
- * one bit; only in really hard cases do we need to
- * compute a second residual.
- * 4. Because of 3., we don't need a large table of powers of 10
- * for ten-to-e (just some small tables, e.g. of 10^k
- * for 0 <= k <= 22).
- */
-
-/*
- * #define IEEE_8087 for IEEE-arithmetic machines where the least
- * significant byte has the lowest address.
- * #define IEEE_MC68k for IEEE-arithmetic machines where the most
- * significant byte has the lowest address.
- * #define Long int on machines with 32-bit ints and 64-bit longs.
- * #define Sudden_Underflow for IEEE-format machines without gradual
- * underflow (i.e., that flush to zero on underflow).
- * #define No_leftright to omit left-right logic in fast floating-point
- * computation of js_dtoa.
- * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
- * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
- * that use extended-precision instructions to compute rounded
- * products and quotients) with IBM.
- * #define ROUND_BIASED for IEEE-format with biased rounding.
- * #define Inaccurate_Divide for IEEE-format with correctly rounded
- * products but inaccurate quotients, e.g., for Intel i860.
- * #define JS_HAVE_LONG_LONG on machines that have a "long long"
- * integer type (of >= 64 bits). If long long is available and the name is
- * something other than "long long", #define Llong to be the name,
- * and if "unsigned Llong" does not work as an unsigned version of
- * Llong, #define #ULLong to be the corresponding unsigned type.
- * #define Bad_float_h if your system lacks a float.h or if it does not
- * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
- * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
- * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
- * if memory is available and otherwise does something you deem
- * appropriate. If MALLOC is undefined, malloc will be invoked
- * directly -- and assumed always to succeed.
- * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
- * memory allocations from a private pool of memory when possible.
- * When used, the private pool is PRIVATE_MEM bytes long: 2000 bytes,
- * unless #defined to be a different length. This default length
- * suffices to get rid of MALLOC calls except for unusual cases,
- * such as decimal-to-binary conversion of a very long string of
- * digits.
- * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
- * Infinity and NaN (case insensitively). On some systems (e.g.,
- * some HP systems), it may be necessary to #define NAN_WORD0
- * appropriately -- to the most significant word of a quiet NaN.
- * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
- * #define MULTIPLE_THREADS if the system offers preemptively scheduled
- * multiple threads. In this case, you must provide (or suitably
- * #define) two locks, acquired by ACQUIRE_DTOA_LOCK() and released
- * by RELEASE_DTOA_LOCK(). (The second lock, accessed
- * in pow5mult, ensures lazy evaluation of only one copy of high
- * powers of 5; omitting this lock would introduce a small
- * probability of wasting memory, but would otherwise be harmless.)
- * You must also invoke freedtoa(s) to free the value s returned by
- * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
- * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
- * avoids underflows on inputs whose result does not underflow.
- */
-#ifdef IS_LITTLE_ENDIAN
-#define IEEE_8087
-#else
-#define IEEE_MC68k
-#endif
-
-#ifndef Long
-#define Long int32
-#endif
-
-#ifndef ULong
-#define ULong uint32
-#endif
-
-#define Bug(errorMessageString) JS_ASSERT(!errorMessageString)
-
-#include "stdlib.h"
-#include "string.h"
-
-#ifdef MALLOC
-extern void *MALLOC(size_t);
-#else
-#define MALLOC malloc
-#endif
-
-#define Omit_Private_Memory
-/* Private memory currently doesn't work with JS_THREADSAFE */
-#ifndef Omit_Private_Memory
-#ifndef PRIVATE_MEM
-#define PRIVATE_MEM 2000
-#endif
-#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
-static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
-#endif
-
-#ifdef Bad_float_h
-#undef __STDC__
-
-#define DBL_DIG 15
-#define DBL_MAX_10_EXP 308
-#define DBL_MAX_EXP 1024
-#define FLT_RADIX 2
-#define FLT_ROUNDS 1
-#define DBL_MAX 1.7976931348623157e+308
-
-
-
-#ifndef LONG_MAX
-#define LONG_MAX 2147483647
-#endif
-
-#else /* ifndef Bad_float_h */
-#include "float.h"
-/*
- * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function
- * which does not exist on 10.1. We can safely #define it to 1 here
- * to allow 10.2 builds to run on 10.1, since we can't use fesetround()
- * (which does not exist on 10.1 either).
- */
-#if defined(MACOS_DEPLOYMENT_TARGET) && (MACOS_DEPLOYMENT_TARGET < 100200)
-#undef FLT_ROUNDS
-#define FLT_ROUNDS 1
-#endif
-#endif /* Bad_float_h */
-
-#ifndef __MATH_H__
-#include "math.h"
-#endif
-
-#ifndef CONST
-#define CONST const
-#endif
-
-#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
-Exactly one of IEEE_8087 or IEEE_MC68k should be defined.
-#endif
-
-#define word0(x) JSDOUBLE_HI32(x)
-#define set_word0(x, y) JSDOUBLE_SET_HI32(x, y)
-#define word1(x) JSDOUBLE_LO32(x)
-#define set_word1(x, y) JSDOUBLE_SET_LO32(x, y)
-
-#define Storeinc(a,b,c) (*(a)++ = (b) << 16 | (c) & 0xffff)
-
-/* #define P DBL_MANT_DIG */
-/* Ten_pmax = floor(P*log(2)/log(5)) */
-/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
-/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
-/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
-
-#define Exp_shift 20
-#define Exp_shift1 20
-#define Exp_msk1 0x100000
-#define Exp_msk11 0x100000
-#define Exp_mask 0x7ff00000
-#define P 53
-#define Bias 1023
-#define Emin (-1022)
-#define Exp_1 0x3ff00000
-#define Exp_11 0x3ff00000
-#define Ebits 11
-#define Frac_mask 0xfffff
-#define Frac_mask1 0xfffff
-#define Ten_pmax 22
-#define Bletch 0x10
-#define Bndry_mask 0xfffff
-#define Bndry_mask1 0xfffff
-#define LSB 1
-#define Sign_bit 0x80000000
-#define Log2P 1
-#define Tiny0 0
-#define Tiny1 1
-#define Quick_max 14
-#define Int_max 14
-#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
-#ifndef NO_IEEE_Scale
-#define Avoid_Underflow
-#endif
-
-
-
-#ifdef RND_PRODQUOT
-#define rounded_product(a,b) a = rnd_prod(a, b)
-#define rounded_quotient(a,b) a = rnd_quot(a, b)
-extern double rnd_prod(double, double), rnd_quot(double, double);
-#else
-#define rounded_product(a,b) a *= b
-#define rounded_quotient(a,b) a /= b
-#endif
-
-#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
-#define Big1 0xffffffff
-
-#ifndef JS_HAVE_LONG_LONG
-#undef ULLong
-#else /* long long available */
-#ifndef Llong
-#define Llong JSInt64
-#endif
-#ifndef ULLong
-#define ULLong JSUint64
-#endif
-#endif /* JS_HAVE_LONG_LONG */
-
-#ifdef JS_THREADSAFE
-#define MULTIPLE_THREADS
-static PRLock *freelist_lock;
-#define ACQUIRE_DTOA_LOCK() \
- JS_BEGIN_MACRO \
- if (!initialized) \
- InitDtoa(); \
- PR_Lock(freelist_lock); \
- JS_END_MACRO
-#define RELEASE_DTOA_LOCK() PR_Unlock(freelist_lock)
-#else
-#undef MULTIPLE_THREADS
-#define ACQUIRE_DTOA_LOCK() /*nothing*/
-#define RELEASE_DTOA_LOCK() /*nothing*/
-#endif
-
-#define Kmax 15
-
-struct Bigint {
- struct Bigint *next; /* Free list link */
- int32 k; /* lg2(maxwds) */
- int32 maxwds; /* Number of words allocated for x */
- int32 sign; /* Zero if positive, 1 if negative. Ignored by most Bigint routines! */
- int32 wds; /* Actual number of words. If value is nonzero, the most significant word must be nonzero. */
- ULong x[1]; /* wds words of number in little endian order */
-};
-
-#ifdef ENABLE_OOM_TESTING
-/* Out-of-memory testing. Use a good testcase (over and over) and then use
- * these routines to cause a memory failure on every possible Balloc allocation,
- * to make sure that all out-of-memory paths can be followed. See bug 14044.
- */
-
-static int allocationNum; /* which allocation is next? */
-static int desiredFailure; /* which allocation should fail? */
-
-/**
- * js_BigintTestingReset
- *
- * Call at the beginning of a test run to set the allocation failure position.
- * (Set to 0 to just have the engine count allocations without failing.)
- */
-JS_PUBLIC_API(void)
-js_BigintTestingReset(int newFailure)
-{
- allocationNum = 0;
- desiredFailure = newFailure;
-}
-
-/**
- * js_BigintTestingWhere
- *
- * Report the current allocation position. This is really only useful when you
- * want to learn how many allocations a test run has.
- */
-JS_PUBLIC_API(int)
-js_BigintTestingWhere()
-{
- return allocationNum;
-}
-
-
-/*
- * So here's what you do: Set up a fantastic test case that exercises the
- * elements of the code you wish. Set the failure point at 0 and run the test,
- * then get the allocation position. This number is the number of allocations
- * your test makes. Now loop from 1 to that number, setting the failure point
- * at each loop count, and run the test over and over, causing failures at each
- * step. Any memory failure *should* cause a Out-Of-Memory exception; if it
- * doesn't, then there's still an error here.
- */
-#endif
-
-typedef struct Bigint Bigint;
-
-static Bigint *freelist[Kmax+1];
-
-/*
- * Allocate a Bigint with 2^k words.
- * This is not threadsafe. The caller must use thread locks
- */
-static Bigint *Balloc(int32 k)
-{
- int32 x;
- Bigint *rv;
-#ifndef Omit_Private_Memory
- uint32 len;
-#endif
-
-#ifdef ENABLE_OOM_TESTING
- if (++allocationNum == desiredFailure) {
- printf("Forced Failing Allocation number %d\n", allocationNum);
- return NULL;
- }
-#endif
-
- if ((rv = freelist[k]) != NULL)
- freelist[k] = rv->next;
- if (rv == NULL) {
- x = 1 << k;
-#ifdef Omit_Private_Memory
- rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
-#else
- len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
- /sizeof(double);
- if (pmem_next - private_mem + len <= PRIVATE_mem) {
- rv = (Bigint*)pmem_next;
- pmem_next += len;
- }
- else
- rv = (Bigint*)MALLOC(len*sizeof(double));
-#endif
- if (!rv)
- return NULL;
- rv->k = k;
- rv->maxwds = x;
- }
- rv->sign = rv->wds = 0;
- return rv;
-}
-
-static void Bfree(Bigint *v)
-{
- if (v) {
- v->next = freelist[v->k];
- freelist[v->k] = v;
- }
-}
-
-#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
- y->wds*sizeof(Long) + 2*sizeof(int32))
-
-/* Return b*m + a. Deallocate the old b. Both a and m must be between 0 and
- * 65535 inclusive. NOTE: old b is deallocated on memory failure.
- */
-static Bigint *multadd(Bigint *b, int32 m, int32 a)
-{
- int32 i, wds;
-#ifdef ULLong
- ULong *x;
- ULLong carry, y;
-#else
- ULong carry, *x, y;
- ULong xi, z;
-#endif
- Bigint *b1;
-
-#ifdef ENABLE_OOM_TESTING
- if (++allocationNum == desiredFailure) {
- /* Faux allocation, because I'm not getting all of the failure paths
- * without it.
- */
- printf("Forced Failing Allocation number %d\n", allocationNum);
- Bfree(b);
- return NULL;
- }
-#endif
-
- wds = b->wds;
- x = b->x;
- i = 0;
- carry = a;
- do {
-#ifdef ULLong
- y = *x * (ULLong)m + carry;
- carry = y >> 32;
- *x++ = (ULong)(y & 0xffffffffUL);
-#else
- xi = *x;
- y = (xi & 0xffff) * m + carry;
- z = (xi >> 16) * m + (y >> 16);
- carry = z >> 16;
- *x++ = (z << 16) + (y & 0xffff);
-#endif
- }
- while(++i < wds);
- if (carry) {
- if (wds >= b->maxwds) {
- b1 = Balloc(b->k+1);
- if (!b1) {
- Bfree(b);
- return NULL;
- }
- Bcopy(b1, b);
- Bfree(b);
- b = b1;
- }
- b->x[wds++] = (ULong)carry;
- b->wds = wds;
- }
- return b;
-}
-
-static Bigint *s2b(CONST char *s, int32 nd0, int32 nd, ULong y9)
-{
- Bigint *b;
- int32 i, k;
- Long x, y;
-
- x = (nd + 8) / 9;
- for(k = 0, y = 1; x > y; y <<= 1, k++) ;
- b = Balloc(k);
- if (!b)
- return NULL;
- b->x[0] = y9;
- b->wds = 1;
-
- i = 9;
- if (9 < nd0) {
- s += 9;
- do {
- b = multadd(b, 10, *s++ - '0');
- if (!b)
- return NULL;
- } while(++i < nd0);
- s++;
- }
- else
- s += 10;
- for(; i < nd; i++) {
- b = multadd(b, 10, *s++ - '0');
- if (!b)
- return NULL;
- }
- return b;
-}
-
-
-/* Return the number (0 through 32) of most significant zero bits in x. */
-static int32 hi0bits(register ULong x)
-{
- register int32 k = 0;
-
- if (!(x & 0xffff0000)) {
- k = 16;
- x <<= 16;
- }
- if (!(x & 0xff000000)) {
- k += 8;
- x <<= 8;
- }
- if (!(x & 0xf0000000)) {
- k += 4;
- x <<= 4;
- }
- if (!(x & 0xc0000000)) {
- k += 2;
- x <<= 2;
- }
- if (!(x & 0x80000000)) {
- k++;
- if (!(x & 0x40000000))
- return 32;
- }
- return k;
-}
-
-
-/* Return the number (0 through 32) of least significant zero bits in y.
- * Also shift y to the right past these 0 through 32 zeros so that y's
- * least significant bit will be set unless y was originally zero. */
-static int32 lo0bits(ULong *y)
-{
- register int32 k;
- register ULong x = *y;
-
- if (x & 7) {
- if (x & 1)
- return 0;
- if (x & 2) {
- *y = x >> 1;
- return 1;
- }
- *y = x >> 2;
- return 2;
- }
- k = 0;
- if (!(x & 0xffff)) {
- k = 16;
- x >>= 16;
- }
- if (!(x & 0xff)) {
- k += 8;
- x >>= 8;
- }
- if (!(x & 0xf)) {
- k += 4;
- x >>= 4;
- }
- if (!(x & 0x3)) {
- k += 2;
- x >>= 2;
- }
- if (!(x & 1)) {
- k++;
- x >>= 1;
- if (!x & 1)
- return 32;
- }
- *y = x;
- return k;
-}
-
-/* Return a new Bigint with the given integer value, which must be nonnegative. */
-static Bigint *i2b(int32 i)
-{
- Bigint *b;
-
- b = Balloc(1);
- if (!b)
- return NULL;
- b->x[0] = i;
- b->wds = 1;
- return b;
-}
-
-/* Return a newly allocated product of a and b. */
-static Bigint *mult(CONST Bigint *a, CONST Bigint *b)
-{
- CONST Bigint *t;
- Bigint *c;
- int32 k, wa, wb, wc;
- ULong y;
- ULong *xc, *xc0, *xce;
- CONST ULong *x, *xa, *xae, *xb, *xbe;
-#ifdef ULLong
- ULLong carry, z;
-#else
- ULong carry, z;
- ULong z2;
-#endif
-
- if (a->wds < b->wds) {
- t = a;
- a = b;
- b = t;
- }
- k = a->k;
- wa = a->wds;
- wb = b->wds;
- wc = wa + wb;
- if (wc > a->maxwds)
- k++;
- c = Balloc(k);
- if (!c)
- return NULL;
- for(xc = c->x, xce = xc + wc; xc < xce; xc++)
- *xc = 0;
- xa = a->x;
- xae = xa + wa;
- xb = b->x;
- xbe = xb + wb;
- xc0 = c->x;
-#ifdef ULLong
- for(; xb < xbe; xc0++) {
- if ((y = *xb++) != 0) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = *x++ * (ULLong)y + *xc + carry;
- carry = z >> 32;
- *xc++ = (ULong)(z & 0xffffffffUL);
- }
- while(x < xae);
- *xc = (ULong)carry;
- }
- }
-#else
- for(; xb < xbe; xb++, xc0++) {
- if ((y = *xb & 0xffff) != 0) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
- carry = z >> 16;
- z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
- carry = z2 >> 16;
- Storeinc(xc, z2, z);
- }
- while(x < xae);
- *xc = carry;
- }
- if ((y = *xb >> 16) != 0) {
- x = xa;
- xc = xc0;
- carry = 0;
- z2 = *xc;
- do {
- z = (*x & 0xffff) * y + (*xc >> 16) + carry;
- carry = z >> 16;
- Storeinc(xc, z, z2);
- z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
- carry = z2 >> 16;
- }
- while(x < xae);
- *xc = z2;
- }
- }
-#endif
- for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
- c->wds = wc;
- return c;
-}
-
-/*
- * 'p5s' points to a linked list of Bigints that are powers of 5.
- * This list grows on demand, and it can only grow: it won't change
- * in any other way. So if we read 'p5s' or the 'next' field of
- * some Bigint on the list, and it is not NULL, we know it won't
- * change to NULL or some other value. Only when the value of
- * 'p5s' or 'next' is NULL do we need to acquire the lock and add
- * a new Bigint to the list.
- */
-
-static Bigint *p5s;
-
-#ifdef JS_THREADSAFE
-static PRLock *p5s_lock;
-#endif
-
-/* Return b * 5^k. Deallocate the old b. k must be nonnegative. */
-/* NOTE: old b is deallocated on memory failure. */
-static Bigint *pow5mult(Bigint *b, int32 k)
-{
- Bigint *b1, *p5, *p51;
- int32 i;
- static CONST int32 p05[3] = { 5, 25, 125 };
-
- if ((i = k & 3) != 0) {
- b = multadd(b, p05[i-1], 0);
- if (!b)
- return NULL;
- }
-
- if (!(k >>= 2))
- return b;
- if (!(p5 = p5s)) {
-#ifdef JS_THREADSAFE
- /*
- * We take great care to not call i2b() and Bfree()
- * while holding the lock.
- */
- Bigint *wasted_effort = NULL;
- p5 = i2b(625);
- if (!p5) {
- Bfree(b);
- return NULL;
- }
- /* lock and check again */
- PR_Lock(p5s_lock);
- if (!p5s) {
- /* first time */
- p5s = p5;
- p5->next = 0;
- } else {
- /* some other thread just beat us */
- wasted_effort = p5;
- p5 = p5s;
- }
- PR_Unlock(p5s_lock);
- if (wasted_effort) {
- Bfree(wasted_effort);
- }
-#else
- /* first time */
- p5 = p5s = i2b(625);
- if (!p5) {
- Bfree(b);
- return NULL;
- }
- p5->next = 0;
-#endif
- }
- for(;;) {
- if (k & 1) {
- b1 = mult(b, p5);
- Bfree(b);
- if (!b1)
- return NULL;
- b = b1;
- }
- if (!(k >>= 1))
- break;
- if (!(p51 = p5->next)) {
-#ifdef JS_THREADSAFE
- Bigint *wasted_effort = NULL;
- p51 = mult(p5, p5);
- if (!p51) {
- Bfree(b);
- return NULL;
- }
- PR_Lock(p5s_lock);
- if (!p5->next) {
- p5->next = p51;
- p51->next = 0;
- } else {
- wasted_effort = p51;
- p51 = p5->next;
- }
- PR_Unlock(p5s_lock);
- if (wasted_effort) {
- Bfree(wasted_effort);
- }
-#else
- p51 = mult(p5,p5);
- if (!p51) {
- Bfree(b);
- return NULL;
- }
- p51->next = 0;
- p5->next = p51;
-#endif
- }
- p5 = p51;
- }
- return b;
-}
-
-/* Return b * 2^k. Deallocate the old b. k must be nonnegative.
- * NOTE: on memory failure, old b is deallocated. */
-static Bigint *lshift(Bigint *b, int32 k)
-{
- int32 i, k1, n, n1;
- Bigint *b1;
- ULong *x, *x1, *xe, z;
-
- n = k >> 5;
- k1 = b->k;
- n1 = n + b->wds + 1;
- for(i = b->maxwds; n1 > i; i <<= 1)
- k1++;
- b1 = Balloc(k1);
- if (!b1)
- goto done;
- x1 = b1->x;
- for(i = 0; i < n; i++)
- *x1++ = 0;
- x = b->x;
- xe = x + b->wds;
- if (k &= 0x1f) {
- k1 = 32 - k;
- z = 0;
- do {
- *x1++ = *x << k | z;
- z = *x++ >> k1;
- }
- while(x < xe);
- if ((*x1 = z) != 0)
- ++n1;
- }
- else do
- *x1++ = *x++;
- while(x < xe);
- b1->wds = n1 - 1;
-done:
- Bfree(b);
- return b1;
-}
-
-/* Return -1, 0, or 1 depending on whether a<b, a==b, or a>b, respectively. */
-static int32 cmp(Bigint *a, Bigint *b)
-{
- ULong *xa, *xa0, *xb, *xb0;
- int32 i, j;
-
- i = a->wds;
- j = b->wds;
-#ifdef DEBUG
- if (i > 1 && !a->x[i-1])
- Bug("cmp called with a->x[a->wds-1] == 0");
- if (j > 1 && !b->x[j-1])
- Bug("cmp called with b->x[b->wds-1] == 0");
-#endif
- if (i -= j)
- return i;
- xa0 = a->x;
- xa = xa0 + j;
- xb0 = b->x;
- xb = xb0 + j;
- for(;;) {
- if (*--xa != *--xb)
- return *xa < *xb ? -1 : 1;
- if (xa <= xa0)
- break;
- }
- return 0;
-}
-
-static Bigint *diff(Bigint *a, Bigint *b)
-{
- Bigint *c;
- int32 i, wa, wb;
- ULong *xa, *xae, *xb, *xbe, *xc;
-#ifdef ULLong
- ULLong borrow, y;
-#else
- ULong borrow, y;
- ULong z;
-#endif
-
- i = cmp(a,b);
- if (!i) {
- c = Balloc(0);
- if (!c)
- return NULL;
- c->wds = 1;
- c->x[0] = 0;
- return c;
- }
- if (i < 0) {
- c = a;
- a = b;
- b = c;
- i = 1;
- }
- else
- i = 0;
- c = Balloc(a->k);
- if (!c)
- return NULL;
- c->sign = i;
- wa = a->wds;
- xa = a->x;
- xae = xa + wa;
- wb = b->wds;
- xb = b->x;
- xbe = xb + wb;
- xc = c->x;
- borrow = 0;
-#ifdef ULLong
- do {
- y = (ULLong)*xa++ - *xb++ - borrow;
- borrow = y >> 32 & 1UL;
- *xc++ = (ULong)(y & 0xffffffffUL);
- }
- while(xb < xbe);
- while(xa < xae) {
- y = *xa++ - borrow;
- borrow = y >> 32 & 1UL;
- *xc++ = (ULong)(y & 0xffffffffUL);
- }
-#else
- do {
- y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
- borrow = (y & 0x10000) >> 16;
- z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
- borrow = (z & 0x10000) >> 16;
- Storeinc(xc, z, y);
- }
- while(xb < xbe);
- while(xa < xae) {
- y = (*xa & 0xffff) - borrow;
- borrow = (y & 0x10000) >> 16;
- z = (*xa++ >> 16) - borrow;
- borrow = (z & 0x10000) >> 16;
- Storeinc(xc, z, y);
- }
-#endif
- while(!*--xc)
- wa--;
- c->wds = wa;
- return c;
-}
-
-/* Return the absolute difference between x and the adjacent greater-magnitude double number (ignoring exponent overflows). */
-static double ulp(double x)
-{
- register Long L;
- double a;
-
- L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
-#ifndef Sudden_Underflow
- if (L > 0) {
-#endif
- set_word0(a, L);
- set_word1(a, 0);
-#ifndef Sudden_Underflow
- }
- else {
- L = -L >> Exp_shift;
- if (L < Exp_shift) {
- set_word0(a, 0x80000 >> L);
- set_word1(a, 0);
- }
- else {
- set_word0(a, 0);
- L -= Exp_shift;
- set_word1(a, L >= 31 ? 1 : 1 << (31 - L));
- }
- }
-#endif
- return a;
-}
-
-
-static double b2d(Bigint *a, int32 *e)
-{
- ULong *xa, *xa0, w, y, z;
- int32 k;
- double d;
-#define d0 word0(d)
-#define d1 word1(d)
-#define set_d0(x) set_word0(d, x)
-#define set_d1(x) set_word1(d, x)
-
- xa0 = a->x;
- xa = xa0 + a->wds;
- y = *--xa;
-#ifdef DEBUG
- if (!y) Bug("zero y in b2d");
-#endif
- k = hi0bits(y);
- *e = 32 - k;
- if (k < Ebits) {
- set_d0(Exp_1 | y >> (Ebits - k));
- w = xa > xa0 ? *--xa : 0;
- set_d1(y << (32-Ebits + k) | w >> (Ebits - k));
- goto ret_d;
- }
- z = xa > xa0 ? *--xa : 0;
- if (k -= Ebits) {
- set_d0(Exp_1 | y << k | z >> (32 - k));
- y = xa > xa0 ? *--xa : 0;
- set_d1(z << k | y >> (32 - k));
- }
- else {
- set_d0(Exp_1 | y);
- set_d1(z);
- }
- ret_d:
-#undef d0
-#undef d1
-#undef set_d0
-#undef set_d1
- return d;
-}
-
-
-/* Convert d into the form b*2^e, where b is an odd integer. b is the returned
- * Bigint and e is the returned binary exponent. Return the number of significant
- * bits in b in bits. d must be finite and nonzero. */
-static Bigint *d2b(double d, int32 *e, int32 *bits)
-{
- Bigint *b;
- int32 de, i, k;
- ULong *x, y, z;
-#define d0 word0(d)
-#define d1 word1(d)
-#define set_d0(x) set_word0(d, x)
-#define set_d1(x) set_word1(d, x)
-
- b = Balloc(1);
- if (!b)
- return NULL;
- x = b->x;
-
- z = d0 & Frac_mask;
- set_d0(d0 & 0x7fffffff); /* clear sign bit, which we ignore */
-#ifdef Sudden_Underflow
- de = (int32)(d0 >> Exp_shift);
- z |= Exp_msk11;
-#else
- if ((de = (int32)(d0 >> Exp_shift)) != 0)
- z |= Exp_msk1;
-#endif
- if ((y = d1) != 0) {
- if ((k = lo0bits(&y)) != 0) {
- x[0] = y | z << (32 - k);
- z >>= k;
- }
- else
- x[0] = y;
- i = b->wds = (x[1] = z) ? 2 : 1;
- }
- else {
- JS_ASSERT(z);
- k = lo0bits(&z);
- x[0] = z;
- i = b->wds = 1;
- k += 32;
- }
-#ifndef Sudden_Underflow
- if (de) {
-#endif
- *e = de - Bias - (P-1) + k;
- *bits = P - k;
-#ifndef Sudden_Underflow
- }
- else {
- *e = de - Bias - (P-1) + 1 + k;
- *bits = 32*i - hi0bits(x[i-1]);
- }
-#endif
- return b;
-}
-#undef d0
-#undef d1
-#undef set_d0
-#undef set_d1
-
-
-static double ratio(Bigint *a, Bigint *b)
-{
- double da, db;
- int32 k, ka, kb;
-
- da = b2d(a, &ka);
- db = b2d(b, &kb);
- k = ka - kb + 32*(a->wds - b->wds);
- if (k > 0)
- set_word0(da, word0(da) + k*Exp_msk1);
- else {
- k = -k;
- set_word0(db, word0(db) + k*Exp_msk1);
- }
- return da / db;
-}
-
-static CONST double
-tens[] = {
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22
-};
-
-static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
-static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
-#ifdef Avoid_Underflow
- 9007199254740992.e-256
-#else
- 1e-256
-#endif
- };
-/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
-/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
-#define Scale_Bit 0x10
-#define n_bigtens 5
-
-
-#ifdef INFNAN_CHECK
-
-#ifndef NAN_WORD0
-#define NAN_WORD0 0x7ff80000
-#endif
-
-#ifndef NAN_WORD1
-#define NAN_WORD1 0
-#endif
-
-static int match(CONST char **sp, char *t)
-{
- int c, d;
- CONST char *s = *sp;
-
- while(d = *t++) {
- if ((c = *++s) >= 'A' && c <= 'Z')
- c += 'a' - 'A';
- if (c != d)
- return 0;
- }
- *sp = s + 1;
- return 1;
- }
-#endif /* INFNAN_CHECK */
-
-
-#ifdef JS_THREADSAFE
-static JSBool initialized = JS_FALSE;
-
-/* hacked replica of nspr _PR_InitDtoa */
-static void InitDtoa(void)
-{
- freelist_lock = PR_NewLock();
- p5s_lock = PR_NewLock();
- initialized = JS_TRUE;
-}
-#endif
-
-void js_FinishDtoa(void)
-{
- int count;
- Bigint *temp;
-
-#ifdef JS_THREADSAFE
- if (initialized == JS_TRUE) {
- PR_DestroyLock(freelist_lock);
- PR_DestroyLock(p5s_lock);
- initialized = JS_FALSE;
- }
-#endif
-
- /* clear down the freelist array and p5s */
-
- /* static Bigint *freelist[Kmax+1]; */
- for (count = 0; count <= Kmax; count++) {
- Bigint **listp = &freelist[count];
- while ((temp = *listp) != NULL) {
- *listp = temp->next;
- free(temp);
- }
- freelist[count] = NULL;
- }
-
- /* static Bigint *p5s; */
- while (p5s) {
- temp = p5s;
- p5s = p5s->next;
- free(temp);
- }
-}
-
-/* nspr2 watcom bug ifdef omitted */
-
-JS_FRIEND_API(double)
-JS_strtod(CONST char *s00, char **se, int *err)
-{
- int32 scale;
- int32 bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
- e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
- CONST char *s, *s0, *s1;
- double aadj, aadj1, adj, rv, rv0;
- Long L;
- ULong y, z;
- Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
-
- SET_FPU();
-
- *err = 0;
-
- bb = bd = bs = delta = NULL;
- sign = nz0 = nz = 0;
- rv = 0.;
-
- /* Locking for Balloc's shared buffers that will be used in this block */
- ACQUIRE_DTOA_LOCK();
-
- for(s = s00;;s++) switch(*s) {
- case '-':
- sign = 1;
- /* no break */
- case '+':
- if (*++s)
- goto break2;
- /* no break */
- case 0:
- s = s00;
- goto ret;
- case '\t':
- case '\n':
- case '\v':
- case '\f':
- case '\r':
- case ' ':
- continue;
- default:
- goto break2;
- }
-break2:
-
- if (*s == '0') {
- nz0 = 1;
- while(*++s == '0') ;
- if (!*s)
- goto ret;
- }
- s0 = s;
- y = z = 0;
- for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
- if (nd < 9)
- y = 10*y + c - '0';
- else if (nd < 16)
- z = 10*z + c - '0';
- nd0 = nd;
- if (c == '.') {
- c = *++s;
- if (!nd) {
- for(; c == '0'; c = *++s)
- nz++;
- if (c > '0' && c <= '9') {
- s0 = s;
- nf += nz;
- nz = 0;
- goto have_dig;
- }
- goto dig_done;
- }
- for(; c >= '0' && c <= '9'; c = *++s) {
- have_dig:
- nz++;
- if (c -= '0') {
- nf += nz;
- for(i = 1; i < nz; i++)
- if (nd++ < 9)
- y *= 10;
- else if (nd <= DBL_DIG + 1)
- z *= 10;
- if (nd++ < 9)
- y = 10*y + c;
- else if (nd <= DBL_DIG + 1)
- z = 10*z + c;
- nz = 0;
- }
- }
- }
-dig_done:
- e = 0;
- if (c == 'e' || c == 'E') {
- if (!nd && !nz && !nz0) {
- s = s00;
- goto ret;
- }
- s00 = s;
- esign = 0;
- switch(c = *++s) {
- case '-':
- esign = 1;
- case '+':
- c = *++s;
- }
- if (c >= '0' && c <= '9') {
- while(c == '0')
- c = *++s;
- if (c > '0' && c <= '9') {
- L = c - '0';
- s1 = s;
- while((c = *++s) >= '0' && c <= '9')
- L = 10*L + c - '0';
- if (s - s1 > 8 || L > 19999)
- /* Avoid confusion from exponents
- * so large that e might overflow.
- */
- e = 19999; /* safe for 16 bit ints */
- else
- e = (int32)L;
- if (esign)
- e = -e;
- }
- else
- e = 0;
- }
- else
- s = s00;
- }
- if (!nd) {
- if (!nz && !nz0) {
-#ifdef INFNAN_CHECK
- /* Check for Nan and Infinity */
- switch(c) {
- case 'i':
- case 'I':
- if (match(&s,"nfinity")) {
- word0(rv) = 0x7ff00000;
- word1(rv) = 0;
- goto ret;
- }
- break;
- case 'n':
- case 'N':
- if (match(&s, "an")) {
- word0(rv) = NAN_WORD0;
- word1(rv) = NAN_WORD1;
- goto ret;
- }
- }
-#endif /* INFNAN_CHECK */
- s = s00;
- }
- goto ret;
- }
- e1 = e -= nf;
-
- /* Now we have nd0 digits, starting at s0, followed by a
- * decimal point, followed by nd-nd0 digits. The number we're
- * after is the integer represented by those digits times
- * 10**e */
-
- if (!nd0)
- nd0 = nd;
- k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- rv = y;
- if (k > 9)
- rv = tens[k - 9] * rv + z;
- bd0 = 0;
- if (nd <= DBL_DIG
-#ifndef RND_PRODQUOT
- && FLT_ROUNDS == 1
-#endif
- ) {
- if (!e)
- goto ret;
- if (e > 0) {
- if (e <= Ten_pmax) {
- /* rv = */ rounded_product(rv, tens[e]);
- goto ret;
- }
- i = DBL_DIG - nd;
- if (e <= Ten_pmax + i) {
- /* A fancier test would sometimes let us do
- * this for larger i values.
- */
- e -= i;
- rv *= tens[i];
- /* rv = */ rounded_product(rv, tens[e]);
- goto ret;
- }
- }
-#ifndef Inaccurate_Divide
- else if (e >= -Ten_pmax) {
- /* rv = */ rounded_quotient(rv, tens[-e]);
- goto ret;
- }
-#endif
- }
- e1 += nd - k;
-
- scale = 0;
-
- /* Get starting approximation = rv * 10**e1 */
-
- if (e1 > 0) {
- if ((i = e1 & 15) != 0)
- rv *= tens[i];
- if (e1 &= ~15) {
- if (e1 > DBL_MAX_10_EXP) {
- ovfl:
- *err = JS_DTOA_ERANGE;
-#ifdef __STDC__
- rv = HUGE_VAL;
-#else
- /* Can't trust HUGE_VAL */
- word0(rv) = Exp_mask;
- word1(rv) = 0;
-#endif
- if (bd0)
- goto retfree;
- goto ret;
- }
- e1 >>= 4;
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- rv *= bigtens[j];
- /* The last multiplication could overflow. */
- set_word0(rv, word0(rv) - P*Exp_msk1);
- rv *= bigtens[j];
- if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P))
- goto ovfl;
- if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
- /* set to largest number */
- /* (Can't trust DBL_MAX) */
- set_word0(rv, Big0);
- set_word1(rv, Big1);
- }
- else
- set_word0(rv, word0(rv) + P*Exp_msk1);
- }
- }
- else if (e1 < 0) {
- e1 = -e1;
- if ((i = e1 & 15) != 0)
- rv /= tens[i];
- if (e1 &= ~15) {
- e1 >>= 4;
- if (e1 >= 1 << n_bigtens)
- goto undfl;
-#ifdef Avoid_Underflow
- if (e1 & Scale_Bit)
- scale = P;
- for(j = 0; e1 > 0; j++, e1 >>= 1)
- if (e1 & 1)
- rv *= tinytens[j];
- if (scale && (j = P + 1 - ((word0(rv) & Exp_mask)
- >> Exp_shift)) > 0) {
- /* scaled rv is denormal; zap j low bits */
- if (j >= 32) {
- set_word1(rv, 0);
- set_word0(rv, word0(rv) & (0xffffffff << (j-32)));
- if (!word0(rv))
- set_word0(rv, 1);
- }
- else
- set_word1(rv, word1(rv) & (0xffffffff << j));
- }
-#else
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- rv *= tinytens[j];
- /* The last multiplication could underflow. */
- rv0 = rv;
- rv *= tinytens[j];
- if (!rv) {
- rv = 2.*rv0;
- rv *= tinytens[j];
-#endif
- if (!rv) {
- undfl:
- rv = 0.;
- *err = JS_DTOA_ERANGE;
- if (bd0)
- goto retfree;
- goto ret;
- }
-#ifndef Avoid_Underflow
- set_word0(rv, Tiny0);
- set_word1(rv, Tiny1);
- /* The refinement below will clean
- * this approximation up.
- */
- }
-#endif
- }
- }
-
- /* Now the hard part -- adjusting rv to the correct value.*/
-
- /* Put digits into bd: true value = bd * 10^e */
-
- bd0 = s2b(s0, nd0, nd, y);
- if (!bd0)
- goto nomem;
-
- for(;;) {
- bd = Balloc(bd0->k);
- if (!bd)
- goto nomem;
- Bcopy(bd, bd0);
- bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
- if (!bb)
- goto nomem;
- bs = i2b(1);
- if (!bs)
- goto nomem;
-
- if (e >= 0) {
- bb2 = bb5 = 0;
- bd2 = bd5 = e;
- }
- else {
- bb2 = bb5 = -e;
- bd2 = bd5 = 0;
- }
- if (bbe >= 0)
- bb2 += bbe;
- else
- bd2 -= bbe;
- bs2 = bb2;
-#ifdef Sudden_Underflow
- j = P + 1 - bbbits;
-#else
-#ifdef Avoid_Underflow
- j = bbe - scale;
-#else
- j = bbe;
-#endif
- i = j + bbbits - 1; /* logb(rv) */
- if (i < Emin) /* denormal */
- j += P - Emin;
- else
- j = P + 1 - bbbits;
-#endif
- bb2 += j;
- bd2 += j;
-#ifdef Avoid_Underflow
- bd2 += scale;
-#endif
- i = bb2 < bd2 ? bb2 : bd2;
- if (i > bs2)
- i = bs2;
- if (i > 0) {
- bb2 -= i;
- bd2 -= i;
- bs2 -= i;
- }
- if (bb5 > 0) {
- bs = pow5mult(bs, bb5);
- if (!bs)
- goto nomem;
- bb1 = mult(bs, bb);
- if (!bb1)
- goto nomem;
- Bfree(bb);
- bb = bb1;
- }
- if (bb2 > 0) {
- bb = lshift(bb, bb2);
- if (!bb)
- goto nomem;
- }
- if (bd5 > 0) {
- bd = pow5mult(bd, bd5);
- if (!bd)
- goto nomem;
- }
- if (bd2 > 0) {
- bd = lshift(bd, bd2);
- if (!bd)
- goto nomem;
- }
- if (bs2 > 0) {
- bs = lshift(bs, bs2);
- if (!bs)
- goto nomem;
- }
- delta = diff(bb, bd);
- if (!delta)
- goto nomem;
- dsign = delta->sign;
- delta->sign = 0;
- i = cmp(delta, bs);
- if (i < 0) {
- /* Error is less than half an ulp -- check for
- * special case of mantissa a power of two.
- */
- if (dsign || word1(rv) || word0(rv) & Bndry_mask
-#ifdef Avoid_Underflow
- || (word0(rv) & Exp_mask) <= Exp_msk1 + P*Exp_msk1
-#else
- || (word0(rv) & Exp_mask) <= Exp_msk1
-#endif
- ) {
-#ifdef Avoid_Underflow
- if (!delta->x[0] && delta->wds == 1)
- dsign = 2;
-#endif
- break;
- }
- delta = lshift(delta,Log2P);
- if (!delta)
- goto nomem;
- if (cmp(delta, bs) > 0)
- goto drop_down;
- break;
- }
- if (i == 0) {
- /* exactly half-way between */
- if (dsign) {
- if ((word0(rv) & Bndry_mask1) == Bndry_mask1
- && word1(rv) == 0xffffffff) {
- /*boundary case -- increment exponent*/
- set_word0(rv, (word0(rv) & Exp_mask) + Exp_msk1);
- set_word1(rv, 0);
-#ifdef Avoid_Underflow
- dsign = 0;
-#endif
- break;
- }
- }
- else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
-#ifdef Avoid_Underflow
- dsign = 2;
-#endif
- drop_down:
- /* boundary case -- decrement exponent */
-#ifdef Sudden_Underflow
- L = word0(rv) & Exp_mask;
- if (L <= Exp_msk1)
- goto undfl;
- L -= Exp_msk1;
-#else
- L = (word0(rv) & Exp_mask) - Exp_msk1;
-#endif
- set_word0(rv, L | Bndry_mask1);
- set_word1(rv, 0xffffffff);
- break;
- }
-#ifndef ROUND_BIASED
- if (!(word1(rv) & LSB))
- break;
-#endif
- if (dsign)
- rv += ulp(rv);
-#ifndef ROUND_BIASED
- else {
- rv -= ulp(rv);
-#ifndef Sudden_Underflow
- if (!rv)
- goto undfl;
-#endif
- }
-#ifdef Avoid_Underflow
- dsign = 1 - dsign;
-#endif
-#endif
- break;
- }
- if ((aadj = ratio(delta, bs)) <= 2.) {
- if (dsign)
- aadj = aadj1 = 1.;
- else if (word1(rv) || word0(rv) & Bndry_mask) {
-#ifndef Sudden_Underflow
- if (word1(rv) == Tiny1 && !word0(rv))
- goto undfl;
-#endif
- aadj = 1.;
- aadj1 = -1.;
- }
- else {
- /* special case -- power of FLT_RADIX to be */
- /* rounded down... */
-
- if (aadj < 2./FLT_RADIX)
- aadj = 1./FLT_RADIX;
- else
- aadj *= 0.5;
- aadj1 = -aadj;
- }
- }
- else {
- aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
-#ifdef Check_FLT_ROUNDS
- switch(FLT_ROUNDS) {
- case 2: /* towards +infinity */
- aadj1 -= 0.5;
- break;
- case 0: /* towards 0 */
- case 3: /* towards -infinity */
- aadj1 += 0.5;
- }
-#else
- if (FLT_ROUNDS == 0)
- aadj1 += 0.5;
-#endif
- }
- y = word0(rv) & Exp_mask;
-
- /* Check for overflow */
-
- if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
- rv0 = rv;
- set_word0(rv, word0(rv) - P*Exp_msk1);
- adj = aadj1 * ulp(rv);
- rv += adj;
- if ((word0(rv) & Exp_mask) >=
- Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
- if (word0(rv0) == Big0 && word1(rv0) == Big1)
- goto ovfl;
- set_word0(rv, Big0);
- set_word1(rv, Big1);
- goto cont;
- }
- else
- set_word0(rv, word0(rv) + P*Exp_msk1);
- }
- else {
-#ifdef Sudden_Underflow
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
- rv0 = rv;
- set_word0(rv, word0(rv) + P*Exp_msk1);
- adj = aadj1 * ulp(rv);
- rv += adj;
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
- {
- if (word0(rv0) == Tiny0
- && word1(rv0) == Tiny1)
- goto undfl;
- set_word0(rv, Tiny0);
- set_word1(rv, Tiny1);
- goto cont;
- }
- else
- set_word0(rv, word0(rv) - P*Exp_msk1);
- }
- else {
- adj = aadj1 * ulp(rv);
- rv += adj;
- }
-#else
- /* Compute adj so that the IEEE rounding rules will
- * correctly round rv + adj in some half-way cases.
- * If rv * ulp(rv) is denormalized (i.e.,
- * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
- * trouble from bits lost to denormalization;
- * example: 1.2e-307 .
- */
-#ifdef Avoid_Underflow
- if (y <= P*Exp_msk1 && aadj > 1.)
-#else
- if (y <= (P-1)*Exp_msk1 && aadj > 1.)
-#endif
- {
- aadj1 = (double)(int32)(aadj + 0.5);
- if (!dsign)
- aadj1 = -aadj1;
- }
-#ifdef Avoid_Underflow
- if (scale && y <= P*Exp_msk1)
- set_word0(aadj1, word0(aadj1) + (P+1)*Exp_msk1 - y);
-#endif
- adj = aadj1 * ulp(rv);
- rv += adj;
-#endif
- }
- z = word0(rv) & Exp_mask;
-#ifdef Avoid_Underflow
- if (!scale)
-#endif
- if (y == z) {
- /* Can we stop now? */
- L = (Long)aadj;
- aadj -= L;
- /* The tolerances below are conservative. */
- if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
- if (aadj < .4999999 || aadj > .5000001)
- break;
- }
- else if (aadj < .4999999/FLT_RADIX)
- break;
- }
- cont:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(delta);
- bb = bd = bs = delta = NULL;
- }
-#ifdef Avoid_Underflow
- if (scale) {
- set_word0(rv0, Exp_1 - P*Exp_msk1);
- set_word1(rv0, 0);
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1
- && word1(rv) & 1
- && dsign != 2) {
- if (dsign) {
-#ifdef Sudden_Underflow
- /* rv will be 0, but this would give the */
- /* right result if only rv *= rv0 worked. */
- set_word0(rv, word0(rv) + P*Exp_msk1);
- set_word0(rv0, Exp_1 - 2*P*Exp_msk1);
-#endif
- rv += ulp(rv);
- }
- else
- set_word1(rv, word1(rv) & ~1);
- }
- rv *= rv0;
- }
-#endif /* Avoid_Underflow */
-retfree:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(bd0);
- Bfree(delta);
-ret:
- RELEASE_DTOA_LOCK();
- if (se)
- *se = (char *)s;
- rv0 = sign ? -rv : rv;
- goto ret1;
-
-nomem:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(bd0);
- Bfree(delta);
- *err = JS_DTOA_ENOMEM;
- rv0 = 0;
-
-ret1:
- RESTORE_FPU();
- return rv0;
-}
-
-
-/* Return floor(b/2^k) and set b to be the remainder. The returned quotient must be less than 2^32. */
-static uint32 quorem2(Bigint *b, int32 k)
-{
- ULong mask;
- ULong result;
- ULong *bx, *bxe;
- int32 w;
- int32 n = k >> 5;
- k &= 0x1F;
- mask = (1<<k) - 1;
-
- w = b->wds - n;
- if (w <= 0)
- return 0;
- JS_ASSERT(w <= 2);
- bx = b->x;
- bxe = bx + n;
- result = *bxe >> k;
- *bxe &= mask;
- if (w == 2) {
- JS_ASSERT(!(bxe[1] & ~mask));
- if (k)
- result |= bxe[1] << (32 - k);
- }
- n++;
- while (!*bxe && bxe != bx) {
- n--;
- bxe--;
- }
- b->wds = n;
- return result;
-}
-
-/* Return floor(b/S) and set b to be the remainder. As added restrictions, b must not have
- * more words than S, the most significant word of S must not start with a 1 bit, and the
- * returned quotient must be less than 36. */
-static int32 quorem(Bigint *b, Bigint *S)
-{
- int32 n;
- ULong *bx, *bxe, q, *sx, *sxe;
-#ifdef ULLong
- ULLong borrow, carry, y, ys;
-#else
- ULong borrow, carry, y, ys;
- ULong si, z, zs;
-#endif
-
- n = S->wds;
- JS_ASSERT(b->wds <= n);
- if (b->wds < n)
- return 0;
- sx = S->x;
- sxe = sx + --n;
- bx = b->x;
- bxe = bx + n;
- JS_ASSERT(*sxe <= 0x7FFFFFFF);
- q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
- JS_ASSERT(q < 36);
- if (q) {
- borrow = 0;
- carry = 0;
- do {
-#ifdef ULLong
- ys = *sx++ * (ULLong)q + carry;
- carry = ys >> 32;
- y = *bx - (ys & 0xffffffffUL) - borrow;
- borrow = y >> 32 & 1UL;
- *bx++ = (ULong)(y & 0xffffffffUL);
-#else
- si = *sx++;
- ys = (si & 0xffff) * q + carry;
- zs = (si >> 16) * q + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
- borrow = (y & 0x10000) >> 16;
- z = (*bx >> 16) - (zs & 0xffff) - borrow;
- borrow = (z & 0x10000) >> 16;
- Storeinc(bx, z, y);
-#endif
- }
- while(sx <= sxe);
- if (!*bxe) {
- bx = b->x;
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- if (cmp(b, S) >= 0) {
- q++;
- borrow = 0;
- carry = 0;
- bx = b->x;
- sx = S->x;
- do {
-#ifdef ULLong
- ys = *sx++ + carry;
- carry = ys >> 32;
- y = *bx - (ys & 0xffffffffUL) - borrow;
- borrow = y >> 32 & 1UL;
- *bx++ = (ULong)(y & 0xffffffffUL);
-#else
- si = *sx++;
- ys = (si & 0xffff) + carry;
- zs = (si >> 16) + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
- borrow = (y & 0x10000) >> 16;
- z = (*bx >> 16) - (zs & 0xffff) - borrow;
- borrow = (z & 0x10000) >> 16;
- Storeinc(bx, z, y);
-#endif
- } while(sx <= sxe);
- bx = b->x;
- bxe = bx + n;
- if (!*bxe) {
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- return (int32)q;
-}
-
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
- *
- * Inspired by "How to Print Floating-Point Numbers Accurately" by
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- * 1. Rather than iterating, we use a simple numeric overestimate
- * to determine k = floor(log10(d)). We scale relevant
- * quantities using O(log2(k)) rather than O(k) multiplications.
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
- * try to generate digits strictly left to right. Instead, we
- * compute with fewer bits and propagate the carry if necessary
- * when rounding the final digit up. This is often faster.
- * 3. Under the assumption that input will be rounded nearest,
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
- * That is, we allow equality in stopping tests when the
- * round-nearest rule will give the same floating-point value
- * as would satisfaction of the stopping test with strict
- * inequality.
- * 4. We remove common factors of powers of 2 from relevant
- * quantities.
- * 5. When converting floating-point integers less than 1e16,
- * we use floating-point arithmetic rather than resorting
- * to multiple-precision integers.
- * 6. When asked to produce fewer than 15 digits, we first try
- * to get by with floating-point arithmetic; we resort to
- * multiple-precision integer arithmetic only if we cannot
- * guarantee that the floating-point calculation has given
- * the correctly rounded result. For k requested digits and
- * "uniformly" distributed input, the probability is
- * something like 10^(k-15) that we must resort to the Long
- * calculation.
- */
-
-/* Always emits at least one digit. */
-/* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
- * when the number is exactly halfway between two representable values. For example,
- * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
- * 2.49 will still round to 2, and 2.51 will still round to 3. */
-/* bufsize should be at least 20 for modes 0 and 1. For the other modes,
- * bufsize should be two greater than the maximum number of output characters expected. */
-static JSBool
-js_dtoa(double d, int mode, JSBool biasUp, int ndigits,
- int *decpt, int *sign, char **rve, char *buf, size_t bufsize)
-{
- /* Arguments ndigits, decpt, sign are similar to those
- of ecvt and fcvt; trailing zeros are suppressed from
- the returned string. If not null, *rve is set to point
- to the end of the return value. If d is +-Infinity or NaN,
- then *decpt is set to 9999.
-
- mode:
- 0 ==> shortest string that yields d when read in
- and rounded to nearest.
- 1 ==> like 0, but with Steele & White stopping rule;
- e.g. with IEEE P754 arithmetic , mode 0 gives
- 1e23 whereas mode 1 gives 9.999999999999999e22.
- 2 ==> max(1,ndigits) significant digits. This gives a
- return value similar to that of ecvt, except
- that trailing zeros are suppressed.
- 3 ==> through ndigits past the decimal point. This
- gives a return value similar to that from fcvt,
- except that trailing zeros are suppressed, and
- ndigits can be negative.
- 4-9 should give the same return values as 2-3, i.e.,
- 4 <= mode <= 9 ==> same return as mode
- 2 + (mode & 1). These modes are mainly for
- debugging; often they run slower but sometimes
- faster than modes 2-3.
- 4,5,8,9 ==> left-to-right digit generation.
- 6-9 ==> don't try fast floating-point estimate
- (if applicable).
-
- Values of mode other than 0-9 are treated as mode 0.
-
- Sufficient space is allocated to the return value
- to hold the suppressed trailing zeros.
- */
-
- int32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
- j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
- spec_case, try_quick;
- Long L;
-#ifndef Sudden_Underflow
- int32 denorm;
- ULong x;
-#endif
- Bigint *b, *b1, *delta, *mlo, *mhi, *S;
- double d2, ds, eps;
- char *s;
- JSBool ok;
-
- SET_FPU();
-
- if (word0(d) & Sign_bit) {
- /* set sign for everything, including 0's and NaNs */
- *sign = 1;
- set_word0(d, word0(d) & ~Sign_bit); /* clear sign bit */
- }
- else
- *sign = 0;
-
- if ((word0(d) & Exp_mask) == Exp_mask) {
- /* Infinity or NaN */
- *decpt = 9999;
- s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";
- if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {
- JS_ASSERT(JS_FALSE);
-/* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
- ok = JS_FALSE;
- goto ret2;
- }
- strcpy(buf, s);
- if (rve) {
- *rve = buf[3] ? buf + 8 : buf + 3;
- JS_ASSERT(**rve == '\0');
- }
- ok = JS_TRUE;
- goto ret2;
- }
-
- b = NULL; /* initialize for abort protection */
- S = NULL;
- mlo = mhi = NULL;
-
- if (!d) {
- no_digits:
- *decpt = 1;
- if (bufsize < 2) {
- JS_ASSERT(JS_FALSE);
-/* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
- ok = JS_FALSE;
- goto ret2;
- }
- buf[0] = '0'; buf[1] = '\0'; /* copy "0" to buffer */
- if (rve)
- *rve = buf + 1;
- /* We might have jumped to "no_digits" from below, so we need
- * to be sure to free the potentially allocated Bigints to avoid
- * memory leaks. */
- Bfree(b);
- Bfree(S);
- if (mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- ok = JS_TRUE;
- goto ret2;
- }
-
- b = d2b(d, &be, &bbits);
- if (!b)
- goto nomem;
-#ifdef Sudden_Underflow
- i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
-#else
- if ((i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
-#endif
- d2 = d;
- set_word0(d2, word0(d2) & Frac_mask1);
- set_word0(d2, word0(d2) | Exp_11);
-
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
- * log10(x) = log(x) / log(10)
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
- *
- * This suggests computing an approximation k to log10(d) by
- *
- * k = (i - Bias)*0.301029995663981
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
- *
- * We want k to be too large rather than too small.
- * The error in the first-order Taylor series approximation
- * is in our favor, so we just round up the constant enough
- * to compensate for any error in the multiplication of
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
- * adding 1e-13 to the constant term more than suffices.
- * Hence we adjust the constant term to 0.1760912590558.
- * (We could get a more accurate k by invoking log10,
- * but this is probably not worthwhile.)
- */
-
- i -= Bias;
-#ifndef Sudden_Underflow
- denorm = 0;
- }
- else {
- /* d is denormalized */
-
- i = bbits + be + (Bias + (P-1) - 1);
- x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) : word1(d) << (32 - i);
- d2 = x;
- set_word0(d2, word0(d2) - 31*Exp_msk1); /* adjust exponent */
- i -= (Bias + (P-1) - 1) + 1;
- denorm = 1;
- }
-#endif
- /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
- ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
- k = (int32)ds;
- if (ds < 0. && ds != k)
- k--; /* want k = floor(ds) */
- k_check = 1;
- if (k >= 0 && k <= Ten_pmax) {
- if (d < tens[k])
- k--;
- k_check = 0;
- }
- /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
- If k_check is zero, we're guaranteed that k = floor(log10(d)). */
- j = bbits - i - 1;
- /* At this point d = b/2^j, where b is an odd integer. */
- if (j >= 0) {
- b2 = 0;
- s2 = j;
- }
- else {
- b2 = -j;
- s2 = 0;
- }
- if (k >= 0) {
- b5 = 0;
- s5 = k;
- s2 += k;
- }
- else {
- b2 -= k;
- b5 = -k;
- s5 = 0;
- }
- /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
- b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
- if (mode < 0 || mode > 9)
- mode = 0;
- try_quick = 1;
- if (mode > 5) {
- mode -= 4;
- try_quick = 0;
- }
- leftright = 1;
- ilim = ilim1 = 0;
- switch(mode) {
- case 0:
- case 1:
- ilim = ilim1 = -1;
- i = 18;
- ndigits = 0;
- break;
- case 2:
- leftright = 0;
- /* no break */
- case 4:
- if (ndigits <= 0)
- ndigits = 1;
- ilim = ilim1 = i = ndigits;
- break;
- case 3:
- leftright = 0;
- /* no break */
- case 5:
- i = ndigits + k + 1;
- ilim = i;
- ilim1 = i - 1;
- if (i <= 0)
- i = 1;
- }
- /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
- /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
- when it turns out that k was computed too high by one. */
-
- /* Ensure space for at least i+1 characters, including trailing null. */
- if (bufsize <= (size_t)i) {
- Bfree(b);
- JS_ASSERT(JS_FALSE);
- ok = JS_FALSE;
- goto ret2;
- }
- s = buf;
-
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {
-
- /* Try to get by with floating-point arithmetic. */
-
- i = 0;
- d2 = d;
- k0 = k;
- ilim0 = ilim;
- ieps = 2; /* conservative */
- /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
- if (k > 0) {
- ds = tens[k&0xf];
- j = k >> 4;
- if (j & Bletch) {
- /* prevent overflows */
- j &= Bletch - 1;
- d /= bigtens[n_bigtens-1];
- ieps++;
- }
- for(; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- ds *= bigtens[i];
- }
- d /= ds;
- }
- else if ((j1 = -k) != 0) {
- d *= tens[j1 & 0xf];
- for(j = j1 >> 4; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- d *= bigtens[i];
- }
- }
- /* Check that k was computed correctly. */
- if (k_check && d < 1. && ilim > 0) {
- if (ilim1 <= 0)
- goto fast_failed;
- ilim = ilim1;
- k--;
- d *= 10.;
- ieps++;
- }
- /* eps bounds the cumulative error. */
- eps = ieps*d + 7.;
- set_word0(eps, word0(eps) - (P-1)*Exp_msk1);
- if (ilim == 0) {
- S = mhi = 0;
- d -= 5.;
- if (d > eps)
- goto one_digit;
- if (d < -eps)
- goto no_digits;
- goto fast_failed;
- }
-#ifndef No_leftright
- if (leftright) {
- /* Use Steele & White method of only
- * generating digits needed.
- */
- eps = 0.5/tens[ilim-1] - eps;
- for(i = 0;;) {
- L = (Long)d;
- d -= L;
- *s++ = '0' + (char)L;
- if (d < eps)
- goto ret1;
- if (1. - d < eps)
- goto bump_up;
- if (++i >= ilim)
- break;
- eps *= 10.;
- d *= 10.;
- }
- }
- else {
-#endif
- /* Generate ilim digits, then fix them up. */
- eps *= tens[ilim-1];
- for(i = 1;; i++, d *= 10.) {
- L = (Long)d;
- d -= L;
- *s++ = '0' + (char)L;
- if (i == ilim) {
- if (d > 0.5 + eps)
- goto bump_up;
- else if (d < 0.5 - eps) {
- while(*--s == '0') ;
- s++;
- goto ret1;
- }
- break;
- }
- }
-#ifndef No_leftright
- }
-#endif
- fast_failed:
- s = buf;
- d = d2;
- k = k0;
- ilim = ilim0;
- }
-
- /* Do we have a "small" integer? */
-
- if (be >= 0 && k <= Int_max) {
- /* Yes. */
- ds = tens[k];
- if (ndigits < 0 && ilim <= 0) {
- S = mhi = 0;
- if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds))
- goto no_digits;
- goto one_digit;
- }
- for(i = 1;; i++) {
- L = (Long) (d / ds);
- d -= L*ds;
-#ifdef Check_FLT_ROUNDS
- /* If FLT_ROUNDS == 2, L will usually be high by 1 */
- if (d < 0) {
- L--;
- d += ds;
- }
-#endif
- *s++ = '0' + (char)L;
- if (i == ilim) {
- d += d;
- if ((d > ds) || (d == ds && (L & 1 || biasUp))) {
- bump_up:
- while(*--s == '9')
- if (s == buf) {
- k++;
- *s = '0';
- break;
- }
- ++*s++;
- }
- break;
- }
- if (!(d *= 10.))
- break;
- }
- goto ret1;
- }
-
- m2 = b2;
- m5 = b5;
- if (leftright) {
- if (mode < 2) {
- i =
-#ifndef Sudden_Underflow
- denorm ? be + (Bias + (P-1) - 1 + 1) :
-#endif
- 1 + P - bbits;
- /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
- (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
- }
- else {
- j = ilim - 1;
- if (m5 >= j)
- m5 -= j;
- else {
- s5 += j -= m5;
- b5 += j;
- m5 = 0;
- }
- if ((i = ilim) < 0) {
- m2 -= i;
- i = 0;
- }
- /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
- }
- b2 += i;
- s2 += i;
- mhi = i2b(1);
- if (!mhi)
- goto nomem;
- /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
- input (when mode < 2) significant digit, divided by 10^k. */
- }
- /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
- b2, m2, and s2 without changing the equalities. */
- if (m2 > 0 && s2 > 0) {
- i = m2 < s2 ? m2 : s2;
- b2 -= i;
- m2 -= i;
- s2 -= i;
- }
-
- /* Fold b5 into b and m5 into mhi. */
- if (b5 > 0) {
- if (leftright) {
- if (m5 > 0) {
- mhi = pow5mult(mhi, m5);
- if (!mhi)
- goto nomem;
- b1 = mult(mhi, b);
- if (!b1)
- goto nomem;
- Bfree(b);
- b = b1;
- }
- if ((j = b5 - m5) != 0) {
- b = pow5mult(b, j);
- if (!b)
- goto nomem;
- }
- }
- else {
- b = pow5mult(b, b5);
- if (!b)
- goto nomem;
- }
- }
- /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
- (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
-
- S = i2b(1);
- if (!S)
- goto nomem;
- if (s5 > 0) {
- S = pow5mult(S, s5);
- if (!S)
- goto nomem;
- }
- /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
- (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
-
- /* Check for special case that d is a normalized power of 2. */
- spec_case = 0;
- if (mode < 2) {
- if (!word1(d) && !(word0(d) & Bndry_mask)
-#ifndef Sudden_Underflow
- && word0(d) & (Exp_mask & Exp_mask << 1)
-#endif
- ) {
- /* The special case. Here we want to be within a quarter of the last input
- significant digit instead of one half of it when the decimal output string's value is less than d. */
- b2 += Log2P;
- s2 += Log2P;
- spec_case = 1;
- }
- }
-
- /* Arrange for convenient computation of quotients:
- * shift left if necessary so divisor has 4 leading 0 bits.
- *
- * Perhaps we should just compute leading 28 bits of S once
- * and for all and pass them and a shift to quorem, so it
- * can do shifts and ors to compute the numerator for q.
- */
- if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
- i = 32 - i;
- /* i is the number of leading zero bits in the most significant word of S*2^s2. */
- if (i > 4) {
- i -= 4;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- else if (i < 4) {
- i += 28;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
- if (b2 > 0) {
- b = lshift(b, b2);
- if (!b)
- goto nomem;
- }
- if (s2 > 0) {
- S = lshift(S, s2);
- if (!S)
- goto nomem;
- }
- /* Now we have d/10^k = b/S and
- (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
- if (k_check) {
- if (cmp(b,S) < 0) {
- k--;
- b = multadd(b, 10, 0); /* we botched the k estimate */
- if (!b)
- goto nomem;
- if (leftright) {
- mhi = multadd(mhi, 10, 0);
- if (!mhi)
- goto nomem;
- }
- ilim = ilim1;
- }
- }
- /* At this point 1 <= d/10^k = b/S < 10. */
-
- if (ilim <= 0 && mode > 2) {
- /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
- Output either zero or the minimum nonzero output depending on which is closer to d. */
- if (ilim < 0)
- goto no_digits;
- S = multadd(S,5,0);
- if (!S)
- goto nomem;
- i = cmp(b,S);
- if (i < 0 || (i == 0 && !biasUp)) {
- /* Always emit at least one digit. If the number appears to be zero
- using the current mode, then emit one '0' digit and set decpt to 1. */
- /*no_digits:
- k = -1 - ndigits;
- goto ret; */
- goto no_digits;
- }
- one_digit:
- *s++ = '1';
- k++;
- goto ret;
- }
- if (leftright) {
- if (m2 > 0) {
- mhi = lshift(mhi, m2);
- if (!mhi)
- goto nomem;
- }
-
- /* Compute mlo -- check for special case
- * that d is a normalized power of 2.
- */
-
- mlo = mhi;
- if (spec_case) {
- mhi = Balloc(mhi->k);
- if (!mhi)
- goto nomem;
- Bcopy(mhi, mlo);
- mhi = lshift(mhi, Log2P);
- if (!mhi)
- goto nomem;
- }
- /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
- /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
-
- for(i = 1;;i++) {
- dig = quorem(b,S) + '0';
- /* Do we yet have the shortest decimal string
- * that will round to d?
- */
- j = cmp(b, mlo);
- /* j is b/S compared with mlo/S. */
- delta = diff(S, mhi);
- if (!delta)
- goto nomem;
- j1 = delta->sign ? 1 : cmp(b, delta);
- Bfree(delta);
- /* j1 is b/S compared with 1 - mhi/S. */
-#ifndef ROUND_BIASED
- if (j1 == 0 && !mode && !(word1(d) & 1)) {
- if (dig == '9')
- goto round_9_up;
- if (j > 0)
- dig++;
- *s++ = (char)dig;
- goto ret;
- }
-#endif
- if ((j < 0) || (j == 0 && !mode
-#ifndef ROUND_BIASED
- && !(word1(d) & 1)
-#endif
- )) {
- if (j1 > 0) {
- /* Either dig or dig+1 would work here as the least significant decimal digit.
- Use whichever would produce a decimal value closer to d. */
- b = lshift(b, 1);
- if (!b)
- goto nomem;
- j1 = cmp(b, S);
- if (((j1 > 0) || (j1 == 0 && (dig & 1 || biasUp)))
- && (dig++ == '9'))
- goto round_9_up;
- }
- *s++ = (char)dig;
- goto ret;
- }
- if (j1 > 0) {
- if (dig == '9') { /* possible if i == 1 */
- round_9_up:
- *s++ = '9';
- goto roundoff;
- }
- *s++ = dig + 1;
- goto ret;
- }
- *s++ = (char)dig;
- if (i == ilim)
- break;
- b = multadd(b, 10, 0);
- if (!b)
- goto nomem;
- if (mlo == mhi) {
- mlo = mhi = multadd(mhi, 10, 0);
- if (!mhi)
- goto nomem;
- }
- else {
- mlo = multadd(mlo, 10, 0);
- if (!mlo)
- goto nomem;
- mhi = multadd(mhi, 10, 0);
- if (!mhi)
- goto nomem;
- }
- }
- }
- else
- for(i = 1;; i++) {
- *s++ = (char)(dig = quorem(b,S) + '0');
- if (i >= ilim)
- break;
- b = multadd(b, 10, 0);
- if (!b)
- goto nomem;
- }
-
- /* Round off last digit */
-
- b = lshift(b, 1);
- if (!b)
- goto nomem;
- j = cmp(b, S);
- if ((j > 0) || (j == 0 && (dig & 1 || biasUp))) {
- roundoff:
- while(*--s == '9')
- if (s == buf) {
- k++;
- *s++ = '1';
- goto ret;
- }
- ++*s++;
- }
- else {
- /* Strip trailing zeros */
- while(*--s == '0') ;
- s++;
- }
- ret:
- Bfree(S);
- if (mhi) {
- if (mlo && mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
- ret1:
- Bfree(b);
- JS_ASSERT(s < buf + bufsize);
- *s = '\0';
- if (rve)
- *rve = s;
- *decpt = k + 1;
- ok = JS_TRUE;
- goto ret2;
-
-nomem:
- Bfree(S);
- if (mhi) {
- if (mlo && mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
- Bfree(b);
- ok = JS_FALSE;
-
-ret2:
- RESTORE_FPU();
- return ok;
-}
-
-
-/* Mapping of JSDToStrMode -> js_dtoa mode */
-static const int dtoaModes[] = {
- 0, /* DTOSTR_STANDARD */
- 0, /* DTOSTR_STANDARD_EXPONENTIAL, */
- 3, /* DTOSTR_FIXED, */
- 2, /* DTOSTR_EXPONENTIAL, */
- 2}; /* DTOSTR_PRECISION */
-
-JS_FRIEND_API(char *)
-JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double d)
-{
- int decPt; /* Position of decimal point relative to first digit returned by js_dtoa */
- int sign; /* Nonzero if the sign bit was set in d */
- int nDigits; /* Number of significand digits returned by js_dtoa */
- char *numBegin = buffer+2; /* Pointer to the digits returned by js_dtoa; the +2 leaves space for */
- /* the sign and/or decimal point */
- char *numEnd; /* Pointer past the digits returned by js_dtoa */
- JSBool dtoaRet;
-
- JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
- DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
-
- if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
- mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
-
- /* Locking for Balloc's shared buffers */
- ACQUIRE_DTOA_LOCK();
- dtoaRet = js_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, &decPt, &sign, &numEnd, numBegin, bufferSize-2);
- RELEASE_DTOA_LOCK();
- if (!dtoaRet)
- return 0;
-
- nDigits = numEnd - numBegin;
-
- /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
- if (decPt != 9999) {
- JSBool exponentialNotation = JS_FALSE;
- int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */
- char *p;
- char *q;
-
- switch (mode) {
- case DTOSTR_STANDARD:
- if (decPt < -5 || decPt > 21)
- exponentialNotation = JS_TRUE;
- else
- minNDigits = decPt;
- break;
-
- case DTOSTR_FIXED:
- if (precision >= 0)
- minNDigits = decPt + precision;
- else
- minNDigits = decPt;
- break;
-
- case DTOSTR_EXPONENTIAL:
- JS_ASSERT(precision > 0);
- minNDigits = precision;
- /* Fall through */
- case DTOSTR_STANDARD_EXPONENTIAL:
- exponentialNotation = JS_TRUE;
- break;
-
- case DTOSTR_PRECISION:
- JS_ASSERT(precision > 0);
- minNDigits = precision;
- if (decPt < -5 || decPt > precision)
- exponentialNotation = JS_TRUE;
- break;
- }
-
- /* If the number has fewer than minNDigits, pad it with zeros at the end */
- if (nDigits < minNDigits) {
- p = numBegin + minNDigits;
- nDigits = minNDigits;
- do {
- *numEnd++ = '0';
- } while (numEnd != p);
- *numEnd = '\0';
- }
-
- if (exponentialNotation) {
- /* Insert a decimal point if more than one significand digit */
- if (nDigits != 1) {
- numBegin--;
- numBegin[0] = numBegin[1];
- numBegin[1] = '.';
- }
- JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
- } else if (decPt != nDigits) {
- /* Some kind of a fraction in fixed notation */
- JS_ASSERT(decPt <= nDigits);
- if (decPt > 0) {
- /* dd...dd . dd...dd */
- p = --numBegin;
- do {
- *p = p[1];
- p++;
- } while (--decPt);
- *p = '.';
- } else {
- /* 0 . 00...00dd...dd */
- p = numEnd;
- numEnd += 1 - decPt;
- q = numEnd;
- JS_ASSERT(numEnd < buffer + bufferSize);
- *numEnd = '\0';
- while (p != numBegin)
- *--q = *--p;
- for (p = numBegin + 1; p != q; p++)
- *p = '0';
- *numBegin = '.';
- *--numBegin = '0';
- }
- }
- }
-
- /* If negative and neither -0.0 nor NaN, output a leading '-'. */
- if (sign &&
- !(word0(d) == Sign_bit && word1(d) == 0) &&
- !((word0(d) & Exp_mask) == Exp_mask &&
- (word1(d) || (word0(d) & Frac_mask)))) {
- *--numBegin = '-';
- }
- return numBegin;
-}
-
-
-/* Let b = floor(b / divisor), and return the remainder. b must be nonnegative.
- * divisor must be between 1 and 65536.
- * This function cannot run out of memory. */
-static uint32
-divrem(Bigint *b, uint32 divisor)
-{
- int32 n = b->wds;
- uint32 remainder = 0;
- ULong *bx;
- ULong *bp;
-
- JS_ASSERT(divisor > 0 && divisor <= 65536);
-
- if (!n)
- return 0; /* b is zero */
- bx = b->x;
- bp = bx + n;
- do {
- ULong a = *--bp;
- ULong dividend = remainder << 16 | a >> 16;
- ULong quotientHi = dividend / divisor;
- ULong quotientLo;
-
- remainder = dividend - quotientHi*divisor;
- JS_ASSERT(quotientHi <= 0xFFFF && remainder < divisor);
- dividend = remainder << 16 | (a & 0xFFFF);
- quotientLo = dividend / divisor;
- remainder = dividend - quotientLo*divisor;
- JS_ASSERT(quotientLo <= 0xFFFF && remainder < divisor);
- *bp = quotientHi << 16 | quotientLo;
- } while (bp != bx);
- /* Decrease the size of the number if its most significant word is now zero. */
- if (bx[n-1] == 0)
- b->wds--;
- return remainder;
-}
-
-
-/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
- * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
- * the output string and malloc fewer bytes depending on d and base, but why bother? */
-#define DTOBASESTR_BUFFER_SIZE 1078
-#define BASEDIGIT(digit) ((char)(((digit) >= 10) ? 'a' - 10 + (digit) : '0' + (digit)))
-
-JS_FRIEND_API(char *)
-JS_dtobasestr(int base, double d)
-{
- char *buffer; /* The output string */
- char *p; /* Pointer to current position in the buffer */
- char *pInt; /* Pointer to the beginning of the integer part of the string */
- char *q;
- uint32 digit;
- double di; /* d truncated to an integer */
- double df; /* The fractional part of d */
-
- JS_ASSERT(base >= 2 && base <= 36);
-
- buffer = (char*) malloc(DTOBASESTR_BUFFER_SIZE);
- if (buffer) {
- p = buffer;
- if (d < 0.0
-#if defined(XP_WIN) || defined(XP_OS2)
- && !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */
-#endif
- ) {
- *p++ = '-';
- d = -d;
- }
-
- /* Check for Infinity and NaN */
- if ((word0(d) & Exp_mask) == Exp_mask) {
- strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN");
- return buffer;
- }
-
- /* Locking for Balloc's shared buffers */
- ACQUIRE_DTOA_LOCK();
-
- /* Output the integer part of d with the digits in reverse order. */
- pInt = p;
- di = fd_floor(d);
- if (di <= 4294967295.0) {
- uint32 n = (uint32)di;
- if (n)
- do {
- uint32 m = n / base;
- digit = n - m*base;
- n = m;
- JS_ASSERT(digit < (uint32)base);
- *p++ = BASEDIGIT(digit);
- } while (n);
- else *p++ = '0';
- } else {
- int32 e;
- int32 bits; /* Number of significant bits in di; not used. */
- Bigint *b = d2b(di, &e, &bits);
- if (!b)
- goto nomem1;
- b = lshift(b, e);
- if (!b) {
- nomem1:
- Bfree(b);
- return NULL;
- }
- do {
- digit = divrem(b, base);
- JS_ASSERT(digit < (uint32)base);
- *p++ = BASEDIGIT(digit);
- } while (b->wds);
- Bfree(b);
- }
- /* Reverse the digits of the integer part of d. */
- q = p-1;
- while (q > pInt) {
- char ch = *pInt;
- *pInt++ = *q;
- *q-- = ch;
- }
-
- df = d - di;
- if (df != 0.0) {
- /* We have a fraction. */
- int32 e, bbits, s2, done;
- Bigint *b, *s, *mlo, *mhi;
-
- b = s = mlo = mhi = NULL;
-
- *p++ = '.';
- b = d2b(df, &e, &bbits);
- if (!b) {
- nomem2:
- Bfree(b);
- Bfree(s);
- if (mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- return NULL;
- }
- JS_ASSERT(e < 0);
- /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
-
- s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1);
-#ifndef Sudden_Underflow
- if (!s2)
- s2 = -1;
-#endif
- s2 += Bias + P;
- /* 1/2^s2 = (nextDouble(d) - d)/2 */
- JS_ASSERT(-s2 < e);
- mlo = i2b(1);
- if (!mlo)
- goto nomem2;
- mhi = mlo;
- if (!word1(d) && !(word0(d) & Bndry_mask)
-#ifndef Sudden_Underflow
- && word0(d) & (Exp_mask & Exp_mask << 1)
-#endif
- ) {
- /* The special case. Here we want to be within a quarter of the last input
- significant digit instead of one half of it when the output string's value is less than d. */
- s2 += Log2P;
- mhi = i2b(1<<Log2P);
- if (!mhi)
- goto nomem2;
- }
- b = lshift(b, e + s2);
- if (!b)
- goto nomem2;
- s = i2b(1);
- if (!s)
- goto nomem2;
- s = lshift(s, s2);
- if (!s)
- goto nomem2;
- /* At this point we have the following:
- * s = 2^s2;
- * 1 > df = b/2^s2 > 0;
- * (d - prevDouble(d))/2 = mlo/2^s2;
- * (nextDouble(d) - d)/2 = mhi/2^s2. */
-
- done = JS_FALSE;
- do {
- int32 j, j1;
- Bigint *delta;
-
- b = multadd(b, base, 0);
- if (!b)
- goto nomem2;
- digit = quorem2(b, s2);
- if (mlo == mhi) {
- mlo = mhi = multadd(mlo, base, 0);
- if (!mhi)
- goto nomem2;
- }
- else {
- mlo = multadd(mlo, base, 0);
- if (!mlo)
- goto nomem2;
- mhi = multadd(mhi, base, 0);
- if (!mhi)
- goto nomem2;
- }
-
- /* Do we yet have the shortest string that will round to d? */
- j = cmp(b, mlo);
- /* j is b/2^s2 compared with mlo/2^s2. */
- delta = diff(s, mhi);
- if (!delta)
- goto nomem2;
- j1 = delta->sign ? 1 : cmp(b, delta);
- Bfree(delta);
- /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
-
-#ifndef ROUND_BIASED
- if (j1 == 0 && !(word1(d) & 1)) {
- if (j > 0)
- digit++;
- done = JS_TRUE;
- } else
-#endif
- if (j < 0 || (j == 0
-#ifndef ROUND_BIASED
- && !(word1(d) & 1)
-#endif
- )) {
- if (j1 > 0) {
- /* Either dig or dig+1 would work here as the least significant digit.
- Use whichever would produce an output value closer to d. */
- b = lshift(b, 1);
- if (!b)
- goto nomem2;
- j1 = cmp(b, s);
- if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
- * such as 3.5 in base 3. */
- digit++;
- }
- done = JS_TRUE;
- } else if (j1 > 0) {
- digit++;
- done = JS_TRUE;
- }
- JS_ASSERT(digit < (uint32)base);
- *p++ = BASEDIGIT(digit);
- } while (!done);
- Bfree(b);
- Bfree(s);
- if (mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
- JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE);
- *p = '\0';
- RELEASE_DTOA_LOCK();
- }
- return buffer;
-}
diff --git a/src/extension/script/js/jsdtoa.h b/src/extension/script/js/jsdtoa.h
deleted file mode 100644
index 409f45454..000000000
--- a/src/extension/script/js/jsdtoa.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsdtoa_h___
-#define jsdtoa_h___
-/*
- * Public interface to portable double-precision floating point to string
- * and back conversion package.
- */
-
-#include "jscompat.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * JS_strtod() returns as a double-precision floating-point number
- * the value represented by the character string pointed to by
- * s00. The string is scanned up to the first unrecognized
- * character.
- * If the value of se is not (char **)NULL, a pointer to
- * the character terminating the scan is returned in the location pointed
- * to by se. If no number can be formed, se is set to s00r, and
- * zero is returned.
- *
- * *err is set to zero on success; it's set to JS_DTOA_ERANGE on range
- * errors and JS_DTOA_ENOMEM on memory failure.
- */
-#define JS_DTOA_ERANGE 1
-#define JS_DTOA_ENOMEM 2
-JS_FRIEND_API(double)
-JS_strtod(const char *s00, char **se, int *err);
-
-/*
- * Modes for converting floating-point numbers to strings.
- *
- * Some of the modes can round-trip; this means that if the number is converted to
- * a string using one of these mode and then converted back to a number, the result
- * will be identical to the original number (except that, due to ECMA, -0 will get converted
- * to +0). These round-trip modes return the minimum number of significand digits that
- * permit the round trip.
- *
- * Some of the modes take an integer parameter <precision>.
- */
-/* NB: Keep this in sync with number_constants[]. */
-typedef enum JSDToStrMode {
- DTOSTR_STANDARD, /* Either fixed or exponential format; round-trip */
- DTOSTR_STANDARD_EXPONENTIAL, /* Always exponential format; round-trip */
- DTOSTR_FIXED, /* Round to <precision> digits after the decimal point; exponential if number is large */
- DTOSTR_EXPONENTIAL, /* Always exponential format; <precision> significant digits */
- DTOSTR_PRECISION /* Either fixed or exponential format; <precision> significant digits */
-} JSDToStrMode;
-
-
-/* Maximum number of characters (including trailing null) that a DTOSTR_STANDARD or DTOSTR_STANDARD_EXPONENTIAL
- * conversion can produce. This maximum is reached for a number like -0.0000012345678901234567. */
-#define DTOSTR_STANDARD_BUFFER_SIZE 26
-
-/* Maximum number of characters (including trailing null) that one of the other conversions
- * can produce. This maximum is reached for TO_FIXED, which can generate up to 21 digits before the decimal point. */
-#define DTOSTR_VARIABLE_BUFFER_SIZE(precision) ((precision)+24 > DTOSTR_STANDARD_BUFFER_SIZE ? (precision)+24 : DTOSTR_STANDARD_BUFFER_SIZE)
-
-/*
- * Convert dval according to the given mode and return a pointer to the resulting ASCII string.
- * The result is held somewhere in buffer, but not necessarily at the beginning. The size of
- * buffer is given in bufferSize, and must be at least as large as given by the above macros.
- *
- * Return NULL if out of memory.
- */
-JS_FRIEND_API(char *)
-JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double dval);
-
-/*
- * Convert d to a string in the given base. The integral part of d will be printed exactly
- * in that base, regardless of how large it is, because there is no exponential notation for non-base-ten
- * numbers. The fractional part will be rounded to as few digits as possible while still preserving
- * the round-trip property (analogous to that of printing decimal numbers). In other words, if one were
- * to read the resulting string in via a hypothetical base-number-reading routine that rounds to the nearest
- * IEEE double (and to an even significand if there are two equally near doubles), then the result would
- * equal d (except for -0.0, which converts to "0", and NaN, which is not equal to itself).
- *
- * Return NULL if out of memory. If the result is not NULL, it must be released via free().
- */
-JS_FRIEND_API(char *)
-JS_dtobasestr(int base, double d);
-
-/*
- * Clean up any persistent RAM allocated during the execution of DtoA
- * routines, and remove any locks that might have been created.
- */
-extern void js_FinishDtoa(void);
-
-JS_END_EXTERN_C
-
-#endif /* jsdtoa_h___ */
diff --git a/src/extension/script/js/jsemit.c b/src/extension/script/js/jsemit.c
deleted file mode 100644
index 13e105c07..000000000
--- a/src/extension/script/js/jsemit.c
+++ /dev/null
@@ -1,4471 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS bytecode generation.
- */
-#include "jsstddef.h"
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsbit.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jsnum.h"
-#include "jsopcode.h"
-#include "jsparse.h"
-#include "jsscan.h"
-#include "jsscope.h"
-#include "jsscript.h"
-
-/* Allocation chunk counts, must be powers of two in general. */
-#define BYTECODE_CHUNK 256 /* code allocation increment */
-#define SRCNOTE_CHUNK 64 /* initial srcnote allocation increment */
-#define TRYNOTE_CHUNK 64 /* trynote allocation increment */
-
-/* Macros to compute byte sizes from typed element counts. */
-#define BYTECODE_SIZE(n) ((n) * sizeof(jsbytecode))
-#define SRCNOTE_SIZE(n) ((n) * sizeof(jssrcnote))
-#define TRYNOTE_SIZE(n) ((n) * sizeof(JSTryNote))
-
-JS_FRIEND_API(JSBool)
-js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
- JSArenaPool *codePool, JSArenaPool *notePool,
- const char *filename, uintN lineno,
- JSPrincipals *principals)
-{
- memset(cg, 0, sizeof *cg);
- TREE_CONTEXT_INIT(&cg->treeContext);
- cg->treeContext.flags |= TCF_COMPILING;
- cg->codePool = codePool;
- cg->notePool = notePool;
- cg->codeMark = JS_ARENA_MARK(codePool);
- cg->noteMark = JS_ARENA_MARK(notePool);
- cg->tempMark = JS_ARENA_MARK(&cx->tempPool);
- cg->current = &cg->main;
- cg->filename = filename;
- cg->firstLine = cg->prolog.currentLine = cg->main.currentLine = lineno;
- cg->principals = principals;
- ATOM_LIST_INIT(&cg->atomList);
- cg->prolog.noteMask = cg->main.noteMask = SRCNOTE_CHUNK - 1;
- return JS_TRUE;
-}
-
-JS_FRIEND_API(void)
-js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg)
-{
- TREE_CONTEXT_FINISH(&cg->treeContext);
- JS_ARENA_RELEASE(cg->codePool, cg->codeMark);
- JS_ARENA_RELEASE(cg->notePool, cg->noteMark);
- JS_ARENA_RELEASE(&cx->tempPool, cg->tempMark);
-}
-
-static ptrdiff_t
-EmitCheck(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t delta)
-{
- jsbytecode *base, *limit, *next;
- ptrdiff_t offset, length;
- size_t incr, size;
-
- base = CG_BASE(cg);
- next = CG_NEXT(cg);
- limit = CG_LIMIT(cg);
- offset = PTRDIFF(next, base, jsbytecode);
- if (next + delta > limit) {
- length = offset + delta;
- length = (length <= BYTECODE_CHUNK)
- ? BYTECODE_CHUNK
- : JS_BIT(JS_CeilingLog2(length));
- incr = BYTECODE_SIZE(length);
- if (!base) {
- JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, cg->codePool, incr);
- } else {
- size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode));
- incr -= size;
- JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
- }
- if (!base) {
- JS_ReportOutOfMemory(cx);
- return -1;
- }
- CG_BASE(cg) = base;
- CG_LIMIT(cg) = base + length;
- CG_NEXT(cg) = base + offset;
- }
- return offset;
-}
-
-static void
-UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target)
-{
- jsbytecode *pc;
- const JSCodeSpec *cs;
- intN nuses;
-
- pc = CG_CODE(cg, target);
- cs = &js_CodeSpec[pc[0]];
- nuses = cs->nuses;
- if (nuses < 0)
- nuses = 2 + GET_ARGC(pc); /* stack: fun, this, [argc arguments] */
- cg->stackDepth -= nuses;
- if (cg->stackDepth < 0) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%d", target);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_STACK_UNDERFLOW,
- cg->filename ? cg->filename : "stdin", numBuf);
- }
- cg->stackDepth += cs->ndefs;
- if ((uintN)cg->stackDepth > cg->maxStackDepth)
- cg->maxStackDepth = cg->stackDepth;
-}
-
-ptrdiff_t
-js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op)
-{
- ptrdiff_t offset = EmitCheck(cx, cg, op, 1);
-
- if (offset >= 0) {
- *CG_NEXT(cg)++ = (jsbytecode)op;
- UpdateDepth(cx, cg, offset);
- }
- return offset;
-}
-
-ptrdiff_t
-js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1)
-{
- ptrdiff_t offset = EmitCheck(cx, cg, op, 2);
-
- if (offset >= 0) {
- jsbytecode *next = CG_NEXT(cg);
- next[0] = (jsbytecode)op;
- next[1] = op1;
- CG_NEXT(cg) = next + 2;
- UpdateDepth(cx, cg, offset);
- }
- return offset;
-}
-
-ptrdiff_t
-js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1,
- jsbytecode op2)
-{
- ptrdiff_t offset = EmitCheck(cx, cg, op, 3);
-
- if (offset >= 0) {
- jsbytecode *next = CG_NEXT(cg);
- next[0] = (jsbytecode)op;
- next[1] = op1;
- next[2] = op2;
- CG_NEXT(cg) = next + 3;
- UpdateDepth(cx, cg, offset);
- }
- return offset;
-}
-
-ptrdiff_t
-js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra)
-{
- ptrdiff_t length = 1 + (ptrdiff_t)extra;
- ptrdiff_t offset = EmitCheck(cx, cg, op, length);
-
- if (offset >= 0) {
- jsbytecode *next = CG_NEXT(cg);
- *next = (jsbytecode)op;
- memset(next + 1, 0, BYTECODE_SIZE(extra));
- CG_NEXT(cg) = next + length;
- UpdateDepth(cx, cg, offset);
- }
- return offset;
-}
-
-/* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */
-const char js_with_statement_str[] = "with statement";
-
-static const char *statementName[] = {
- "block", /* BLOCK */
- "label statement", /* LABEL */
- "if statement", /* IF */
- "else statement", /* ELSE */
- "switch statement", /* SWITCH */
- js_with_statement_str, /* WITH */
- "try statement", /* TRY */
- "catch block", /* CATCH */
- "finally statement", /* FINALLY */
- "do loop", /* DO_LOOP */
- "for loop", /* FOR_LOOP */
- "for/in loop", /* FOR_IN_LOOP */
- "while loop", /* WHILE_LOOP */
-};
-
-static const char *
-StatementName(JSCodeGenerator *cg)
-{
- if (!cg->treeContext.topStmt)
- return "script";
- return statementName[cg->treeContext.topStmt->type];
-}
-
-static void
-ReportStatementTooLarge(JSContext *cx, JSCodeGenerator *cg)
-{
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET,
- StatementName(cg));
-}
-
-/**
- Span-dependent instructions in JS bytecode consist of the jump (JOF_JUMP)
- and switch (JOF_LOOKUPSWITCH, JOF_TABLESWITCH) format opcodes, subdivided
- into unconditional (gotos and gosubs), and conditional jumps or branches
- (which pop a value, test it, and jump depending on its value). Most jumps
- have just one immediate operand, a signed offset from the jump opcode's pc
- to the target bytecode. The lookup and table switch opcodes may contain
- many jump offsets.
-
- Mozilla bug #80981 (http://bugzilla.mozilla.org/show_bug.cgi?id=80981) was
- fixed by adding extended "X" counterparts to the opcodes/formats (NB: X is
- suffixed to prefer JSOP_ORX thereby avoiding a JSOP_XOR name collision for
- the extended form of the JSOP_OR branch opcode). The unextended or short
- formats have 16-bit signed immediate offset operands, the extended or long
- formats have 32-bit signed immediates. The span-dependency problem consists
- of selecting as few long instructions as possible, or about as few -- since
- jumps can span other jumps, extending one jump may cause another to need to
- be extended.
-
- Most JS scripts are short, so need no extended jumps. We optimize for this
- case by generating short jumps until we know a long jump is needed. After
- that point, we keep generating short jumps, but each jump's 16-bit immediate
- offset operand is actually an unsigned index into cg->spanDeps, an array of
- JSSpanDep structs. Each struct tells the top offset in the script of the
- opcode, the "before" offset of the jump (which will be the same as top for
- simplex jumps, but which will index further into the bytecode array for a
- non-initial jump offset in a lookup or table switch), the after "offset"
- adjusted during span-dependent instruction selection (initially the same
- value as the "before" offset), and the jump target (more below).
-
- Since we generate cg->spanDeps lazily, from within js_SetJumpOffset, we must
- ensure that all bytecode generated so far can be inspected to discover where
- the jump offset immediate operands lie within CG_CODE(cg). But the bonus is
- that we generate span-dependency records sorted by their offsets, so we can
- binary-search when trying to find a JSSpanDep for a given bytecode offset,
- or the nearest JSSpanDep at or above a given pc.
-
- To avoid limiting scripts to 64K jumps, if the cg->spanDeps index overflows
- 65534, we store SPANDEP_INDEX_HUGE in the jump's immediate operand. This
- tells us that we need to binary-search for the cg->spanDeps entry by the
- jump opcode's bytecode offset (sd->before).
-
- Jump targets need to be maintained in a data structure that lets us look
- up an already-known target by its address (jumps may have a common target),
- and that also lets us update the addresses (script-relative, a.k.a. absolute
- offsets) of targets that come after a jump target (for when a jump below
- that target needs to be extended). We use an AVL tree, implemented using
- recursion, but with some tricky optimizations to its height-balancing code
- (see http://www.enteract.com/~bradapp/ftp/src/libs/C++/AvlTrees.html).
-
- A final wrinkle: backpatch chains are linked by jump-to-jump offsets with
- positive sign, even though they link "backward" (i.e., toward lower bytecode
- address). We don't want to waste space and search time in the AVL tree for
- such temporary backpatch deltas, so we use a single-bit wildcard scheme to
- tag true JSJumpTarget pointers and encode untagged, signed (positive) deltas
- in JSSpanDep.target pointers, depending on whether the JSSpanDep has a known
- target, or is still awaiting backpatching.
-
- Note that backpatch chains would present a problem for BuildSpanDepTable,
- which inspects bytecode to build cg->spanDeps on demand, when the first
- short jump offset overflows. To solve this temporary problem, we emit a
- proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_PUSH for jumps that push a
- result on the interpreter's stack, namely JSOP_GOSUB; or JSOP_BACKPATCH_POP
- for branch ops) whose nuses/ndefs counts help keep the stack balanced, but
- whose opcode format distinguishes its backpatch delta immediate operand from
- a normal jump offset.
- */
-static int
-BalanceJumpTargets(JSJumpTarget **jtp)
-{
- JSJumpTarget *jt, *jt2, *root;
- int dir, otherDir, heightChanged;
- JSBool doubleRotate;
-
- jt = *jtp;
- JS_ASSERT(jt->balance != 0);
-
- if (jt->balance < -1) {
- dir = JT_RIGHT;
- doubleRotate = (jt->kids[JT_LEFT]->balance > 0);
- } else if (jt->balance > 1) {
- dir = JT_LEFT;
- doubleRotate = (jt->kids[JT_RIGHT]->balance < 0);
- } else {
- return 0;
- }
-
- otherDir = JT_OTHER_DIR(dir);
- if (doubleRotate) {
- jt2 = jt->kids[otherDir];
- *jtp = root = jt2->kids[dir];
-
- jt->kids[otherDir] = root->kids[dir];
- root->kids[dir] = jt;
-
- jt2->kids[dir] = root->kids[otherDir];
- root->kids[otherDir] = jt2;
-
- heightChanged = 1;
- root->kids[JT_LEFT]->balance = -JS_MAX(root->balance, 0);
- root->kids[JT_RIGHT]->balance = -JS_MIN(root->balance, 0);
- root->balance = 0;
- } else {
- *jtp = root = jt->kids[otherDir];
- jt->kids[otherDir] = root->kids[dir];
- root->kids[dir] = jt;
-
- heightChanged = (root->balance != 0);
- jt->balance = -((dir == JT_LEFT) ? --root->balance : ++root->balance);
- }
-
- return heightChanged;
-}
-
-typedef struct AddJumpTargetArgs {
- JSContext *cx;
- JSCodeGenerator *cg;
- ptrdiff_t offset;
- JSJumpTarget *node;
-} AddJumpTargetArgs;
-
-static int
-AddJumpTarget(AddJumpTargetArgs *args, JSJumpTarget **jtp)
-{
- JSJumpTarget *jt;
- int balanceDelta;
-
- jt = *jtp;
- if (!jt) {
- JSCodeGenerator *cg = args->cg;
-
- jt = cg->jtFreeList;
- if (jt) {
- cg->jtFreeList = jt->kids[JT_LEFT];
- } else {
- JS_ARENA_ALLOCATE_CAST(jt, JSJumpTarget *, &args->cx->tempPool,
- sizeof *jt);
- if (!jt) {
- JS_ReportOutOfMemory(args->cx);
- return 0;
- }
- }
- jt->offset = args->offset;
- jt->balance = 0;
- jt->kids[JT_LEFT] = jt->kids[JT_RIGHT] = NULL;
- cg->numJumpTargets++;
- args->node = jt;
- *jtp = jt;
- return 1;
- }
-
- if (jt->offset == args->offset) {
- args->node = jt;
- return 0;
- }
-
- if (args->offset < jt->offset)
- balanceDelta = -AddJumpTarget(args, &jt->kids[JT_LEFT]);
- else
- balanceDelta = AddJumpTarget(args, &jt->kids[JT_RIGHT]);
- if (!args->node)
- return 0;
-
- jt->balance += balanceDelta;
- return (balanceDelta && jt->balance)
- ? 1 - BalanceJumpTargets(jtp)
- : 0;
-}
-
-#ifdef DEBUG_brendan
-static int AVLCheck(JSJumpTarget *jt)
-{
- int lh, rh;
-
- if (!jt) return 0;
- JS_ASSERT(-1 <= jt->balance && jt->balance <= 1);
- lh = AVLCheck(jt->kids[JT_LEFT]);
- rh = AVLCheck(jt->kids[JT_RIGHT]);
- JS_ASSERT(jt->balance == rh - lh);
- return 1 + JS_MAX(lh, rh);
-}
-#endif
-
-static JSBool
-SetSpanDepTarget(JSContext *cx, JSCodeGenerator *cg, JSSpanDep *sd,
- ptrdiff_t off)
-{
- AddJumpTargetArgs args;
-
- if (off < JUMPX_OFFSET_MIN || JUMPX_OFFSET_MAX < off) {
- ReportStatementTooLarge(cx, cg);
- return JS_FALSE;
- }
-
- args.cx = cx;
- args.cg = cg;
- args.offset = sd->top + off;
- args.node = NULL;
- AddJumpTarget(&args, &cg->jumpTargets);
- if (!args.node)
- return JS_FALSE;
-
-#ifdef DEBUG_brendan
- AVLCheck(cg->jumpTargets);
-#endif
-
- SD_SET_TARGET(sd, args.node);
- return JS_TRUE;
-}
-
-#define SPANDEPS_MIN 256
-#define SPANDEPS_SIZE(n) ((n) * sizeof(JSSpanDep))
-#define SPANDEPS_SIZE_MIN SPANDEPS_SIZE(SPANDEPS_MIN)
-
-static JSBool
-AddSpanDep(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, jsbytecode *pc2,
- ptrdiff_t off)
-{
- uintN index;
- JSSpanDep *sdbase, *sd;
- size_t size;
-
- index = cg->numSpanDeps;
- if (index + 1 == 0) {
- ReportStatementTooLarge(cx, cg);
- return JS_FALSE;
- }
-
- if ((index & (index - 1)) == 0 &&
- (!(sdbase = cg->spanDeps) || index >= SPANDEPS_MIN)) {
- if (!sdbase) {
- size = SPANDEPS_SIZE_MIN;
- JS_ARENA_ALLOCATE_CAST(sdbase, JSSpanDep *, &cx->tempPool, size);
- } else {
- size = SPANDEPS_SIZE(index);
- JS_ARENA_GROW_CAST(sdbase, JSSpanDep *, &cx->tempPool, size, size);
- }
- if (!sdbase)
- return JS_FALSE;
- cg->spanDeps = sdbase;
- }
-
- cg->numSpanDeps = index + 1;
- sd = cg->spanDeps + index;
- sd->top = PTRDIFF(pc, CG_BASE(cg), jsbytecode);
- sd->offset = sd->before = PTRDIFF(pc2, CG_BASE(cg), jsbytecode);
-
- if (js_CodeSpec[*pc].format & JOF_BACKPATCH) {
- /* Jump offset will be backpatched if off is a non-zero "bpdelta". */
- if (off != 0) {
- JS_ASSERT(off >= 1 + JUMP_OFFSET_LEN);
- if (off > BPDELTA_MAX) {
- ReportStatementTooLarge(cx, cg);
- return JS_FALSE;
- }
- }
- SD_SET_BPDELTA(sd, off);
- } else if (off == 0) {
- /* Jump offset will be patched directly, without backpatch chaining. */
- SD_SET_TARGET(sd, NULL);
- } else {
- /* The jump offset in off is non-zero, therefore it's already known. */
- if (!SetSpanDepTarget(cx, cg, sd, off))
- return JS_FALSE;
- }
-
- if (index > SPANDEP_INDEX_MAX)
- index = SPANDEP_INDEX_HUGE;
- SET_SPANDEP_INDEX(pc2, index);
- return JS_TRUE;
-}
-
-static JSBool
-BuildSpanDepTable(JSContext *cx, JSCodeGenerator *cg)
-{
- jsbytecode *pc, *end;
- JSOp op;
- const JSCodeSpec *cs;
- ptrdiff_t len, off;
-
- pc = CG_BASE(cg);
- end = CG_NEXT(cg);
- while (pc < end) {
- op = (JSOp)*pc;
- cs = &js_CodeSpec[op];
- len = (ptrdiff_t)cs->length;
-
- switch (cs->format & JOF_TYPEMASK) {
- case JOF_JUMP:
- off = GET_JUMP_OFFSET(pc);
- if (!AddSpanDep(cx, cg, pc, pc, off))
- return JS_FALSE;
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JOF_TABLESWITCH:
- {
- jsbytecode *pc2;
- jsint i, low, high;
-
- pc2 = pc;
- off = GET_JUMP_OFFSET(pc2);
- if (!AddSpanDep(cx, cg, pc, pc2, off))
- return JS_FALSE;
- pc2 += JUMP_OFFSET_LEN;
- low = GET_JUMP_OFFSET(pc2);
- pc2 += JUMP_OFFSET_LEN;
- high = GET_JUMP_OFFSET(pc2);
- pc2 += JUMP_OFFSET_LEN;
- for (i = low; i <= high; i++) {
- off = GET_JUMP_OFFSET(pc2);
- if (!AddSpanDep(cx, cg, pc, pc2, off))
- return JS_FALSE;
- pc2 += JUMP_OFFSET_LEN;
- }
- len = 1 + pc2 - pc;
- break;
- }
-
- case JOF_LOOKUPSWITCH:
- {
- jsbytecode *pc2;
- jsint npairs;
-
- pc2 = pc;
- off = GET_JUMP_OFFSET(pc2);
- if (!AddSpanDep(cx, cg, pc, pc2, off))
- return JS_FALSE;
- pc2 += JUMP_OFFSET_LEN;
- npairs = (jsint) GET_ATOM_INDEX(pc2);
- pc2 += ATOM_INDEX_LEN;
- while (npairs) {
- pc2 += ATOM_INDEX_LEN;
- off = GET_JUMP_OFFSET(pc2);
- if (!AddSpanDep(cx, cg, pc, pc2, off))
- return JS_FALSE;
- pc2 += JUMP_OFFSET_LEN;
- npairs--;
- }
- len = 1 + pc2 - pc;
- break;
- }
-#endif /* JS_HAS_SWITCH_STATEMENT */
- }
-
- pc += len;
- }
-
- return JS_TRUE;
-}
-
-static JSSpanDep *
-GetSpanDep(JSCodeGenerator *cg, jsbytecode *pc)
-{
- uintN index;
- ptrdiff_t offset;
- int lo, hi, mid;
- JSSpanDep *sd;
-
- index = GET_SPANDEP_INDEX(pc);
- if (index != SPANDEP_INDEX_HUGE)
- return cg->spanDeps + index;
-
- offset = PTRDIFF(pc, CG_BASE(cg), jsbytecode);
- lo = 0;
- hi = cg->numSpanDeps - 1;
- while (lo <= hi) {
- mid = (lo + hi) / 2;
- sd = cg->spanDeps + mid;
- if (sd->before == offset)
- return sd;
- if (sd->before < offset)
- lo = mid + 1;
- else
- hi = mid - 1;
- }
-
- JS_ASSERT(0);
- return NULL;
-}
-
-static JSBool
-SetBackPatchDelta(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
- ptrdiff_t delta)
-{
- JSSpanDep *sd;
-
- JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
- if (!cg->spanDeps && delta < JUMP_OFFSET_MAX) {
- SET_JUMP_OFFSET(pc, delta);
- return JS_TRUE;
- }
-
- if (delta > BPDELTA_MAX) {
- ReportStatementTooLarge(cx, cg);
- return JS_FALSE;
- }
-
- if (!cg->spanDeps && !BuildSpanDepTable(cx, cg))
- return JS_FALSE;
-
- sd = GetSpanDep(cg, pc);
- JS_ASSERT(SD_GET_BPDELTA(sd) == 0);
- SD_SET_BPDELTA(sd, delta);
- return JS_TRUE;
-}
-
-static void
-UpdateJumpTargets(JSJumpTarget *jt, ptrdiff_t pivot, ptrdiff_t delta)
-{
- if (jt->offset > pivot) {
- jt->offset += delta;
- if (jt->kids[JT_LEFT])
- UpdateJumpTargets(jt->kids[JT_LEFT], pivot, delta);
- }
- if (jt->kids[JT_RIGHT])
- UpdateJumpTargets(jt->kids[JT_RIGHT], pivot, delta);
-}
-
-static JSSpanDep *
-FindNearestSpanDep(JSCodeGenerator *cg, ptrdiff_t offset, int lo,
- JSSpanDep *guard)
-{
- int num, hi, mid;
- JSSpanDep *sdbase, *sd;
-
- num = cg->numSpanDeps;
- JS_ASSERT(num > 0);
- hi = num - 1;
- sdbase = cg->spanDeps;
- while (lo <= hi) {
- mid = (lo + hi) / 2;
- sd = sdbase + mid;
- if (sd->before == offset)
- return sd;
- if (sd->before < offset)
- lo = mid + 1;
- else
- hi = mid - 1;
- }
- if (lo == num)
- return guard;
- sd = sdbase + lo;
- JS_ASSERT(sd->before >= offset && (lo == 0 || sd[-1].before < offset));
- return sd;
-}
-
-static void
-FreeJumpTargets(JSCodeGenerator *cg, JSJumpTarget *jt)
-{
- if (jt->kids[JT_LEFT])
- FreeJumpTargets(cg, jt->kids[JT_LEFT]);
- if (jt->kids[JT_RIGHT])
- FreeJumpTargets(cg, jt->kids[JT_RIGHT]);
- jt->kids[JT_LEFT] = cg->jtFreeList;
- cg->jtFreeList = jt;
-}
-
-static JSBool
-OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
-{
- jsbytecode *pc, *oldpc, *base, *limit, *next;
- JSSpanDep *sd, *sd2, *sdbase, *sdlimit, *sdtop, guard;
- ptrdiff_t offset, growth, delta, top, pivot, span, length, target;
- JSBool done;
- JSOp op;
- uint32 type;
- size_t size, incr;
- jssrcnote *sn, *snlimit;
- JSSrcNoteSpec *spec;
- uintN i, n, noteIndex;
- JSTryNote *tn, *tnlimit;
-#ifdef DEBUG_brendan
- int passes = 0;
-#endif
-
- base = CG_BASE(cg);
- sdbase = cg->spanDeps;
- sdlimit = sdbase + cg->numSpanDeps;
- offset = CG_OFFSET(cg);
- growth = 0;
-
- do {
- done = JS_TRUE;
- delta = 0;
- top = pivot = -1;
- sdtop = NULL;
- pc = NULL;
- op = JSOP_NOP;
- type = 0;
-#ifdef DEBUG_brendan
- passes++;
-#endif
-
- for (sd = sdbase; sd < sdlimit; sd++) {
- JS_ASSERT(JT_HAS_TAG(sd->target));
- sd->offset += delta;
-
- if (sd->top != top) {
- sdtop = sd;
- top = sd->top;
- JS_ASSERT(top == sd->before);
- pivot = sd->offset;
- pc = base + top;
- op = (JSOp) *pc;
- type = (js_CodeSpec[op].format & JOF_TYPEMASK);
- if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
- /*
- * We already extended all the jump offset operands for
- * the opcode at sd->top. Jumps and branches have only
- * one jump offset operand, but switches have many, all
- * of which are adjacent in cg->spanDeps.
- */
- continue;
- }
-
- JS_ASSERT(type == JOF_JUMP ||
- type == JOF_TABLESWITCH ||
- type == JOF_LOOKUPSWITCH);
- }
-
- if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
- span = SD_TARGET_OFFSET(sd) - pivot;
- if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
- ptrdiff_t deltaFromTop = 0;
-
- done = JS_FALSE;
-
- switch (op) {
- case JSOP_GOTO: op = JSOP_GOTOX; break;
- case JSOP_IFEQ: op = JSOP_IFEQX; break;
- case JSOP_IFNE: op = JSOP_IFNEX; break;
- case JSOP_OR: op = JSOP_ORX; break;
- case JSOP_AND: op = JSOP_ANDX; break;
- case JSOP_GOSUB: op = JSOP_GOSUBX; break;
- case JSOP_CASE: op = JSOP_CASEX; break;
- case JSOP_DEFAULT: op = JSOP_DEFAULTX; break;
- case JSOP_TABLESWITCH: op = JSOP_TABLESWITCHX; break;
- case JSOP_LOOKUPSWITCH: op = JSOP_LOOKUPSWITCHX; break;
- default: JS_ASSERT(0);
- }
- *pc = (jsbytecode) op;
-
- for (sd2 = sdtop; sd2 < sdlimit && sd2->top == top; sd2++) {
- if (sd2 <= sd) {
- /*
- * sd2->offset already includes delta as it stood
- * before we entered this loop, but it must also
- * include the delta relative to top due to all the
- * extended jump offset immediates for the opcode
- * starting at top, which we extend in this loop.
- *
- * If there is only one extended jump offset, then
- * sd2->offset won't change and this for loop will
- * iterate once only.
- */
- sd2->offset += deltaFromTop;
- deltaFromTop += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
- } else {
- /*
- * sd2 comes after sd, and won't be revisited by
- * the outer for loop, so we have to increase its
- * offset by delta, not merely by deltaFromTop.
- */
- sd2->offset += delta;
- }
-
- delta += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
- UpdateJumpTargets(cg->jumpTargets, sd2->offset,
- JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
- }
- sd = sd2 - 1;
- }
- }
- }
-
- growth += delta;
- } while (!done);
-
- if (growth) {
-#ifdef DEBUG_brendan
- printf("%s:%u: %u/%u jumps extended in %d passes (%d=%d+%d)\n",
- cg->filename ? cg->filename : "stdin", cg->firstLine,
- growth / (JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN), cg->numSpanDeps,
- passes, offset + growth, offset, growth);
-#endif
-
- /*
- * Ensure that we have room for the extended jumps, but don't round up
- * to a power of two -- we're done generating code, so we cut to fit.
- */
- limit = CG_LIMIT(cg);
- length = offset + growth;
- next = base + length;
- if (next > limit) {
- JS_ASSERT(length > BYTECODE_CHUNK);
- size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode));
- incr = BYTECODE_SIZE(length) - size;
- JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
- if (!base) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- CG_BASE(cg) = base;
- CG_LIMIT(cg) = next = base + length;
- }
- CG_NEXT(cg) = next;
-
- /*
- * Set up a fake span dependency record to guard the end of the code
- * being generated. This guard record is returned as a fencepost by
- * FindNearestSpanDep if there is no real spandep at or above a given
- * unextended code offset.
- */
- guard.top = -1;
- guard.offset = offset + growth;
- guard.before = offset;
- guard.target = NULL;
- }
-
- /*
- * Now work backwards through the span dependencies, copying chunks of
- * bytecode between each extended jump toward the end of the grown code
- * space, and restoring immediate offset operands for all jump bytecodes.
- * The first chunk of bytecodes, starting at base and ending at the first
- * extended jump offset (NB: this chunk includes the operation bytecode
- * just before that immediate jump offset), doesn't need to be copied.
- */
- JS_ASSERT(sd == sdlimit);
- top = -1;
- while (--sd >= sdbase) {
- if (sd->top != top) {
- top = sd->top;
- op = (JSOp) base[top];
- type = (js_CodeSpec[op].format & JOF_TYPEMASK);
-
- for (sd2 = sd - 1; sd2 >= sdbase && sd2->top == top; sd2--)
- continue;
- sd2++;
- pivot = sd2->offset;
- JS_ASSERT(top == sd2->before);
- }
-
- oldpc = base + sd->before;
- span = SD_TARGET_OFFSET(sd) - pivot;
-
- /*
- * If this jump didn't need to be extended, restore its span immediate
- * offset operand now, overwriting the index of sd within cg->spanDeps
- * that was stored temporarily after *pc when BuildSpanDepTable ran.
- *
- * Note that span might fit in 16 bits even for an extended jump op,
- * if the op has multiple span operands, not all of which overflowed
- * (e.g. JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH where some cases are in
- * range for a short jump, but others are not).
- */
- if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
- JS_ASSERT(JUMP_OFFSET_MIN <= span && span <= JUMP_OFFSET_MAX);
- SET_JUMP_OFFSET(oldpc, span);
- continue;
- }
-
- /*
- * Set up parameters needed to copy the next run of bytecode starting
- * at offset (which is a cursor into the unextended, original bytecode
- * vector), down to sd->before (a cursor of the same scale as offset,
- * it's the index of the original jump pc). Reuse delta to count the
- * nominal number of bytes to copy.
- */
- pc = base + sd->offset;
- delta = offset - sd->before;
- JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
-
- /*
- * Don't bother copying the jump offset we're about to reset, but do
- * copy the bytecode at oldpc (which comes just before its immediate
- * jump offset operand), on the next iteration through the loop, by
- * including it in offset's new value.
- */
- offset = sd->before + 1;
- size = BYTECODE_SIZE(delta - (1 + JUMP_OFFSET_LEN));
- if (size) {
- memmove(pc + 1 + JUMPX_OFFSET_LEN,
- oldpc + 1 + JUMP_OFFSET_LEN,
- size);
- }
-
- SET_JUMPX_OFFSET(pc, span);
- }
-
- if (growth) {
- /*
- * Fix source note deltas. Don't hardwire the delta fixup adjustment,
- * even though currently it must be JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN
- * at each sd that moved. The future may bring different offset sizes
- * for span-dependent instruction operands. However, we fix only main
- * notes here, not prolog notes -- we know that prolog opcodes are not
- * span-dependent, and aren't likely ever to be.
- */
- offset = growth = 0;
- sd = sdbase;
- for (sn = cg->main.notes, snlimit = sn + cg->main.noteCount;
- sn < snlimit;
- sn = SN_NEXT(sn)) {
- /*
- * Recall that the offset of a given note includes its delta, and
- * tells the offset of the annotated bytecode from the main entry
- * point of the script.
- */
- offset += SN_DELTA(sn);
- while (sd < sdlimit && sd->before < offset) {
- /*
- * To compute the delta to add to sn, we need to look at the
- * spandep after sd, whose offset - (before + growth) tells by
- * how many bytes sd's instruction grew.
- */
- sd2 = sd + 1;
- if (sd2 == sdlimit)
- sd2 = &guard;
- delta = sd2->offset - (sd2->before + growth);
- if (delta > 0) {
- JS_ASSERT(delta == JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
- sn = js_AddToSrcNoteDelta(cx, cg, sn, delta);
- if (!sn)
- return JS_FALSE;
- snlimit = cg->main.notes + cg->main.noteCount;
- growth += delta;
- }
- sd++;
- }
-
- /*
- * If sn has span-dependent offset operands, check whether each
- * covers further span-dependencies, and increase those operands
- * accordingly. Some source notes measure offset not from the
- * annotated pc, but from that pc plus some small bias. NB: we
- * assume that spec->offsetBias can't itself span span-dependent
- * instructions!
- */
- spec = &js_SrcNoteSpec[SN_TYPE(sn)];
- if (spec->isSpanDep) {
- pivot = offset + spec->offsetBias;
- n = spec->arity;
- for (i = 0; i < n; i++) {
- span = js_GetSrcNoteOffset(sn, i);
- if (span == 0)
- continue;
- target = pivot + span * spec->isSpanDep;
- sd2 = FindNearestSpanDep(cg, target,
- (target >= pivot)
- ? sd - sdbase
- : 0,
- &guard);
-
- /*
- * Increase target by sd2's before-vs-after offset delta,
- * which is absolute (i.e., relative to start of script,
- * as is target). Recompute the span by subtracting its
- * adjusted pivot from target.
- */
- target += sd2->offset - sd2->before;
- span = target - (pivot + growth);
- span *= spec->isSpanDep;
- noteIndex = sn - cg->main.notes;
- if (!js_SetSrcNoteOffset(cx, cg, noteIndex, i, span))
- return JS_FALSE;
- sn = cg->main.notes + noteIndex;
- snlimit = cg->main.notes + cg->main.noteCount;
- }
- }
- }
-
- /*
- * Fix try/catch notes (O(numTryNotes * log2(numSpanDeps)), but it's
- * not clear how we can beat that).
- */
- for (tn = cg->tryBase, tnlimit = cg->tryNext; tn < tnlimit; tn++) {
- /*
- * First, look for the nearest span dependency at/above tn->start.
- * There may not be any such spandep, in which case the guard will
- * be returned.
- */
- offset = tn->start;
- sd = FindNearestSpanDep(cg, offset, 0, &guard);
- delta = sd->offset - sd->before;
- tn->start = offset + delta;
-
- /*
- * Next, find the nearest spandep at/above tn->start + tn->length.
- * Use its delta minus tn->start's delta to increase tn->length.
- */
- length = tn->length;
- sd2 = FindNearestSpanDep(cg, offset + length, sd - sdbase, &guard);
- if (sd2 != sd)
- tn->length = length + sd2->offset - sd2->before - delta;
-
- /*
- * Finally, adjust tn->catchStart upward only if it is non-zero,
- * and provided there are spandeps below it that grew.
- */
- offset = tn->catchStart;
- if (offset != 0) {
- sd = FindNearestSpanDep(cg, offset, sd2 - sdbase, &guard);
- tn->catchStart = offset + sd->offset - sd->before;
- }
- }
- }
-
-#ifdef DEBUG_brendan
- {
- uintN bigspans = 0;
- top = -1;
- for (sd = sdbase; sd < sdlimit; sd++) {
- offset = sd->offset;
-
- /* NB: sd->top cursors into the original, unextended bytecode vector. */
- if (sd->top != top) {
- JS_ASSERT(top == -1 ||
- !JOF_TYPE_IS_EXTENDED_JUMP(type) ||
- bigspans != 0);
- bigspans = 0;
- top = sd->top;
- JS_ASSERT(top == sd->before);
- op = (JSOp) base[offset];
- type = (js_CodeSpec[op].format & JOF_TYPEMASK);
- JS_ASSERT(type == JOF_JUMP ||
- type == JOF_JUMPX ||
- type == JOF_TABLESWITCH ||
- type == JOF_TABLESWITCHX ||
- type == JOF_LOOKUPSWITCH ||
- type == JOF_LOOKUPSWITCHX);
- pivot = offset;
- }
-
- pc = base + offset;
- if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
- span = GET_JUMPX_OFFSET(pc);
- if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
- bigspans++;
- } else {
- JS_ASSERT(type == JOF_TABLESWITCHX ||
- type == JOF_LOOKUPSWITCHX);
- }
- } else {
- span = GET_JUMP_OFFSET(pc);
- }
- JS_ASSERT(SD_TARGET_OFFSET(sd) == pivot + span);
- }
- JS_ASSERT(!JOF_TYPE_IS_EXTENDED_JUMP(type) || bigspans != 0);
- }
-#endif
-
- /*
- * Reset so we optimize at most once -- cg may be used for further code
- * generation of successive, independent, top-level statements. No jump
- * can span top-level statements, because JS lacks goto.
- */
- size = SPANDEPS_SIZE(JS_BIT(JS_CeilingLog2(cg->numSpanDeps)));
- JS_ArenaFreeAllocation(&cx->tempPool, cg->spanDeps,
- JS_MAX(size, SPANDEPS_SIZE_MIN));
- cg->spanDeps = NULL;
- FreeJumpTargets(cg, cg->jumpTargets);
- cg->jumpTargets = NULL;
- cg->numSpanDeps = cg->numJumpTargets = 0;
- return JS_TRUE;
-}
-
-static JSBool
-EmitJump(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t off)
-{
- ptrdiff_t jmp;
- jsbytecode *pc;
-
- if (off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off) {
- if (!cg->spanDeps && !BuildSpanDepTable(cx, cg))
- return JS_FALSE;
- }
-
- jmp = js_Emit3(cx, cg, op, JUMP_OFFSET_HI(off), JUMP_OFFSET_LO(off));
- if (jmp >= 0 && cg->spanDeps) {
- pc = CG_CODE(cg, jmp);
- if (!AddSpanDep(cx, cg, pc, pc, off))
- return JS_FALSE;
- }
- return jmp;
-}
-
-static ptrdiff_t
-GetJumpOffset(JSCodeGenerator *cg, jsbytecode *pc)
-{
- JSSpanDep *sd;
- JSJumpTarget *jt;
- ptrdiff_t top;
-
- if (!cg->spanDeps)
- return GET_JUMP_OFFSET(pc);
-
- sd = GetSpanDep(cg, pc);
- jt = sd->target;
- if (!JT_HAS_TAG(jt))
- return JT_TO_BPDELTA(jt);
-
- top = sd->top;
- while (--sd >= cg->spanDeps && sd->top == top)
- continue;
- sd++;
- return JT_CLR_TAG(jt)->offset - sd->offset;
-}
-
-JSBool
-js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
- ptrdiff_t off)
-{
- if (!cg->spanDeps) {
- if (JUMP_OFFSET_MIN <= off && off <= JUMP_OFFSET_MAX) {
- SET_JUMP_OFFSET(pc, off);
- return JS_TRUE;
- }
-
- if (!BuildSpanDepTable(cx, cg))
- return JS_FALSE;
- }
-
- return SetSpanDepTarget(cx, cg, GetSpanDep(cg, pc), off);
-}
-
-JSBool
-js_InWithStatement(JSTreeContext *tc)
-{
- JSStmtInfo *stmt;
-
- for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
- if (stmt->type == STMT_WITH)
- return JS_TRUE;
- }
- return JS_FALSE;
-}
-
-JSBool
-js_InCatchBlock(JSTreeContext *tc, JSAtom *atom)
-{
- JSStmtInfo *stmt;
-
- for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
- if (stmt->type == STMT_CATCH && stmt->label == atom)
- return JS_TRUE;
- }
- return JS_FALSE;
-}
-
-void
-js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
- ptrdiff_t top)
-{
- stmt->type = type;
- SET_STATEMENT_TOP(stmt, top);
- stmt->label = NULL;
- stmt->down = tc->topStmt;
- tc->topStmt = stmt;
-}
-
-/*
- * Emit a backpatch op with offset pointing to the previous jump of this type,
- * so that we can walk back up the chain fixing up the op and jump offset.
- */
-#define EMIT_BACKPATCH_OP(cx, cg, last, op, jmp) \
- JS_BEGIN_MACRO \
- ptrdiff_t offset, delta; \
- offset = CG_OFFSET(cg); \
- delta = offset - (last); \
- last = offset; \
- JS_ASSERT(delta > 0); \
- jmp = EmitJump((cx), (cg), (op), (delta)); \
- JS_END_MACRO
-
-/* Emit additional bytecode(s) for non-local jumps. */
-static JSBool
-EmitNonLocalJumpFixup(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
- JSOp *returnop)
-{
- intN depth;
- JSStmtInfo *stmt;
- ptrdiff_t jmp;
-
- /*
- * Return from within a try block that has a finally clause must be split
- * into two ops: JSOP_SETRVAL, to pop the r.v. and store it in fp->rval;
- * and JSOP_RETRVAL, which makes control flow go back to the caller, who
- * picks up fp->rval as usual. Otherwise, the stack will be unbalanced
- * when executing the finally clause.
- *
- * We mutate *returnop once only if we find an enclosing try-block (viz,
- * STMT_FINALLY) to ensure that we emit just one JSOP_SETRVAL before one
- * or more JSOP_GOSUBs and other fixup opcodes emitted by this function.
- * Our caller (the TOK_RETURN case of js_EmitTree) then emits *returnop.
- * The fixup opcodes and gosubs must interleave in the proper order, from
- * inner statement to outer, so that finally clauses run at the correct
- * stack depth.
- */
- if (returnop) {
- JS_ASSERT(*returnop == JSOP_RETURN);
- for (stmt = cg->treeContext.topStmt; stmt != toStmt;
- stmt = stmt->down) {
- if (stmt->type == STMT_FINALLY) {
- if (js_Emit1(cx, cg, JSOP_SETRVAL) < 0)
- return JS_FALSE;
- *returnop = JSOP_RETRVAL;
- break;
- }
- }
-
- /*
- * If there are no try-with-finally blocks open around this return
- * statement, we can generate a return forthwith and skip generating
- * any fixup code.
- */
- if (*returnop == JSOP_RETURN)
- return JS_TRUE;
- }
-
- /*
- * The non-local jump fixup we emit will unbalance cg->stackDepth, because
- * the fixup replicates balanced code such as JSOP_LEAVEWITH emitted at the
- * end of a with statement, so we save cg->stackDepth here and restore it
- * just before a successful return.
- */
- depth = cg->stackDepth;
- for (stmt = cg->treeContext.topStmt; stmt != toStmt; stmt = stmt->down) {
- switch (stmt->type) {
- case STMT_FINALLY:
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- EMIT_BACKPATCH_OP(cx, cg, stmt->gosub, JSOP_BACKPATCH_PUSH, jmp);
- if (jmp < 0)
- return JS_FALSE;
- break;
-
- case STMT_WITH:
- case STMT_CATCH:
- /* There's a With object on the stack that we need to pop. */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)
- return JS_FALSE;
- break;
-
- case STMT_FOR_IN_LOOP:
- /*
- * The iterator and the object being iterated need to be popped.
- * JSOP_POP2 isn't decompiled, so it doesn't need to be HIDDEN.
- */
- if (js_Emit1(cx, cg, JSOP_POP2) < 0)
- return JS_FALSE;
- break;
-
- case STMT_SUBROUTINE:
- /* There's a retsub pc-offset on the stack that we need to pop. */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_POP) < 0)
- return JS_FALSE;
- break;
-
- default:;
- }
- }
-
- cg->stackDepth = depth;
- return JS_TRUE;
-}
-
-static ptrdiff_t
-EmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
- ptrdiff_t *last, JSAtomListElement *label, JSSrcNoteType noteType)
-{
- intN index;
- ptrdiff_t jmp;
-
- if (!EmitNonLocalJumpFixup(cx, cg, toStmt, NULL))
- return -1;
-
- if (label) {
- index = js_NewSrcNote(cx, cg, noteType);
- if (index < 0)
- return -1;
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)index, 0,
- (ptrdiff_t) ALE_INDEX(label))) {
- return -1;
- }
- } else if (noteType != SRC_NULL) {
- if (js_NewSrcNote(cx, cg, noteType) < 0)
- return -1;
- }
-
- EMIT_BACKPATCH_OP(cx, cg, *last, JSOP_BACKPATCH, jmp);
- return jmp;
-}
-
-static JSBool
-BackPatch(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t last,
- jsbytecode *target, jsbytecode op)
-{
- jsbytecode *pc, *stop;
- ptrdiff_t delta, span;
-
- pc = CG_CODE(cg, last);
- stop = CG_CODE(cg, -1);
- while (pc != stop) {
- delta = GetJumpOffset(cg, pc);
- span = PTRDIFF(target, pc, jsbytecode);
- CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, span);
-
- /*
- * Set *pc after jump offset in case bpdelta didn't overflow, but span
- * does (if so, CHECK_AND_SET_JUMP_OFFSET might call BuildSpanDepTable
- * and need to see the JSOP_BACKPATCH* op at *pc).
- */
- *pc = op;
- pc -= delta;
- }
- return JS_TRUE;
-}
-
-void
-js_PopStatement(JSTreeContext *tc)
-{
- tc->topStmt = tc->topStmt->down;
-}
-
-JSBool
-js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg)
-{
- JSStmtInfo *stmt;
-
- stmt = cg->treeContext.topStmt;
- if (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) ||
- !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update),
- JSOP_GOTO)) {
- return JS_FALSE;
- }
- js_PopStatement(&cg->treeContext);
- return JS_TRUE;
-}
-
-/*
- * Emit a bytecode and its 2-byte constant (atom) index immediate operand.
- * NB: We use cx and cg from our caller's lexical environment, and return
- * false on error.
- */
-#define EMIT_ATOM_INDEX_OP(op, atomIndex) \
- JS_BEGIN_MACRO \
- if (js_Emit3(cx, cg, op, ATOM_INDEX_HI(atomIndex), \
- ATOM_INDEX_LO(atomIndex)) < 0) { \
- return JS_FALSE; \
- } \
- JS_END_MACRO
-
-static JSBool
-EmitAtomOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
-{
- JSAtomListElement *ale;
-
- ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale));
- return JS_TRUE;
-}
-
-/*
- * This routine tries to optimize name gets and sets to stack slot loads and
- * stores, given the variables object and scope chain in cx's top frame, the
- * compile-time context in tc, and a TOK_NAME node pn. It returns false on
- * error, true on success.
- *
- * The caller can inspect pn->pn_slot for a non-negative slot number to tell
- * whether optimization occurred, in which case LookupArgOrVar also updated
- * pn->pn_op. If pn->pn_slot is still -1 on return, pn->pn_op nevertheless
- * may have been optimized, e.g., from JSOP_NAME to JSOP_ARGUMENTS. Whether
- * or not pn->pn_op was modified, if this function finds an argument or local
- * variable name, pn->pn_attrs will contain the property's attributes after a
- * successful return.
- */
-static JSBool
-LookupArgOrVar(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
-{
- JSObject *obj, *pobj;
- JSClass *clasp;
- JSAtom *atom;
- JSScopeProperty *sprop;
- JSOp op;
-
- JS_ASSERT(pn->pn_type == TOK_NAME);
- if (pn->pn_slot >= 0 || pn->pn_op == JSOP_ARGUMENTS)
- return JS_TRUE;
-
- /*
- * We can't optimize if var and closure (a local function not in a larger
- * expression and not at top-level within another's body) collide.
- * XXX suboptimal: keep track of colliding names and deoptimize only those
- */
- if (tc->flags & TCF_FUN_CLOSURE_VS_VAR)
- return JS_TRUE;
-
- /*
- * We can't optimize if we're not compiling a function body, whether via
- * eval, or directly when compiling a function statement or expression.
- */
- obj = cx->fp->varobj;
- clasp = OBJ_GET_CLASS(cx, obj);
- if (clasp != &js_FunctionClass && clasp != &js_CallClass)
- return JS_TRUE;
-
- /*
- * We can't optimize if we're in an eval called inside a with statement,
- * or we're compiling a with statement and its body, or we're in a catch
- * block whose exception variable has the same name as pn.
- */
- atom = pn->pn_atom;
- if (cx->fp->scopeChain != obj ||
- js_InWithStatement(tc) ||
- js_InCatchBlock(tc, atom)) {
- return JS_TRUE;
- }
-
- /*
- * Ok, we may be able to optimize name to stack slot. Look for an argument
- * or variable property in the function, or its call object, not found in
- * any prototype object. Rewrite pn_op and update pn accordingly. NB: We
- * know that JSOP_DELNAME on an argument or variable must evaluate to
- * false, due to JSPROP_PERMANENT.
- */
- if (!js_LookupProperty(cx, obj, (jsid)atom, &pobj, (JSProperty **)&sprop))
- return JS_FALSE;
- op = pn->pn_op;
- if (sprop) {
- if (pobj == obj) {
- JSPropertyOp getter = sprop->getter;
-
- if (getter == js_GetArgument) {
- switch (op) {
- case JSOP_NAME: op = JSOP_GETARG; break;
- case JSOP_SETNAME: op = JSOP_SETARG; break;
- case JSOP_INCNAME: op = JSOP_INCARG; break;
- case JSOP_NAMEINC: op = JSOP_ARGINC; break;
- case JSOP_DECNAME: op = JSOP_DECARG; break;
- case JSOP_NAMEDEC: op = JSOP_ARGDEC; break;
- case JSOP_FORNAME: op = JSOP_FORARG; break;
- case JSOP_DELNAME: op = JSOP_FALSE; break;
- default: JS_ASSERT(0);
- }
- } else if (getter == js_GetLocalVariable ||
- getter == js_GetCallVariable)
- {
- switch (op) {
- case JSOP_NAME: op = JSOP_GETVAR; break;
- case JSOP_SETNAME: op = JSOP_SETVAR; break;
- case JSOP_SETCONST: op = JSOP_SETVAR; break;
- case JSOP_INCNAME: op = JSOP_INCVAR; break;
- case JSOP_NAMEINC: op = JSOP_VARINC; break;
- case JSOP_DECNAME: op = JSOP_DECVAR; break;
- case JSOP_NAMEDEC: op = JSOP_VARDEC; break;
- case JSOP_FORNAME: op = JSOP_FORVAR; break;
- case JSOP_DELNAME: op = JSOP_FALSE; break;
- default: JS_ASSERT(0);
- }
- }
- if (op != pn->pn_op) {
- pn->pn_op = op;
- pn->pn_slot = sprop->shortid;
- }
- pn->pn_attrs = sprop->attrs;
- }
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- }
-
- if (pn->pn_slot < 0) {
- /*
- * We couldn't optimize it, so it's not an arg or local var name. Now
- * we must check for the predefined arguments variable. It may be
- * overridden by assignment, in which case the function is heavyweight
- * and the interpreter will look up 'arguments' in the function's call
- * object.
- */
- if (pn->pn_op == JSOP_NAME &&
- atom == cx->runtime->atomState.argumentsAtom) {
- pn->pn_op = JSOP_ARGUMENTS;
- return JS_TRUE;
- }
-
- tc->flags |= TCF_FUN_USES_NONLOCALS;
- }
- return JS_TRUE;
-}
-
-/*
- * If pn contains a useful expression, return true with *answer set to true.
- * If pn contains a useless expression, return true with *answer set to false.
- * Return false on error.
- *
- * The caller should initialize *answer to false and invoke this function on
- * an expression statement or similar subtree to decide whether the tree could
- * produce code that has any side effects. For an expression statement, we
- * define useless code as code with no side effects, because the main effect,
- * the value left on the stack after the code executes, will be discarded by a
- * pop bytecode.
- */
-static JSBool
-CheckSideEffects(JSContext *cx, JSTreeContext *tc, JSParseNode *pn,
- JSBool *answer)
-{
- JSBool ok;
- JSFunction *fun;
- JSParseNode *pn2;
-
- ok = JS_TRUE;
- if (!pn || *answer)
- return ok;
-
- switch (pn->pn_arity) {
- case PN_FUNC:
- /*
- * A named function is presumed useful: we can't yet know that it is
- * not called. The side effects are the creation of a scope object
- * to parent this function object, and the binding of the function's
- * name in that scope object. See comments at case JSOP_NAMEDFUNOBJ:
- * in jsinterp.c.
- */
- fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom));
- if (fun->atom)
- *answer = JS_TRUE;
- break;
-
- case PN_LIST:
- if (pn->pn_type == TOK_NEW ||
- pn->pn_type == TOK_LP ||
- pn->pn_type == TOK_LB) {
- /*
- * All invocation operations (construct: TOK_NEW, call: TOK_LP)
- * are presumed to be useful, because they may have side effects
- * even if their main effect (their return value) is discarded.
- *
- * TOK_LB binary trees of 3 or more nodes are flattened into lists
- * to avoid too much recursion. All such lists must be presumed
- * to be useful because each index operation could invoke a getter
- * (the JSOP_ARGUMENTS special case below, in the PN_BINARY case,
- * does not apply here: arguments[i][j] might invoke a getter).
- */
- *answer = JS_TRUE;
- } else {
- for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next)
- ok &= CheckSideEffects(cx, tc, pn2, answer);
- }
- break;
-
- case PN_TERNARY:
- ok = CheckSideEffects(cx, tc, pn->pn_kid1, answer) &&
- CheckSideEffects(cx, tc, pn->pn_kid2, answer) &&
- CheckSideEffects(cx, tc, pn->pn_kid3, answer);
- break;
-
- case PN_BINARY:
- if (pn->pn_type == TOK_ASSIGN) {
- /*
- * Assignment is presumed to be useful, even if the next operation
- * is another assignment overwriting this one's ostensible effect,
- * because the left operand may be a property with a setter that
- * has side effects.
- */
- *answer = JS_TRUE;
- } else {
- if (pn->pn_type == TOK_LB) {
- pn2 = pn->pn_left;
- if (pn2->pn_type == TOK_NAME && !LookupArgOrVar(cx, tc, pn2))
- return JS_FALSE;
- if (pn2->pn_op != JSOP_ARGUMENTS) {
- /*
- * Any indexed property reference could call a getter with
- * side effects, except for arguments[i] where arguments is
- * unambiguous.
- */
- *answer = JS_TRUE;
- }
- }
- ok = CheckSideEffects(cx, tc, pn->pn_left, answer) &&
- CheckSideEffects(cx, tc, pn->pn_right, answer);
- }
- break;
-
- case PN_UNARY:
- if (pn->pn_type == TOK_INC || pn->pn_type == TOK_DEC ||
- pn->pn_type == TOK_DELETE ||
- pn->pn_type == TOK_THROW ||
- pn->pn_type == TOK_DEFSHARP) {
- /* All these operations have effects that we must commit. */
- *answer = JS_TRUE;
- } else {
- ok = CheckSideEffects(cx, tc, pn->pn_kid, answer);
- }
- break;
-
- case PN_NAME:
- if (pn->pn_type == TOK_NAME) {
- if (!LookupArgOrVar(cx, tc, pn))
- return JS_FALSE;
- if (pn->pn_slot < 0 && pn->pn_op != JSOP_ARGUMENTS) {
- /*
- * Not an argument or local variable use, so this expression
- * could invoke a getter that has side effects.
- */
- *answer = JS_TRUE;
- }
- }
- pn2 = pn->pn_expr;
- if (pn->pn_type == TOK_DOT && pn2->pn_type == TOK_NAME) {
- if (!LookupArgOrVar(cx, tc, pn2))
- return JS_FALSE;
- if (!(pn2->pn_op == JSOP_ARGUMENTS &&
- pn->pn_atom == cx->runtime->atomState.lengthAtom)) {
- /*
- * Any dotted property reference could call a getter, except
- * for arguments.length where arguments is unambiguous.
- */
- *answer = JS_TRUE;
- }
- }
- ok = CheckSideEffects(cx, tc, pn2, answer);
- break;
-
- case PN_NULLARY:
- if (pn->pn_type == TOK_DEBUGGER)
- *answer = JS_TRUE;
- break;
- }
- return ok;
-}
-
-static JSBool
-EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
-{
- JSParseNode *pn2, *pndot, *pnup, *pndown;
- ptrdiff_t top;
- JSAtomListElement *ale;
-
- pn2 = pn->pn_expr;
- if (op == JSOP_GETPROP &&
- pn->pn_type == TOK_DOT &&
- pn2->pn_type == TOK_NAME) {
- /* Try to optimize arguments.length into JSOP_ARGCNT. */
- if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
- return JS_FALSE;
- if (pn2->pn_op == JSOP_ARGUMENTS &&
- pn->pn_atom == cx->runtime->atomState.lengthAtom) {
- return js_Emit1(cx, cg, JSOP_ARGCNT) >= 0;
- }
- }
-
- /*
- * If the object operand is also a dotted property reference, reverse the
- * list linked via pn_expr temporarily so we can iterate over it from the
- * bottom up (reversing again as we go), to avoid excessive recursion.
- */
- if (pn2->pn_type == TOK_DOT) {
- pndot = pn2;
- pnup = NULL;
- top = CG_OFFSET(cg);
- for (;;) {
- /* Reverse pndot->pn_expr to point up, not down. */
- pndot->pn_offset = top;
- pndown = pndot->pn_expr;
- pndot->pn_expr = pnup;
- if (pndown->pn_type != TOK_DOT)
- break;
- pnup = pndot;
- pndot = pndown;
- }
-
- /* pndown is a primary expression, not a dotted property reference. */
- if (!js_EmitTree(cx, cg, pndown))
- return JS_FALSE;
-
- do {
- /* Walk back up the list, emitting annotated name ops. */
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE,
- CG_OFFSET(cg) - pndown->pn_offset) < 0) {
- return JS_FALSE;
- }
- ale = js_IndexAtom(cx, pndot->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(pndot->pn_op, ALE_INDEX(ale));
-
- /* Reverse the pn_expr link again. */
- pnup = pndot->pn_expr;
- pndot->pn_expr = pndown;
- pndown = pndot;
- } while ((pndot = pnup) != NULL);
- } else {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- }
-
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - pn2->pn_offset) < 0)
- return JS_FALSE;
- if (!pn->pn_atom) {
- JS_ASSERT(op == JSOP_IMPORTALL);
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- } else {
- ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale));
- }
- return JS_TRUE;
-}
-
-static JSBool
-EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
-{
- ptrdiff_t top;
- JSParseNode *left, *right, *next;
- jsint slot;
-
- top = CG_OFFSET(cg);
- if (pn->pn_arity == PN_LIST) {
- /* Left-associative operator chain to avoid too much recursion. */
- JS_ASSERT(pn->pn_op == JSOP_GETELEM);
- JS_ASSERT(pn->pn_count >= 3);
- left = pn->pn_head;
- right = PN_LAST(pn);
- next = left->pn_next;
- JS_ASSERT(next != right);
-
- /*
- * Try to optimize arguments[0][j]... into JSOP_ARGSUB<0> followed by
- * one or more index expression and JSOP_GETELEM op pairs.
- */
- if (left->pn_type == TOK_NAME && next->pn_type == TOK_NUMBER) {
- if (!LookupArgOrVar(cx, &cg->treeContext, left))
- return JS_FALSE;
- if (left->pn_op == JSOP_ARGUMENTS &&
- JSDOUBLE_IS_INT(next->pn_dval, slot) &&
- (jsuint)slot < ATOM_INDEX_LIMIT) {
- left->pn_offset = next->pn_offset = top;
- EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot);
- left = next;
- next = left->pn_next;
- }
- }
-
- /*
- * Check whether we generated JSOP_ARGSUB, just above, and have only
- * one more index expression to emit. Given arguments[0][j], we must
- * skip the while loop altogether, falling through to emit code for j
- * (in the subtree referenced by right), followed by the annotated op,
- * at the bottom of this function.
- */
- JS_ASSERT(next != right || pn->pn_count == 3);
- if (left == pn->pn_head) {
- if (!js_EmitTree(cx, cg, left))
- return JS_FALSE;
- }
- while (next != right) {
- if (!js_EmitTree(cx, cg, next))
- return JS_FALSE;
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
- return JS_FALSE;
- next = next->pn_next;
- }
- } else {
- JS_ASSERT(pn->pn_arity == PN_BINARY);
- left = pn->pn_left;
- right = pn->pn_right;
-
- /* Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. */
- if (op == JSOP_GETELEM &&
- left->pn_type == TOK_NAME &&
- right->pn_type == TOK_NUMBER) {
- if (!LookupArgOrVar(cx, &cg->treeContext, left))
- return JS_FALSE;
- if (left->pn_op == JSOP_ARGUMENTS &&
- JSDOUBLE_IS_INT(right->pn_dval, slot) &&
- (jsuint)slot < ATOM_INDEX_LIMIT) {
- left->pn_offset = right->pn_offset = top;
- EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot);
- return JS_TRUE;
- }
- }
-
- if (!js_EmitTree(cx, cg, left))
- return JS_FALSE;
- }
- if (!js_EmitTree(cx, cg, right))
- return JS_FALSE;
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
- return JS_FALSE;
- return js_Emit1(cx, cg, op) >= 0;
-}
-
-static JSBool
-EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
-{
- jsint ival;
- jsatomid atomIndex;
- JSAtom *atom;
- JSAtomListElement *ale;
-
- if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) {
- if (ival == 0)
- return js_Emit1(cx, cg, JSOP_ZERO) >= 0;
- if (ival == 1)
- return js_Emit1(cx, cg, JSOP_ONE) >= 0;
- if ((jsuint)ival < (jsuint)ATOM_INDEX_LIMIT) {
- atomIndex = (jsatomid)ival;
- EMIT_ATOM_INDEX_OP(JSOP_UINT16, atomIndex);
- return JS_TRUE;
- }
- atom = js_AtomizeInt(cx, ival, 0);
- } else {
- atom = js_AtomizeDouble(cx, dval, 0);
- }
- if (!atom)
- return JS_FALSE;
- ale = js_IndexAtom(cx, atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_NUMBER, ALE_INDEX(ale));
- return JS_TRUE;
-}
-
-#if JS_HAS_SWITCH_STATEMENT
-static JSBool
-EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
- JSStmtInfo *stmtInfo)
-{
- JSOp switchop;
- JSBool ok, hasDefault;
- ptrdiff_t top, off, defaultOffset;
- JSParseNode *pn2, *pn3, *pn4;
- uint32 ncases, tablen;
- jsdouble d;
- jsint i, low, high;
- JSAtom *atom;
- JSAtomListElement *ale;
- intN noteIndex;
- size_t switchsize, tablesize;
- JSParseNode **table;
- jsbytecode *pc;
-
- /* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
- switchop = JSOP_TABLESWITCH;
- ok = JS_TRUE;
- hasDefault = JS_FALSE;
- defaultOffset = -1;
-
- /* Emit code for the discriminant first. */
- if (!js_EmitTree(cx, cg, pn->pn_kid1))
- return JS_FALSE;
-
- /* Switch bytecodes run from here till end of final case. */
- top = CG_OFFSET(cg);
- js_PushStatement(&cg->treeContext, stmtInfo, STMT_SWITCH, top);
-
- pn2 = pn->pn_kid2;
- ncases = pn2->pn_count;
- tablen = 0;
-
- if (ncases == 0 ||
- (ncases == 1 &&
- (hasDefault = (pn2->pn_head->pn_type == TOK_DEFAULT)))) {
- ncases = 0;
- low = 0;
- high = -1;
- } else {
-#define INTMAP_LENGTH 256
- jsbitmap intmap_space[INTMAP_LENGTH];
- jsbitmap *intmap = NULL;
- int32 intmap_bitlen = 0;
-
- low = JSVAL_INT_MAX;
- high = JSVAL_INT_MIN;
-
- for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
- if (pn3->pn_type == TOK_DEFAULT) {
- hasDefault = JS_TRUE;
- ncases--; /* one of the "cases" was the default */
- continue;
- }
-
- JS_ASSERT(pn3->pn_type == TOK_CASE);
- if (switchop == JSOP_CONDSWITCH)
- continue;
-
- pn4 = pn3->pn_left;
- switch (pn4->pn_type) {
- case TOK_NUMBER:
- d = pn4->pn_dval;
- if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
- pn3->pn_val = INT_TO_JSVAL(i);
- } else {
- atom = js_AtomizeDouble(cx, d, 0);
- if (!atom) {
- ok = JS_FALSE;
- goto release;
- }
- pn3->pn_val = ATOM_KEY(atom);
- }
- break;
- case TOK_STRING:
- pn3->pn_val = ATOM_KEY(pn4->pn_atom);
- break;
- case TOK_PRIMARY:
- if (pn4->pn_op == JSOP_TRUE) {
- pn3->pn_val = JSVAL_TRUE;
- break;
- }
- if (pn4->pn_op == JSOP_FALSE) {
- pn3->pn_val = JSVAL_FALSE;
- break;
- }
- /* FALL THROUGH */
- default:
- switchop = JSOP_CONDSWITCH;
- continue;
- }
-
- JS_ASSERT(JSVAL_IS_NUMBER(pn3->pn_val) ||
- JSVAL_IS_STRING(pn3->pn_val) ||
- JSVAL_IS_BOOLEAN(pn3->pn_val));
-
- if (switchop != JSOP_TABLESWITCH)
- continue;
- if (!JSVAL_IS_INT(pn3->pn_val)) {
- switchop = JSOP_LOOKUPSWITCH;
- continue;
- }
- i = JSVAL_TO_INT(pn3->pn_val);
- if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
- switchop = JSOP_LOOKUPSWITCH;
- continue;
- }
- if (i < low)
- low = i;
- if (high < i)
- high = i;
-
- /*
- * Check for duplicates, which require a JSOP_LOOKUPSWITCH.
- * We bias i by 65536 if it's negative, and hope that's a rare
- * case (because it requires a malloc'd bitmap).
- */
- if (i < 0)
- i += JS_BIT(16);
- if (i >= intmap_bitlen) {
- if (!intmap &&
- i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) {
- intmap = intmap_space;
- intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2;
- } else {
- /* Just grab 8K for the worst-case bitmap. */
- intmap_bitlen = JS_BIT(16);
- intmap = (jsbitmap *)
- JS_malloc(cx,
- (JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
- * sizeof(jsbitmap));
- if (!intmap) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- }
- memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
- }
- if (JS_TEST_BIT(intmap, i)) {
- switchop = JSOP_LOOKUPSWITCH;
- continue;
- }
- JS_SET_BIT(intmap, i);
- }
-
- release:
- if (intmap && intmap != intmap_space)
- JS_free(cx, intmap);
- if (!ok)
- return JS_FALSE;
-
- /*
- * Compute table length and select lookup instead if overlarge or
- * more than half-sparse.
- */
- if (switchop == JSOP_TABLESWITCH) {
- tablen = (uint32)(high - low + 1);
- if (tablen >= JS_BIT(16) || tablen > 2 * ncases)
- switchop = JSOP_LOOKUPSWITCH;
- }
- }
-
- /*
- * Emit a note with two offsets: first tells total switch code length,
- * second tells offset to first JSOP_CASE if condswitch.
- */
- noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0);
- if (noteIndex < 0)
- return JS_FALSE;
-
- if (switchop == JSOP_CONDSWITCH) {
- /*
- * 0 bytes of immediate for unoptimized ECMAv2 switch.
- */
- switchsize = 0;
- } else if (switchop == JSOP_TABLESWITCH) {
- /*
- * 3 offsets (len, low, high) before the table, 1 per entry.
- */
- switchsize = (size_t)(JUMP_OFFSET_LEN * (3 + tablen));
- } else {
- /*
- * JSOP_LOOKUPSWITCH:
- * 1 offset (len) and 1 atom index (npairs) before the table,
- * 1 atom index and 1 jump offset per entry.
- */
- switchsize = (size_t)(JUMP_OFFSET_LEN + ATOM_INDEX_LEN +
- (ATOM_INDEX_LEN + JUMP_OFFSET_LEN) * ncases);
- }
-
- /*
- * Emit switchop followed by switchsize bytes of jump or lookup table.
- *
- * If switchop is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial
- * to emit the immediate operand(s) by which bytecode readers such as
- * BuildSpanDepTable discover the length of the switch opcode *before*
- * calling js_SetJumpOffset (which may call BuildSpanDepTable). It's
- * also important to zero all unknown jump offset immediate operands,
- * so they can be converted to span dependencies with null targets to
- * be computed later (js_EmitN zeros switchsize bytes after switchop).
- */
- if (js_EmitN(cx, cg, switchop, switchsize) < 0)
- return JS_FALSE;
-
- off = -1;
- if (switchop == JSOP_CONDSWITCH) {
- intN caseNoteIndex = -1;
-
- /* Emit code for evaluating cases and jumping to case statements. */
- for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
- pn4 = pn3->pn_left;
- if (pn4 && !js_EmitTree(cx, cg, pn4))
- return JS_FALSE;
- if (caseNoteIndex >= 0) {
- /* off is the previous JSOP_CASE's bytecode offset. */
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0,
- CG_OFFSET(cg) - off)) {
- return JS_FALSE;
- }
- }
- if (pn3->pn_type == TOK_DEFAULT)
- continue;
- caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
- if (caseNoteIndex < 0)
- return JS_FALSE;
- off = EmitJump(cx, cg, JSOP_CASE, 0);
- if (off < 0)
- return JS_FALSE;
- pn3->pn_offset = off;
- if (pn3 == pn2->pn_head) {
- /* Switch note's second offset is to first JSOP_CASE. */
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
- off - top)) {
- return JS_FALSE;
- }
- }
- }
-
- /* Emit default even if no explicit default statement. */
- defaultOffset = EmitJump(cx, cg, JSOP_DEFAULT, 0);
- if (defaultOffset < 0)
- return JS_FALSE;
- } else if (switchop == JSOP_TABLESWITCH) {
- /* Fill in switch bounds, which we know fit in 16-bit offsets. */
- pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
- SET_JUMP_OFFSET(pc, low);
- pc += JUMP_OFFSET_LEN;
- SET_JUMP_OFFSET(pc, high);
- pc += JUMP_OFFSET_LEN;
- } else {
- JS_ASSERT(switchop == JSOP_LOOKUPSWITCH);
-
- /* Fill in the number of cases. */
- pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
- SET_ATOM_INDEX(pc, ncases);
- }
-
- /* Emit code for each case's statements, copying pn_offset up to pn3. */
- for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
- if (switchop == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT)
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset);
- pn4 = pn3->pn_right;
- if (!js_EmitTree(cx, cg, pn4))
- return JS_FALSE;
- pn3->pn_offset = pn4->pn_offset;
- if (pn3->pn_type == TOK_DEFAULT)
- off = pn3->pn_offset - top;
- }
-
- if (!hasDefault) {
- /* If no default case, offset for default is to end of switch. */
- off = CG_OFFSET(cg) - top;
- }
-
- /* We better have set "off" by now. */
- JS_ASSERT(off != -1);
-
- /* Set the default offset (to end of switch if no default). */
- pc = NULL;
- if (switchop == JSOP_CONDSWITCH) {
- JS_ASSERT(defaultOffset != -1);
- if (!js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset),
- off - (defaultOffset - top))) {
- return JS_FALSE;
- }
- } else {
- pc = CG_CODE(cg, top);
- if (!js_SetJumpOffset(cx, cg, pc, off))
- return JS_FALSE;
- pc += JUMP_OFFSET_LEN;
- }
-
- /* Set the SRC_SWITCH note's offset operand to tell end of switch. */
- off = CG_OFFSET(cg) - top;
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off))
- return JS_FALSE;
-
- if (switchop == JSOP_TABLESWITCH) {
- /* Skip over the already-initialized switch bounds. */
- pc += 2 * JUMP_OFFSET_LEN;
-
- /* Fill in the jump table, if there is one. */
- if (tablen) {
- /* Avoid bloat for a compilation unit with many switches. */
- tablesize = (size_t)tablen * sizeof *table;
- table = (JSParseNode **) JS_malloc(cx, tablesize);
- if (!table)
- return JS_FALSE;
- memset(table, 0, tablesize);
- for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
- if (pn3->pn_type == TOK_DEFAULT)
- continue;
- i = JSVAL_TO_INT(pn3->pn_val);
- i -= low;
- JS_ASSERT((uint32)i < tablen);
- table[i] = pn3;
- }
- for (i = 0; i < (jsint)tablen; i++) {
- pn3 = table[i];
- off = pn3 ? pn3->pn_offset - top : 0;
- ok = js_SetJumpOffset(cx, cg, pc, off);
- if (!ok)
- break;
- pc += JUMP_OFFSET_LEN;
- }
- JS_free(cx, table);
- if (!ok)
- return JS_FALSE;
- }
- } else if (switchop == JSOP_LOOKUPSWITCH) {
- /* Skip over the already-initialized number of cases. */
- pc += ATOM_INDEX_LEN;
-
- for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
- if (pn3->pn_type == TOK_DEFAULT)
- continue;
- atom = js_AtomizeValue(cx, pn3->pn_val, 0);
- if (!atom)
- return JS_FALSE;
- ale = js_IndexAtom(cx, atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- SET_ATOM_INDEX(pc, ALE_INDEX(ale));
- pc += ATOM_INDEX_LEN;
-
- off = pn3->pn_offset - top;
- if (!js_SetJumpOffset(cx, cg, pc, off))
- return JS_FALSE;
- pc += JUMP_OFFSET_LEN;
- }
- }
-
- return js_PopStatementCG(cx, cg);
-}
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
-JSBool
-js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
- JSFunction *fun)
-{
- JSStackFrame *fp, frame;
- JSObject *funobj;
- JSBool ok;
-
- if (!js_AllocTryNotes(cx, cg))
- return JS_FALSE;
-
- fp = cx->fp;
- funobj = fun->object;
- if (!fp || fp->fun != fun || fp->varobj != funobj ||
- fp->scopeChain != funobj) {
- memset(&frame, 0, sizeof frame);
- frame.fun = fun;
- frame.varobj = frame.scopeChain = funobj;
- frame.down = fp;
- cx->fp = &frame;
- }
- ok = js_EmitTree(cx, cg, body);
- cx->fp = fp;
- if (!ok)
- return JS_FALSE;
-
- fun->script = js_NewScriptFromCG(cx, cg, fun);
- if (!fun->script)
- return JS_FALSE;
- if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)
- fun->flags |= JSFUN_HEAVYWEIGHT;
- return JS_TRUE;
-}
-
-/* A macro for inlining at the top of js_EmitTree (whence it came). */
-#define UPDATE_LINE_NUMBER_NOTES(cx, cg, pn) \
- JS_BEGIN_MACRO \
- uintN line_ = (pn)->pn_pos.begin.lineno; \
- uintN delta_ = line_ - CG_CURRENT_LINE(cg); \
- if (delta_ != 0) { \
- /* \
- * Encode any change in the current source line number by using \
- * either several SRC_NEWLINE notes or just one SRC_SETLINE note, \
- * whichever consumes less space. \
- * \
- * NB: We handle backward line number deltas (possible with for \
- * loops where the update part is emitted after the body, but its \
- * line number is <= any line number in the body) here by letting \
- * unsigned delta_ wrap to a very large number, which triggers a \
- * SRC_SETLINE. \
- */ \
- CG_CURRENT_LINE(cg) = line_; \
- if (delta_ >= (uintN)(2 + ((line_ > SN_3BYTE_OFFSET_MASK)<<1))) { \
- if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)line_) < 0)\
- return JS_FALSE; \
- } else { \
- do { \
- if (js_NewSrcNote(cx, cg, SRC_NEWLINE) < 0) \
- return JS_FALSE; \
- } while (--delta_ != 0); \
- } \
- } \
- JS_END_MACRO
-
-/* A function, so that we avoid macro-bloating all the other callsites. */
-static JSBool
-UpdateLineNumberNotes(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
-{
- UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
- return JS_TRUE;
-}
-
-JSBool
-js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
-{
- JSBool ok, useful, wantval;
- JSStmtInfo *stmt, stmtInfo;
- ptrdiff_t top, off, tmp, beq, jmp;
- JSParseNode *pn2, *pn3;
- JSAtom *atom;
- JSAtomListElement *ale;
- jsatomid atomIndex;
- intN noteIndex;
- JSSrcNoteType noteType;
- jsbytecode *pc;
- JSOp op;
- uint32 argc;
- int stackDummy;
-
- if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
- return JS_FALSE;
- }
-
- ok = JS_TRUE;
- cg->emitLevel++;
- pn->pn_offset = top = CG_OFFSET(cg);
-
- /* Emit notes to tell the current bytecode's source line number. */
- UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
-
- switch (pn->pn_type) {
- case TOK_FUNCTION:
- {
- void *cg2mark;
- JSCodeGenerator *cg2;
- JSFunction *fun;
-
- /* Generate code for the function's body. */
- cg2mark = JS_ARENA_MARK(&cx->tempPool);
- JS_ARENA_ALLOCATE_TYPE(cg2, JSCodeGenerator, &cx->tempPool);
- if (!cg2) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- if (!js_InitCodeGenerator(cx, cg2, cg->codePool, cg->notePool,
- cg->filename, pn->pn_pos.begin.lineno,
- cg->principals)) {
- return JS_FALSE;
- }
- cg2->treeContext.flags = pn->pn_flags | TCF_IN_FUNCTION;
- cg2->treeContext.tryCount = pn->pn_tryCount;
- fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom));
- if (!js_EmitFunctionBody(cx, cg2, pn->pn_body, fun))
- return JS_FALSE;
-
- /*
- * We need an activation object if an inner peeks out, or if such
- * inner-peeking caused one of our inners to become heavyweight.
- */
- if (cg2->treeContext.flags &
- (TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
- cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
- }
- js_FinishCodeGenerator(cx, cg2);
- JS_ARENA_RELEASE(&cx->tempPool, cg2mark);
-
- /* Make the function object a literal in the outer script's pool. */
- ale = js_IndexAtom(cx, pn->pn_funAtom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- atomIndex = ALE_INDEX(ale);
-
-#if JS_HAS_LEXICAL_CLOSURE
- /* Emit a bytecode pointing to the closure object in its immediate. */
- if (pn->pn_op != JSOP_NOP) {
- EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
- break;
- }
-#endif
-
- /* Top-level named functions need a nop for decompilation. */
- noteIndex = js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)atomIndex);
- if (noteIndex < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
-
- /*
- * Top-levels also need a prolog op to predefine their names in the
- * variable object, or if local, to fill their stack slots.
- */
- CG_SWITCH_TO_PROLOG(cg);
-
-#if JS_HAS_LEXICAL_CLOSURE
- if (cg->treeContext.flags & TCF_IN_FUNCTION) {
- JSObject *obj, *pobj;
- JSScopeProperty *sprop;
- uintN slot;
-
- obj = OBJ_GET_PARENT(cx, fun->object);
- if (!js_LookupProperty(cx, obj, (jsid)fun->atom, &pobj,
- (JSProperty **)&sprop)) {
- return JS_FALSE;
- }
- JS_ASSERT(sprop && pobj == obj);
- slot = sprop->shortid;
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
-
- /* Emit [JSOP_DEFLOCALFUN, local variable slot, atomIndex]. */
- off = js_EmitN(cx, cg, JSOP_DEFLOCALFUN, VARNO_LEN+ATOM_INDEX_LEN);
- if (off < 0)
- return JS_FALSE;
- pc = CG_CODE(cg, off);
- SET_VARNO(pc, slot);
- pc += VARNO_LEN;
- SET_ATOM_INDEX(pc, atomIndex);
- } else
-#endif
- EMIT_ATOM_INDEX_OP(JSOP_DEFFUN, atomIndex);
-
- CG_SWITCH_TO_MAIN(cg);
- break;
- }
-
-#if JS_HAS_EXPORT_IMPORT
- case TOK_EXPORT:
- pn2 = pn->pn_head;
- if (pn2->pn_type == TOK_STAR) {
- /*
- * 'export *' must have no other elements in the list (what would
- * be the point?).
- */
- if (js_Emit1(cx, cg, JSOP_EXPORTALL) < 0)
- return JS_FALSE;
- } else {
- /*
- * If not 'export *', the list consists of NAME nodes identifying
- * properties of the variables object to flag as exported.
- */
- do {
- ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_EXPORTNAME, ALE_INDEX(ale));
- } while ((pn2 = pn2->pn_next) != NULL);
- }
- break;
-
- case TOK_IMPORT:
- for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
- /*
- * Each subtree on an import list is rooted by a DOT or LB node.
- * A DOT may have a null pn_atom member, in which case pn_op must
- * be JSOP_IMPORTALL -- see EmitPropOp above.
- */
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- }
- break;
-#endif /* JS_HAS_EXPORT_IMPORT */
-
- case TOK_IF:
- /* Initialize so we can detect else-if chains and avoid recursion. */
- stmtInfo.type = STMT_IF;
- beq = jmp = -1;
- noteIndex = -1;
-
- if_again:
- /* Emit code for the condition before pushing stmtInfo. */
- if (!js_EmitTree(cx, cg, pn->pn_kid1))
- return JS_FALSE;
- if (stmtInfo.type == STMT_IF) {
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF,
- CG_OFFSET(cg));
- } else {
- /*
- * We came here from the goto further below that detects else-if
- * chains, so we must mutate stmtInfo back into a STMT_IF record.
- * Also (see below for why) we need a note offset for SRC_IF_ELSE
- * to help the decompiler.
- */
- JS_ASSERT(stmtInfo.type == STMT_ELSE);
- stmtInfo.type = STMT_IF;
- if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
- return JS_FALSE;
- }
-
- /* Emit an annotated branch-if-false around the then part. */
- pn3 = pn->pn_kid3;
- noteIndex = js_NewSrcNote(cx, cg, pn3 ? SRC_IF_ELSE : SRC_IF);
- if (noteIndex < 0)
- return JS_FALSE;
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0)
- return JS_FALSE;
-
- /* Emit code for the then and optional else parts. */
- if (!js_EmitTree(cx, cg, pn->pn_kid2))
- return JS_FALSE;
- if (pn3) {
- /* Modify stmtInfo so we know we're in the else part. */
- stmtInfo.type = STMT_ELSE;
-
- /*
- * Emit a JSOP_BACKPATCH op to jump from the end of our then part
- * around the else part. The js_PopStatementCG call at the bottom
- * of this switch case will fix up the backpatch chain linked from
- * stmtInfo.breaks.
- */
- jmp = EmitGoto(cx, cg, &stmtInfo, &stmtInfo.breaks, NULL, SRC_NULL);
- if (jmp < 0)
- return JS_FALSE;
-
- /* Ensure the branch-if-false comes here, then emit the else. */
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
- if (pn3->pn_type == TOK_IF) {
- pn = pn3;
- goto if_again;
- }
-
- if (!js_EmitTree(cx, cg, pn3))
- return JS_FALSE;
-
- /*
- * Annotate SRC_IF_ELSE with the offset from branch to jump, for
- * the decompiler's benefit. We can't just "back up" from the pc
- * of the else clause, because we don't know whether an extended
- * jump was required to leap from the end of the then clause over
- * the else clause.
- */
- if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
- return JS_FALSE;
- } else {
- /* No else part, fixup the branch-if-false to come here. */
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
- }
- ok = js_PopStatementCG(cx, cg);
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case TOK_SWITCH:
- /* Out of line to avoid bloating js_EmitTree's stack frame size. */
- ok = EmitSwitch(cx, cg, pn, &stmtInfo);
- break;
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
- case TOK_WHILE:
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WHILE_LOOP, top);
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
- noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
- if (noteIndex < 0)
- return JS_FALSE;
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0)
- return JS_FALSE;
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
- jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
- if (jmp < 0)
- return JS_FALSE;
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
- if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
- return JS_FALSE;
- ok = js_PopStatementCG(cx, cg);
- break;
-
-#if JS_HAS_DO_WHILE_LOOP
- case TOK_DO:
- /* Emit an annotated nop so we know to decompile a 'do' keyword. */
- if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
-
- /* Compile the loop body. */
- top = CG_OFFSET(cg);
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_DO_LOOP, top);
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
-
- /* Set loop and enclosing label update offsets, for continue. */
- stmt = &stmtInfo;
- do {
- stmt->update = CG_OFFSET(cg);
- } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
-
- /* Compile the loop condition, now that continues know where to go. */
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
-
- /*
- * No source note needed, because JSOP_IFNE is used only for do-while.
- * If we ever use JSOP_IFNE for other purposes, we can still avoid yet
- * another note here, by storing (jmp - top) in the SRC_WHILE note's
- * offset, and fetching that delta in order to decompile recursively.
- */
- if (EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg)) < 0)
- return JS_FALSE;
- ok = js_PopStatementCG(cx, cg);
- break;
-#endif /* JS_HAS_DO_WHILE_LOOP */
-
- case TOK_FOR:
- beq = 0; /* suppress gcc warnings */
- pn2 = pn->pn_left;
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top);
-
- if (pn2->pn_type == TOK_IN) {
- /* Set stmtInfo type for later testing. */
- stmtInfo.type = STMT_FOR_IN_LOOP;
- noteIndex = -1;
-
- /* If the left part is var x = i, bind x, evaluate i, and pop. */
- pn3 = pn2->pn_left;
- if (pn3->pn_type == TOK_VAR && pn3->pn_head->pn_expr) {
- if (!js_EmitTree(cx, cg, pn3))
- return JS_FALSE;
- /* Set pn3 to the variable name, to avoid another var note. */
- pn3 = pn3->pn_head;
- JS_ASSERT(pn3->pn_type == TOK_NAME);
- }
-
- /* Emit a push to allocate the iterator. */
- if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
- return JS_FALSE;
-
- /* Compile the object expression to the right of 'in'. */
- if (!js_EmitTree(cx, cg, pn2->pn_right))
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_TOOBJECT) < 0)
- return JS_FALSE;
-
- top = CG_OFFSET(cg);
- SET_STATEMENT_TOP(&stmtInfo, top);
-
- /* Compile a JSOP_FOR* bytecode based on the left hand side. */
- switch (pn3->pn_type) {
- case TOK_VAR:
- pn3 = pn3->pn_head;
- if (js_NewSrcNote(cx, cg, SRC_VAR) < 0)
- return JS_FALSE;
- /* FALL THROUGH */
- case TOK_NAME:
- pn3->pn_op = JSOP_FORNAME;
- if (!LookupArgOrVar(cx, &cg->treeContext, pn3))
- return JS_FALSE;
- op = pn3->pn_op;
- if (pn3->pn_slot >= 0) {
- if (pn3->pn_attrs & JSPROP_READONLY)
- op = JSOP_GETVAR;
- atomIndex = (jsatomid) pn3->pn_slot;
- EMIT_ATOM_INDEX_OP(op, atomIndex);
- } else {
- if (!EmitAtomOp(cx, pn3, op, cg))
- return JS_FALSE;
- }
- break;
-
- case TOK_DOT:
- if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg))
- return JS_FALSE;
- break;
-
- case TOK_LB:
- /*
- * We separate the first/next bytecode from the enumerator
- * variable binding to avoid any side-effects in the index
- * expression (e.g., for (x[i++] in {}) should not bind x[i]
- * or increment i at all).
- */
- if (!js_Emit1(cx, cg, JSOP_FORELEM))
- return JS_FALSE;
-
- /*
- * Emit a SRC_WHILE note with offset telling the distance to
- * the loop-closing jump (we can't reckon from the branch at
- * the top of the loop, because the loop-closing jump might
- * need to be an extended jump, independent of whether the
- * branch is short or long).
- */
- noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
- if (noteIndex < 0)
- return JS_FALSE;
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0)
- return JS_FALSE;
-
- /* Now that we're safely past the IFEQ, commit side effects. */
- if (!EmitElemOp(cx, pn3, JSOP_ENUMELEM, cg))
- return JS_FALSE;
- break;
-
- default:
- JS_ASSERT(0);
- }
- if (pn3->pn_type != TOK_LB) {
- /* Annotate so the decompiler can find the loop-closing jump. */
- noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
- if (noteIndex < 0)
- return JS_FALSE;
-
- /* Pop and test the loop condition generated by JSOP_FOR*. */
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0)
- return JS_FALSE;
- }
- } else {
- if (!pn2->pn_kid1) {
- /* No initializer: emit an annotated nop for the decompiler. */
- op = JSOP_NOP;
- } else {
- if (!js_EmitTree(cx, cg, pn2->pn_kid1))
- return JS_FALSE;
- op = JSOP_POP;
- }
- noteIndex = js_NewSrcNote(cx, cg, SRC_FOR);
- if (noteIndex < 0 ||
- js_Emit1(cx, cg, op) < 0) {
- return JS_FALSE;
- }
-
- top = CG_OFFSET(cg);
- SET_STATEMENT_TOP(&stmtInfo, top);
- if (!pn2->pn_kid2) {
- /* No loop condition: flag this fact in the source notes. */
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, 0))
- return JS_FALSE;
- } else {
- if (!js_EmitTree(cx, cg, pn2->pn_kid2))
- return JS_FALSE;
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
- CG_OFFSET(cg) - top)) {
- return JS_FALSE;
- }
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0)
- return JS_FALSE;
- }
-
- /* Set pn3 (used below) here to avoid spurious gcc warnings. */
- pn3 = pn2->pn_kid3;
- }
-
- /* Emit code for the loop body. */
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
-
- if (pn2->pn_type != TOK_IN) {
- /* Set the second note offset so we can find the update part. */
- JS_ASSERT(noteIndex != -1);
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
- CG_OFFSET(cg) - top)) {
- return JS_FALSE;
- }
-
- if (pn3) {
- /* Set loop and enclosing "update" offsets, for continue. */
- stmt = &stmtInfo;
- do {
- stmt->update = CG_OFFSET(cg);
- } while ((stmt = stmt->down) != NULL &&
- stmt->type == STMT_LABEL);
-
- if (!js_EmitTree(cx, cg, pn3))
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_POP) < 0)
- return JS_FALSE;
-
- /* Restore the absolute line number for source note readers. */
- off = (ptrdiff_t) pn->pn_pos.end.lineno;
- if (CG_CURRENT_LINE(cg) != (uintN) off) {
- if (js_NewSrcNote2(cx, cg, SRC_SETLINE, off) < 0)
- return JS_FALSE;
- CG_CURRENT_LINE(cg) = (uintN) off;
- }
- }
-
- /* The third note offset helps us find the loop-closing jump. */
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 2,
- CG_OFFSET(cg) - top)) {
- return JS_FALSE;
- }
- }
-
- /* Emit the loop-closing jump and fixup all jump offsets. */
- jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
- if (jmp < 0)
- return JS_FALSE;
- if (beq > 0)
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
- if (pn2->pn_type == TOK_IN) {
- /* Set the SRC_WHILE note offset so we can find the closing jump. */
- JS_ASSERT(noteIndex != -1);
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, jmp - beq))
- return JS_FALSE;
- }
-
- /* Now fixup all breaks and continues (before for/in's final POP2). */
- if (!js_PopStatementCG(cx, cg))
- return JS_FALSE;
-
- if (pn2->pn_type == TOK_IN) {
- /*
- * Generate the object and iterator pop opcodes after popping the
- * stmtInfo stack, so breaks will go to this pop bytecode.
- */
- if (pn3->pn_type != TOK_LB) {
- if (js_Emit1(cx, cg, JSOP_POP2) < 0)
- return JS_FALSE;
- } else {
- /*
- * With 'for(x[i]...)', there's only the object on the stack,
- * so we need to hide the pop.
- */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_POP) < 0)
- return JS_FALSE;
- }
- }
- break;
-
- case TOK_BREAK:
- stmt = cg->treeContext.topStmt;
- atom = pn->pn_atom;
- if (atom) {
- ale = js_IndexAtom(cx, atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- while (stmt->type != STMT_LABEL || stmt->label != atom)
- stmt = stmt->down;
- noteType = SRC_BREAK2LABEL;
- } else {
- ale = NULL;
- while (!STMT_IS_LOOP(stmt) && stmt->type != STMT_SWITCH)
- stmt = stmt->down;
- noteType = SRC_NULL;
- }
-
- if (EmitGoto(cx, cg, stmt, &stmt->breaks, ale, noteType) < 0)
- return JS_FALSE;
- break;
-
- case TOK_CONTINUE:
- stmt = cg->treeContext.topStmt;
- atom = pn->pn_atom;
- if (atom) {
- /* Find the loop statement enclosed by the matching label. */
- JSStmtInfo *loop = NULL;
- ale = js_IndexAtom(cx, atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- while (stmt->type != STMT_LABEL || stmt->label != atom) {
- if (STMT_IS_LOOP(stmt))
- loop = stmt;
- stmt = stmt->down;
- }
- stmt = loop;
- noteType = SRC_CONT2LABEL;
- } else {
- ale = NULL;
- while (!STMT_IS_LOOP(stmt))
- stmt = stmt->down;
- noteType = SRC_CONTINUE;
- }
-
- if (EmitGoto(cx, cg, stmt, &stmt->continues, ale, noteType) < 0)
- return JS_FALSE;
- break;
-
- case TOK_WITH:
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WITH, CG_OFFSET(cg));
- if (js_Emit1(cx, cg, JSOP_ENTERWITH) < 0)
- return JS_FALSE;
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)
- return JS_FALSE;
- ok = js_PopStatementCG(cx, cg);
- break;
-
-#if JS_HAS_EXCEPTIONS
-
- case TOK_TRY:
- {
- ptrdiff_t start, end, catchStart, finallyCatch, catchJump;
- JSParseNode *iter;
- intN depth;
-
- /* Quell GCC overwarnings. */
- end = catchStart = finallyCatch = catchJump = -1;
-
-/* Emit JSOP_GOTO that points to the first op after the catch/finally blocks */
-#define EMIT_CATCH_GOTO(cx, cg, jmp) \
- EMIT_BACKPATCH_OP(cx, cg, stmtInfo.catchJump, JSOP_BACKPATCH, jmp)
-
-/* Emit JSOP_GOSUB that points to the finally block. */
-#define EMIT_FINALLY_GOSUB(cx, cg, jmp) \
- EMIT_BACKPATCH_OP(cx, cg, stmtInfo.gosub, JSOP_BACKPATCH_PUSH, jmp)
-
- /*
- * Push stmtInfo to track jumps-over-catches and gosubs-to-finally
- * for later fixup.
- *
- * When a finally block is `active' (STMT_FINALLY on the treeContext),
- * non-local jumps (including jumps-over-catches) result in a GOSUB
- * being written into the bytecode stream and fixed-up later (c.f.
- * EMIT_BACKPATCH_OP and BackPatch).
- */
- js_PushStatement(&cg->treeContext, &stmtInfo,
- pn->pn_kid3 ? STMT_FINALLY : STMT_BLOCK,
- CG_OFFSET(cg));
-
- /*
- * About JSOP_SETSP: an exception can be thrown while the stack is in
- * an unbalanced state, and this imbalance causes problems with things
- * like function invocation later on.
- *
- * To fix this, we compute the `balanced' stack depth upon try entry,
- * and then restore the stack to this depth when we hit the first catch
- * or finally block. We can't just zero the stack, because things like
- * for/in and with that are active upon entry to the block keep state
- * variables on the stack.
- */
- depth = cg->stackDepth;
-
- /* Mark try location for decompilation, then emit try block. */
- if (js_Emit1(cx, cg, JSOP_TRY) < 0)
- return JS_FALSE;
- start = CG_OFFSET(cg);
- if (!js_EmitTree(cx, cg, pn->pn_kid1))
- return JS_FALSE;
-
- /* GOSUB to finally, if present. */
- if (pn->pn_kid3) {
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- EMIT_FINALLY_GOSUB(cx, cg, jmp);
- if (jmp < 0)
- return JS_FALSE;
- }
-
- /* Emit (hidden) jump over catch and/or finally. */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- EMIT_CATCH_GOTO(cx, cg, jmp);
- if (jmp < 0)
- return JS_FALSE;
-
- end = CG_OFFSET(cg);
-
- /* If this try has a catch block, emit it. */
- iter = pn->pn_kid2;
- if (iter) {
- catchStart = end;
-
- /*
- * The emitted code for a catch block looks like:
- *
- * [ popscope ] only if 2nd+ catch block
- * name Object
- * pushobj
- * newinit
- * exception
- * initcatchvar <atom>
- * enterwith
- * [< catchguard code >] if there's a catchguard
- * [ifeq <offset to next catch block>] " "
- * < catch block contents >
- * leavewith
- * goto <end of catch blocks> non-local; finally applies
- *
- * If there's no catch block without a catchguard, the last
- * <offset to next catch block> points to rethrow code. This
- * code will GOSUB to the finally code if appropriate, and is
- * also used for the catch-all trynote for capturing exceptions
- * thrown from catch{} blocks.
- */
- for (;;) {
- JSStmtInfo stmtInfo2;
- JSParseNode *disc;
- ptrdiff_t guardnote;
-
- if (!UpdateLineNumberNotes(cx, cg, iter))
- return JS_FALSE;
-
- if (catchJump != -1) {
- /* Fix up and clean up previous catch block. */
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
-
- /* Compensate for the [leavewith]. */
- cg->stackDepth++;
- JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth);
-
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
- return JS_FALSE;
- }
- } else {
- /* Set stack to original depth (see SETSP comment above). */
- EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);
- cg->stackDepth = depth;
- }
-
- /* Non-negative guardnote offset is length of catchguard. */
- guardnote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0);
- if (guardnote < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
-
- /* Construct the scope holder and push it on. */
- ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
- &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
-
- if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0 ||
- js_Emit1(cx, cg, JSOP_NEWINIT) < 0 ||
- js_Emit1(cx, cg, JSOP_EXCEPTION) < 0) {
- return JS_FALSE;
- }
-
- /* initcatchvar <atomIndex> */
- disc = iter->pn_kid1;
- ale = js_IndexAtom(cx, disc->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
-
- EMIT_ATOM_INDEX_OP(JSOP_INITCATCHVAR, ALE_INDEX(ale));
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_ENTERWITH) < 0) {
- return JS_FALSE;
- }
-
- /* boolean_expr */
- if (disc->pn_expr) {
- ptrdiff_t guardstart = CG_OFFSET(cg);
- if (!js_EmitTree(cx, cg, disc->pn_expr))
- return JS_FALSE;
- if (!js_SetSrcNoteOffset(cx, cg, guardnote, 0,
- CG_OFFSET(cg) - guardstart)) {
- return JS_FALSE;
- }
- /* ifeq <next block> */
- catchJump = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (catchJump < 0)
- return JS_FALSE;
- }
-
- /* Emit catch block. */
- js_PushStatement(&cg->treeContext, &stmtInfo2, STMT_CATCH,
- CG_OFFSET(cg));
- stmtInfo2.label = disc->pn_atom;
- if (!js_EmitTree(cx, cg, iter->pn_kid3))
- return JS_FALSE;
- js_PopStatementCG(cx, cg);
-
- /*
- * Jump over the remaining catch blocks.
- * This counts as a non-local jump, so do the finally thing.
- */
-
- /* popscope */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
- return JS_FALSE;
- }
-
- /* gosub <finally>, if required */
- if (pn->pn_kid3) {
- EMIT_FINALLY_GOSUB(cx, cg, jmp);
- if (jmp < 0)
- return JS_FALSE;
- }
-
- /* This will get fixed up to jump to after catch/finally. */
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
- return JS_FALSE;
- EMIT_CATCH_GOTO(cx, cg, jmp);
- if (jmp < 0)
- return JS_FALSE;
- if (!iter->pn_kid2) /* leave iter at last catch */
- break;
- iter = iter->pn_kid2;
- }
- }
-
- /*
- * We use a [leavewith],[gosub],rethrow block for rethrowing
- * when there's no unguarded catch, and also for running finally
- * code while letting an uncaught exception pass through.
- */
- if (pn->pn_kid3 ||
- (catchJump != -1 && iter->pn_kid1->pn_expr)) {
- /*
- * Emit another stack fixup, because the catch could itself
- * throw an exception in an unbalanced state, and the finally
- * may need to call functions. If there is no finally, only
- * guarded catches, the rethrow code below nevertheless needs
- * stack fixup.
- */
- finallyCatch = CG_OFFSET(cg);
- EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);
- cg->stackDepth = depth;
-
- /* Last discriminant jumps to rethrow if none match. */
- if (catchJump != -1 && iter->pn_kid1->pn_expr) {
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
-
- /* Compensate for the [leavewith]. */
- cg->stackDepth++;
- JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth);
-
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
- return JS_FALSE;
- }
- }
-
- if (pn->pn_kid3) {
- EMIT_FINALLY_GOSUB(cx, cg, jmp);
- if (jmp < 0)
- return JS_FALSE;
- cg->stackDepth = depth;
- }
-
- if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 ||
- js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
- js_Emit1(cx, cg, JSOP_THROW) < 0) {
- return JS_FALSE;
- }
- JS_ASSERT(cg->stackDepth == depth);
- }
-
- /*
- * If we have a finally, it belongs here, and we have to fix up the
- * gosubs that might have been emitted before non-local jumps.
- */
- if (pn->pn_kid3) {
- if (!BackPatch(cx, cg, stmtInfo.gosub, CG_NEXT(cg), JSOP_GOSUB))
- return JS_FALSE;
-
- /*
- * The stack budget must be balanced at this point, and we need
- * one more slot for the JSOP_RETSUB return address pushed by a
- * JSOP_GOSUB opcode that calls this finally clause.
- */
- JS_ASSERT(cg->stackDepth == depth);
- if ((uintN)++cg->stackDepth > cg->maxStackDepth)
- cg->maxStackDepth = cg->stackDepth;
-
- /* Now indicate that we're emitting a subroutine body. */
- stmtInfo.type = STMT_SUBROUTINE;
- if (!UpdateLineNumberNotes(cx, cg, pn->pn_kid3))
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_FINALLY) < 0 ||
- !js_EmitTree(cx, cg, pn->pn_kid3) ||
- js_Emit1(cx, cg, JSOP_RETSUB) < 0) {
- return JS_FALSE;
- }
- }
- js_PopStatementCG(cx, cg);
-
- if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
-
- /* Fix up the end-of-try/catch jumps to come here. */
- if (!BackPatch(cx, cg, stmtInfo.catchJump, CG_NEXT(cg), JSOP_GOTO))
- return JS_FALSE;
-
- /*
- * Add the try note last, to let post-order give us the right ordering
- * (first to last for a given nesting level, inner to outer by level).
- */
- if (pn->pn_kid2) {
- JS_ASSERT(end != -1 && catchStart != -1);
- if (!js_NewTryNote(cx, cg, start, end, catchStart))
- return JS_FALSE;
- }
-
- /*
- * If we've got a finally, mark try+catch region with additional
- * trynote to catch exceptions (re)thrown from a catch block or
- * for the try{}finally{} case.
- */
- if (pn->pn_kid3) {
- JS_ASSERT(finallyCatch != -1);
- if (!js_NewTryNote(cx, cg, start, finallyCatch, finallyCatch))
- return JS_FALSE;
- }
- break;
- }
-
-#endif /* JS_HAS_EXCEPTIONS */
-
- case TOK_VAR:
- off = noteIndex = -1;
- for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
- JS_ASSERT(pn2->pn_type == TOK_NAME);
- if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
- return JS_FALSE;
- op = pn2->pn_op;
- if (op == JSOP_ARGUMENTS) {
- JS_ASSERT(!pn2->pn_expr); /* JSOP_ARGUMENTS => no initializer */
-#ifdef __GNUC__
- atomIndex = 0; /* quell GCC overwarning */
-#endif
- } else {
- if (pn2->pn_slot >= 0) {
- atomIndex = (jsatomid) pn2->pn_slot;
- } else {
- ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- atomIndex = ALE_INDEX(ale);
-
- if (!(cg->treeContext.flags & TCF_IN_FUNCTION) ||
- (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)) {
- /* Emit a prolog bytecode to predefine the variable. */
- CG_SWITCH_TO_PROLOG(cg);
- if (!UpdateLineNumberNotes(cx, cg, pn2))
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
- CG_SWITCH_TO_MAIN(cg);
- }
- }
- if (pn2->pn_expr) {
- if (op == JSOP_SETNAME)
- EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
- if (!js_EmitTree(cx, cg, pn2->pn_expr))
- return JS_FALSE;
- }
- }
- if (pn2 == pn->pn_head &&
- js_NewSrcNote(cx, cg,
- (pn->pn_op == JSOP_DEFCONST)
- ? SRC_CONST
- : SRC_VAR) < 0) {
- return JS_FALSE;
- }
- if (op == JSOP_ARGUMENTS) {
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- } else {
- EMIT_ATOM_INDEX_OP(op, atomIndex);
- }
- tmp = CG_OFFSET(cg);
- if (noteIndex >= 0) {
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
- return JS_FALSE;
- }
- if (!pn2->pn_next)
- break;
- off = tmp;
- noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
- if (noteIndex < 0 ||
- js_Emit1(cx, cg, JSOP_POP) < 0) {
- return JS_FALSE;
- }
- }
- if (pn->pn_extra) {
- if (js_Emit1(cx, cg, JSOP_POP) < 0)
- return JS_FALSE;
- }
- break;
-
- case TOK_RETURN:
- /* Push a return value */
- pn2 = pn->pn_kid;
- if (pn2) {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- } else {
- if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
- return JS_FALSE;
- }
-
- /*
- * EmitNonLocalJumpFixup mutates op to JSOP_RETRVAL after emitting a
- * JSOP_SETRVAL if there are open try blocks having finally clauses.
- * We can't simply transfer control flow to our caller in that case,
- * because we must gosub to those clauses from inner to outer, with
- * the correct stack pointer (i.e., after popping any with, for/in,
- * etc., slots nested inside the finally's try).
- */
- op = JSOP_RETURN;
- if (!EmitNonLocalJumpFixup(cx, cg, NULL, &op))
- return JS_FALSE;
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- break;
-
- case TOK_LC:
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_BLOCK, top);
- for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- }
- ok = js_PopStatementCG(cx, cg);
- break;
-
- case TOK_SEMI:
- pn2 = pn->pn_kid;
- if (pn2) {
- /*
- * Top-level or called-from-a-native JS_Execute/EvaluateScript,
- * debugger, and eval frames may need the value of the ultimate
- * expression statement as the script's result, despite the fact
- * that it appears useless to the compiler.
- */
- useful = wantval = !cx->fp->fun ||
- cx->fp->fun->native ||
- (cx->fp->flags & JSFRAME_SPECIAL);
- if (!useful) {
- if (!CheckSideEffects(cx, &cg->treeContext, pn2, &useful))
- return JS_FALSE;
- }
- if (!useful) {
- CG_CURRENT_LINE(cg) = pn2->pn_pos.begin.lineno;
- if (!js_ReportCompileErrorNumber(cx, NULL, cg,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_USELESS_EXPR)) {
- return JS_FALSE;
- }
- } else {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- if (js_Emit1(cx, cg, wantval ? JSOP_POPV : JSOP_POP) < 0)
- return JS_FALSE;
- }
- }
- break;
-
- case TOK_COLON:
- /* Emit an annotated nop so we know to decompile a label. */
- atom = pn->pn_atom;
- ale = js_IndexAtom(cx, atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- pn2 = pn->pn_expr;
- noteIndex = js_NewSrcNote2(cx, cg,
- (pn2->pn_type == TOK_LC)
- ? SRC_LABELBRACE
- : SRC_LABEL,
- (ptrdiff_t) ALE_INDEX(ale));
- if (noteIndex < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
-
- /* Emit code for the labeled statement. */
- js_PushStatement(&cg->treeContext, &stmtInfo, STMT_LABEL,
- CG_OFFSET(cg));
- stmtInfo.label = atom;
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- if (!js_PopStatementCG(cx, cg))
- return JS_FALSE;
-
- /* If the statement was compound, emit a note for the end brace. */
- if (pn2->pn_type == TOK_LC) {
- if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||
- js_Emit1(cx, cg, JSOP_NOP) < 0) {
- return JS_FALSE;
- }
- }
- break;
-
- case TOK_COMMA:
- /*
- * Emit SRC_PCDELTA notes on each JSOP_POP between comma operands.
- * These notes help the decompiler bracket the bytecodes generated
- * from each sub-expression that follows a comma.
- */
- off = noteIndex = -1;
- for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- tmp = CG_OFFSET(cg);
- if (noteIndex >= 0) {
- if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
- return JS_FALSE;
- }
- if (!pn2->pn_next)
- break;
- off = tmp;
- noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
- if (noteIndex < 0 ||
- js_Emit1(cx, cg, JSOP_POP) < 0) {
- return JS_FALSE;
- }
- }
- break;
-
- case TOK_ASSIGN:
- /*
- * Check left operand type and generate specialized code for it.
- * Specialize to avoid ECMA "reference type" values on the operand
- * stack, which impose pervasive runtime "GetValue" costs.
- */
- pn2 = pn->pn_left;
- JS_ASSERT(pn2->pn_type != TOK_RP);
- atomIndex = (jsatomid) -1; /* Suppress warning. */
- switch (pn2->pn_type) {
- case TOK_NAME:
- if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
- return JS_FALSE;
- if (pn2->pn_slot >= 0) {
- atomIndex = (jsatomid) pn2->pn_slot;
- } else {
- ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- atomIndex = ALE_INDEX(ale);
- EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
- }
- break;
- case TOK_DOT:
- if (!js_EmitTree(cx, cg, pn2->pn_expr))
- return JS_FALSE;
- ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- atomIndex = ALE_INDEX(ale);
- break;
- case TOK_LB:
- JS_ASSERT(pn->pn_arity == PN_BINARY);
- if (!js_EmitTree(cx, cg, pn2->pn_left))
- return JS_FALSE;
- if (!js_EmitTree(cx, cg, pn2->pn_right))
- return JS_FALSE;
- break;
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- break;
-#endif
- default:
- JS_ASSERT(0);
- }
-
- op = pn->pn_op;
-#if JS_HAS_GETTER_SETTER
- if (op == JSOP_GETTER || op == JSOP_SETTER) {
- /* We'll emit these prefix bytecodes after emitting the r.h.s. */
- } else
-#endif
- /* If += or similar, dup the left operand and get its value. */
- if (op != JSOP_NOP) {
- switch (pn2->pn_type) {
- case TOK_NAME:
- if (pn2->pn_op != JSOP_SETNAME) {
- EMIT_ATOM_INDEX_OP((pn2->pn_op == JSOP_SETARG)
- ? JSOP_GETARG
- : JSOP_GETVAR,
- atomIndex);
- break;
- }
- /* FALL THROUGH */
- case TOK_DOT:
- if (js_Emit1(cx, cg, JSOP_DUP) < 0)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_GETPROP, atomIndex);
- break;
- case TOK_LB:
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
-#endif
- if (js_Emit1(cx, cg, JSOP_DUP2) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
- return JS_FALSE;
- break;
- default:;
- }
- }
-
- /* Now emit the right operand (it may affect the namespace). */
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
-
- /* If += etc., emit the binary operator with a decompiler note. */
- if (op != JSOP_NOP) {
- if (js_NewSrcNote(cx, cg, SRC_ASSIGNOP) < 0 ||
- js_Emit1(cx, cg, op) < 0) {
- return JS_FALSE;
- }
- }
-
- /* Left parts such as a.b.c and a[b].c need a decompiler note. */
- if (pn2->pn_type != TOK_NAME) {
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
- return JS_FALSE;
- }
-
- /* Finally, emit the specialized assignment bytecode. */
- switch (pn2->pn_type) {
- case TOK_NAME:
- if (pn2->pn_slot < 0 || !(pn2->pn_attrs & JSPROP_READONLY)) {
- case TOK_DOT:
- EMIT_ATOM_INDEX_OP(pn2->pn_op, atomIndex);
- }
- break;
- case TOK_LB:
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
-#endif
- if (js_Emit1(cx, cg, JSOP_SETELEM) < 0)
- return JS_FALSE;
- break;
- default:;
- }
- break;
-
- case TOK_HOOK:
- /* Emit the condition, then branch if false to the else part. */
- if (!js_EmitTree(cx, cg, pn->pn_kid1))
- return JS_FALSE;
- noteIndex = js_NewSrcNote(cx, cg, SRC_COND);
- if (noteIndex < 0)
- return JS_FALSE;
- beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
- if (beq < 0 || !js_EmitTree(cx, cg, pn->pn_kid2))
- return JS_FALSE;
-
- /* Jump around else, fixup the branch, emit else, fixup jump. */
- jmp = EmitJump(cx, cg, JSOP_GOTO, 0);
- if (jmp < 0)
- return JS_FALSE;
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
- if (!js_EmitTree(cx, cg, pn->pn_kid3))
- return JS_FALSE;
- CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
- if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
- return JS_FALSE;
-
- /*
- * Because each branch pushes a single value, but our stack budgeting
- * analysis ignores branches, we now have two values accounted for in
- * cg->stackDepth. Execution will follow only one path, so we must
- * decrement cg->stackDepth here. Failing to do this will foil code,
- * such as the try/catch/finally exception handling code generator,
- * that samples cg->stackDepth for use at runtime (JSOP_SETSP).
- */
- JS_ASSERT(cg->stackDepth > 1);
- cg->stackDepth--;
- break;
-
- case TOK_OR:
- case TOK_AND:
- /*
- * JSOP_OR converts the operand on the stack to boolean, and if true,
- * leaves the original operand value on the stack and jumps; otherwise
- * it pops and falls into the next bytecode, which evaluates the right
- * operand. The jump goes around the right operand evaluation.
- *
- * JSOP_AND converts the operand on the stack to boolean, and if false,
- * leaves the original operand value on the stack and jumps; otherwise
- * it pops and falls into the right operand's bytecode.
- *
- * Avoid tail recursion for long ||...|| expressions and long &&...&&
- * expressions or long mixtures of ||'s and &&'s that can easily blow
- * the stack, by forward-linking and then backpatching all the JSOP_OR
- * and JSOP_AND bytecodes' immediate jump-offset operands.
- */
- pn3 = pn;
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
- top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
- if (top < 0)
- return JS_FALSE;
- jmp = top;
- pn2 = pn->pn_right;
- while (pn2->pn_type == TOK_OR || pn2->pn_type == TOK_AND) {
- pn = pn2;
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
- off = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
- if (off < 0)
- return JS_FALSE;
- if (!SetBackPatchDelta(cx, cg, CG_CODE(cg, jmp), off - jmp))
- return JS_FALSE;
- jmp = off;
- pn2 = pn->pn_right;
- }
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- off = CG_OFFSET(cg);
- do {
- pc = CG_CODE(cg, top);
- tmp = GetJumpOffset(cg, pc);
- CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top);
- *pc = pn3->pn_op;
- top += tmp;
- } while ((pn3 = pn3->pn_right) != pn2);
- break;
-
- case TOK_BITOR:
- case TOK_BITXOR:
- case TOK_BITAND:
- case TOK_EQOP:
- case TOK_RELOP:
-#if JS_HAS_IN_OPERATOR
- case TOK_IN:
-#endif
-#if JS_HAS_INSTANCEOF
- case TOK_INSTANCEOF:
-#endif
- case TOK_SHOP:
- case TOK_PLUS:
- case TOK_MINUS:
- case TOK_STAR:
- case TOK_DIVOP:
- if (pn->pn_arity == PN_LIST) {
- /* Left-associative operator chain: avoid too much recursion. */
- pn2 = pn->pn_head;
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- op = pn->pn_op;
- while ((pn2 = pn2->pn_next) != NULL) {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- }
- } else {
- /* Binary operators that evaluate both operands unconditionally. */
- if (!js_EmitTree(cx, cg, pn->pn_left))
- return JS_FALSE;
- if (!js_EmitTree(cx, cg, pn->pn_right))
- return JS_FALSE;
- if (js_Emit1(cx, cg, pn->pn_op) < 0)
- return JS_FALSE;
- }
- break;
-
-#if JS_HAS_EXCEPTIONS
- case TOK_THROW:
-#endif
- case TOK_UNARYOP:
- /* Unary op, including unary +/-. */
- if (!js_EmitTree(cx, cg, pn->pn_kid))
- return JS_FALSE;
- if (js_Emit1(cx, cg, pn->pn_op) < 0)
- return JS_FALSE;
- break;
-
- case TOK_INC:
- case TOK_DEC:
- /* Emit lvalue-specialized code for ++/-- operators. */
- pn2 = pn->pn_kid;
- JS_ASSERT(pn2->pn_type != TOK_RP);
- op = pn->pn_op;
- switch (pn2->pn_type) {
- case TOK_NAME:
- pn2->pn_op = op;
- if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
- return JS_FALSE;
- op = pn2->pn_op;
- if (pn2->pn_slot >= 0) {
- if (pn2->pn_attrs & JSPROP_READONLY)
- op = JSOP_GETVAR;
- atomIndex = (jsatomid) pn2->pn_slot;
- EMIT_ATOM_INDEX_OP(op, atomIndex);
- } else {
- if (!EmitAtomOp(cx, pn2, op, cg))
- return JS_FALSE;
- }
- break;
- case TOK_DOT:
- if (!EmitPropOp(cx, pn2, op, cg))
- return JS_FALSE;
- break;
- case TOK_LB:
- if (!EmitElemOp(cx, pn2, op, cg))
- return JS_FALSE;
- break;
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE,
- CG_OFFSET(cg) - pn2->pn_offset) < 0) {
- return JS_FALSE;
- }
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- break;
-#endif
- default:
- JS_ASSERT(0);
- }
- break;
-
- case TOK_DELETE:
- /* Under ECMA 3, deleting a non-reference returns true. */
- pn2 = pn->pn_kid;
- switch (pn2->pn_type) {
- case TOK_NAME:
- pn2->pn_op = JSOP_DELNAME;
- if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
- return JS_FALSE;
- op = pn2->pn_op;
- if (op == JSOP_FALSE) {
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- } else {
- if (!EmitAtomOp(cx, pn2, op, cg))
- return JS_FALSE;
- }
- break;
- case TOK_DOT:
- if (!EmitPropOp(cx, pn2, JSOP_DELPROP, cg))
- return JS_FALSE;
- break;
- case TOK_LB:
- if (!EmitElemOp(cx, pn2, JSOP_DELELEM, cg))
- return JS_FALSE;
- break;
- default:
- if (js_Emit1(cx, cg, JSOP_TRUE) < 0)
- return JS_FALSE;
- }
- break;
-
- case TOK_DOT:
- /*
- * Pop a stack operand, convert it to object, get a property named by
- * this bytecode's immediate-indexed atom operand, and push its value
- * (not a reference to it). This bytecode sets the virtual machine's
- * "obj" register to the left operand's ToObject conversion result,
- * for use by JSOP_PUSHOBJ.
- */
- ok = EmitPropOp(cx, pn, pn->pn_op, cg);
- break;
-
- case TOK_LB:
- /*
- * Pop two operands, convert the left one to object and the right one
- * to property name (atom or tagged int), get the named property, and
- * push its value. Set the "obj" register to the result of ToObject
- * on the left operand.
- */
- ok = EmitElemOp(cx, pn, pn->pn_op, cg);
- break;
-
- case TOK_NEW:
- case TOK_LP:
- /*
- * Emit function call or operator new (constructor call) code.
- * First, emit code for the left operand to evaluate the callable or
- * constructable object expression.
- */
- pn2 = pn->pn_head;
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
-
- /* Remember start of callable-object bytecode for decompilation hint. */
- off = pn2->pn_offset;
-
- /*
- * Push the virtual machine's "obj" register, which was set by a name,
- * property, or element get (or set) bytecode.
- */
- if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
- return JS_FALSE;
-
- /*
- * Emit code for each argument in order, then emit the JSOP_*CALL or
- * JSOP_NEW bytecode with a two-byte immediate telling how many args
- * were pushed on the operand stack.
- */
- for (pn2 = pn2->pn_next; pn2; pn2 = pn2->pn_next) {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- }
- if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - off) < 0)
- return JS_FALSE;
- argc = pn->pn_count - 1;
- if (js_Emit3(cx, cg, pn->pn_op, ARGC_HI(argc), ARGC_LO(argc)) < 0)
- return JS_FALSE;
- break;
-
-#if JS_HAS_INITIALIZERS
- case TOK_RB:
- /*
- * Emit code for [a, b, c] of the form:
- * t = new Array; t[0] = a; t[1] = b; t[2] = c; t;
- * but use a stack slot for t and avoid dup'ing and popping it via
- * the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
- */
- ale = js_IndexAtom(cx, cx->runtime->atomState.ArrayAtom,
- &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
- if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
- return JS_FALSE;
-
- pn2 = pn->pn_head;
-#if JS_HAS_SHARP_VARS
- if (pn2 && pn2->pn_type == TOK_DEFSHARP) {
- EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
- pn2 = pn2->pn_next;
- }
-#endif
-
- for (atomIndex = 0; pn2; pn2 = pn2->pn_next) {
- /* PrimaryExpr enforced ATOM_INDEX_LIMIT, so in-line optimize. */
- JS_ASSERT(atomIndex < ATOM_INDEX_LIMIT);
- if (atomIndex == 0) {
- if (js_Emit1(cx, cg, JSOP_ZERO) < 0)
- return JS_FALSE;
- } else if (atomIndex == 1) {
- if (js_Emit1(cx, cg, JSOP_ONE) < 0)
- return JS_FALSE;
- } else {
- EMIT_ATOM_INDEX_OP(JSOP_UINT16, (jsatomid)atomIndex);
- }
-
- /* Sub-optimal: holes in a sparse initializer are void-filled. */
- if (pn2->pn_type == TOK_COMMA) {
- if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
- return JS_FALSE;
- } else {
- if (!js_EmitTree(cx, cg, pn2))
- return JS_FALSE;
- }
- if (js_Emit1(cx, cg, JSOP_INITELEM) < 0)
- return JS_FALSE;
-
- atomIndex++;
- }
-
- if (pn->pn_extra) {
- /* Emit a source note so we know to decompile an extra comma. */
- if (js_NewSrcNote(cx, cg, SRC_CONTINUE) < 0)
- return JS_FALSE;
- }
-
- /* Emit an op for sharp array cleanup and decompilation. */
- if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
- return JS_FALSE;
- break;
-
- case TOK_RC:
- /*
- * Emit code for {p:a, '%q':b, 2:c} of the form:
- * t = new Object; t.p = a; t['%q'] = b; t[2] = c; t;
- * but use a stack slot for t and avoid dup'ing and popping it via
- * the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
- */
- ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
- &cg->atomList);
- if (!ale)
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
-
- if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
- return JS_FALSE;
-
- pn2 = pn->pn_head;
-#if JS_HAS_SHARP_VARS
- if (pn2 && pn2->pn_type == TOK_DEFSHARP) {
- EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
- pn2 = pn2->pn_next;
- }
-#endif
-
- for (; pn2; pn2 = pn2->pn_next) {
- /* Emit an index for t[2], else map an atom for t.p or t['%q']. */
- pn3 = pn2->pn_left;
- switch (pn3->pn_type) {
- case TOK_NUMBER:
- if (!EmitNumberOp(cx, pn3->pn_dval, cg))
- return JS_FALSE;
- break;
- case TOK_NAME:
- case TOK_STRING:
- ale = js_IndexAtom(cx, pn3->pn_atom, &cg->atomList);
- if (!ale)
- return JS_FALSE;
- break;
- default:
- JS_ASSERT(0);
- }
-
- /* Emit code for the property initializer. */
- if (!js_EmitTree(cx, cg, pn2->pn_right))
- return JS_FALSE;
-
-#if JS_HAS_GETTER_SETTER
- op = pn2->pn_op;
- if (op == JSOP_GETTER || op == JSOP_SETTER) {
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- }
-#endif
- /* Annotate JSOP_INITELEM so we decompile 2:c and not just c. */
- if (pn3->pn_type == TOK_NUMBER) {
- if (js_NewSrcNote(cx, cg, SRC_LABEL) < 0)
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_INITELEM) < 0)
- return JS_FALSE;
- } else {
- EMIT_ATOM_INDEX_OP(JSOP_INITPROP, ALE_INDEX(ale));
- }
- }
-
- /* Emit an op for sharpArray cleanup and decompilation. */
- if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
- return JS_FALSE;
- break;
-
-#if JS_HAS_SHARP_VARS
- case TOK_DEFSHARP:
- if (!js_EmitTree(cx, cg, pn->pn_kid))
- return JS_FALSE;
- EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid) pn->pn_num);
- break;
-
- case TOK_USESHARP:
- EMIT_ATOM_INDEX_OP(JSOP_USESHARP, (jsatomid) pn->pn_num);
- break;
-#endif /* JS_HAS_SHARP_VARS */
-#endif /* JS_HAS_INITIALIZERS */
-
- case TOK_RP:
- /*
- * The node for (e) has e as its kid, enabling users who want to nest
- * assignment expressions in conditions to avoid the error correction
- * done by Condition (from x = y to x == y) by double-parenthesizing.
- */
- if (!js_EmitTree(cx, cg, pn->pn_kid))
- return JS_FALSE;
- if (js_Emit1(cx, cg, JSOP_GROUP) < 0)
- return JS_FALSE;
- break;
-
- case TOK_NAME:
- if (!LookupArgOrVar(cx, &cg->treeContext, pn))
- return JS_FALSE;
- op = pn->pn_op;
- if (op == JSOP_ARGUMENTS) {
- if (js_Emit1(cx, cg, op) < 0)
- return JS_FALSE;
- break;
- }
- if (pn->pn_slot >= 0) {
- atomIndex = (jsatomid) pn->pn_slot;
- EMIT_ATOM_INDEX_OP(op, atomIndex);
- break;
- }
- /* FALL THROUGH */
- case TOK_STRING:
- case TOK_OBJECT:
- /*
- * The scanner and parser associate JSOP_NAME with TOK_NAME, although
- * other bytecodes may result instead (JSOP_BINDNAME/JSOP_SETNAME,
- * JSOP_FORNAME, etc.). Among JSOP_*NAME* variants, only JSOP_NAME
- * may generate the first operand of a call or new expression, so only
- * it sets the "obj" virtual machine register to the object along the
- * scope chain in which the name was found.
- *
- * Token types for STRING and OBJECT have corresponding bytecode ops
- * in pn_op and emit the same format as NAME, so they share this code.
- */
- ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
- break;
-
- case TOK_NUMBER:
- ok = EmitNumberOp(cx, pn->pn_dval, cg);
- break;
-
- case TOK_PRIMARY:
- if (js_Emit1(cx, cg, pn->pn_op) < 0)
- return JS_FALSE;
- break;
-
-#if JS_HAS_DEBUGGER_KEYWORD
- case TOK_DEBUGGER:
- if (js_Emit1(cx, cg, JSOP_DEBUGGER) < 0)
- return JS_FALSE;
- break;
-#endif /* JS_HAS_DEBUGGER_KEYWORD */
-
- default:
- JS_ASSERT(0);
- }
-
- if (ok && --cg->emitLevel == 0 && cg->spanDeps)
- ok = OptimizeSpanDeps(cx, cg);
-
- return ok;
-}
-
-JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = {
- {"null", 0, 0, 0},
- {"if", 0, 0, 0},
- {"if-else", 1, 0, 1},
- {"while", 1, 0, 1},
- {"for", 3, 1, 1},
- {"continue", 0, 0, 0},
- {"var", 0, 0, 0},
- {"pcdelta", 1, 0, 1},
- {"assignop", 0, 0, 0},
- {"cond", 1, 0, 1},
- {"reserved0", 0, 0, 0},
- {"hidden", 0, 0, 0},
- {"pcbase", 1, 0, -1},
- {"label", 1, 0, 0},
- {"labelbrace", 1, 0, 0},
- {"endbrace", 0, 0, 0},
- {"break2label", 1, 0, 0},
- {"cont2label", 1, 0, 0},
- {"switch", 2, 0, 1},
- {"funcdef", 1, 0, 0},
- {"catch", 1, 11, 1},
- {"const", 0, 0, 0},
- {"newline", 0, 0, 0},
- {"setline", 1, 0, 0},
- {"xdelta", 0, 0, 0},
-};
-
-static intN
-AllocSrcNote(JSContext *cx, JSCodeGenerator *cg)
-{
- intN index;
- JSArenaPool *pool;
- size_t size;
-
- index = CG_NOTE_COUNT(cg);
- if (((uintN)index & CG_NOTE_MASK(cg)) == 0) {
- pool = cg->notePool;
- size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
- if (!CG_NOTES(cg)) {
- /* Allocate the first note array lazily; leave noteMask alone. */
- JS_ARENA_ALLOCATE_CAST(CG_NOTES(cg), jssrcnote *, pool, size);
- } else {
- /* Grow by doubling note array size; update noteMask on success. */
- JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
- if (CG_NOTES(cg))
- CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
- }
- if (!CG_NOTES(cg)) {
- JS_ReportOutOfMemory(cx);
- return -1;
- }
- }
-
- CG_NOTE_COUNT(cg) = index + 1;
- return index;
-}
-
-intN
-js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type)
-{
- intN index, n;
- jssrcnote *sn;
- ptrdiff_t offset, delta, xdelta;
-
- /*
- * Claim a note slot in CG_NOTES(cg) by growing it if necessary and then
- * incrementing CG_NOTE_COUNT(cg).
- */
- index = AllocSrcNote(cx, cg);
- if (index < 0)
- return -1;
- sn = &CG_NOTES(cg)[index];
-
- /*
- * Compute delta from the last annotated bytecode's offset. If it's too
- * big to fit in sn, allocate one or more xdelta notes and reset sn.
- */
- offset = CG_OFFSET(cg);
- delta = offset - CG_LAST_NOTE_OFFSET(cg);
- CG_LAST_NOTE_OFFSET(cg) = offset;
- if (delta >= SN_DELTA_LIMIT) {
- do {
- xdelta = JS_MIN(delta, SN_XDELTA_MASK);
- SN_MAKE_XDELTA(sn, xdelta);
- delta -= xdelta;
- index = AllocSrcNote(cx, cg);
- if (index < 0)
- return -1;
- sn = &CG_NOTES(cg)[index];
- } while (delta >= SN_DELTA_LIMIT);
- }
-
- /*
- * Initialize type and delta, then allocate the minimum number of notes
- * needed for type's arity. Usually, we won't need more, but if an offset
- * does take two bytes, js_SetSrcNoteOffset will grow CG_NOTES(cg).
- */
- SN_MAKE_NOTE(sn, type, delta);
- for (n = (intN)js_SrcNoteSpec[type].arity; n > 0; n--) {
- if (js_NewSrcNote(cx, cg, SRC_NULL) < 0)
- return -1;
- }
- return index;
-}
-
-intN
-js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
- ptrdiff_t offset)
-{
- intN index;
-
- index = js_NewSrcNote(cx, cg, type);
- if (index >= 0) {
- if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset))
- return -1;
- }
- return index;
-}
-
-intN
-js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
- ptrdiff_t offset1, ptrdiff_t offset2)
-{
- intN index;
-
- index = js_NewSrcNote(cx, cg, type);
- if (index >= 0) {
- if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset1))
- return -1;
- if (!js_SetSrcNoteOffset(cx, cg, index, 1, offset2))
- return -1;
- }
- return index;
-}
-
-static JSBool
-GrowSrcNotes(JSContext *cx, JSCodeGenerator *cg)
-{
- JSArenaPool *pool;
- size_t size;
-
- /* Grow by doubling note array size; update noteMask on success. */
- pool = cg->notePool;
- size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
- JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
- if (!CG_NOTES(cg)) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
- return JS_TRUE;
-}
-
-jssrcnote *
-js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn,
- ptrdiff_t delta)
-{
- ptrdiff_t base, limit, newdelta, diff;
- intN index;
-
- /*
- * Called only from OptimizeSpanDeps and js_FinishTakingSrcNotes to add to
- * main script note deltas, and only by a small positive amount.
- */
- JS_ASSERT(cg->current == &cg->main);
- JS_ASSERT((unsigned) delta < (unsigned) SN_XDELTA_LIMIT);
-
- base = SN_DELTA(sn);
- limit = SN_IS_XDELTA(sn) ? SN_XDELTA_LIMIT : SN_DELTA_LIMIT;
- newdelta = base + delta;
- if (newdelta < limit) {
- SN_SET_DELTA(sn, newdelta);
- } else {
- index = sn - cg->main.notes;
- if ((cg->main.noteCount & cg->main.noteMask) == 0) {
- if (!GrowSrcNotes(cx, cg))
- return NULL;
- sn = cg->main.notes + index;
- }
- diff = cg->main.noteCount - index;
- cg->main.noteCount++;
- memmove(sn + 1, sn, SRCNOTE_SIZE(diff));
- SN_MAKE_XDELTA(sn, delta);
- sn++;
- }
- return sn;
-}
-
-uintN
-js_SrcNoteLength(jssrcnote *sn)
-{
- uintN arity;
- jssrcnote *base;
-
- arity = (intN)js_SrcNoteSpec[SN_TYPE(sn)].arity;
- for (base = sn++; arity; sn++, arity--) {
- if (*sn & SN_3BYTE_OFFSET_FLAG)
- sn += 2;
- }
- return sn - base;
-}
-
-JS_FRIEND_API(ptrdiff_t)
-js_GetSrcNoteOffset(jssrcnote *sn, uintN which)
-{
- /* Find the offset numbered which (i.e., skip exactly which offsets). */
- JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
- JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
- for (sn++; which; sn++, which--) {
- if (*sn & SN_3BYTE_OFFSET_FLAG)
- sn += 2;
- }
- if (*sn & SN_3BYTE_OFFSET_FLAG) {
- return (ptrdiff_t)(((uint32)(sn[0] & SN_3BYTE_OFFSET_MASK) << 16)
- | (sn[1] << 8)
- | sn[2]);
- }
- return (ptrdiff_t)*sn;
-}
-
-JSBool
-js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
- uintN which, ptrdiff_t offset)
-{
- jssrcnote *sn;
- ptrdiff_t diff;
-
- if ((jsuword)offset >= (jsuword)((ptrdiff_t)SN_3BYTE_OFFSET_FLAG << 16)) {
- ReportStatementTooLarge(cx, cg);
- return JS_FALSE;
- }
-
- /* Find the offset numbered which (i.e., skip exactly which offsets). */
- sn = &CG_NOTES(cg)[index];
- JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
- JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
- for (sn++; which; sn++, which--) {
- if (*sn & SN_3BYTE_OFFSET_FLAG)
- sn += 2;
- }
-
- /* See if the new offset requires three bytes. */
- if (offset > (ptrdiff_t)SN_3BYTE_OFFSET_MASK) {
- /* Maybe this offset was already set to a three-byte value. */
- if (!(*sn & SN_3BYTE_OFFSET_FLAG)) {
- /* Losing, need to insert another two bytes for this offset. */
- index = PTRDIFF(sn, CG_NOTES(cg), jssrcnote);
-
- /*
- * Simultaneously test to see if the source note array must grow to
- * accomodate either the first or second byte of additional storage
- * required by this 3-byte offset.
- */
- if (((CG_NOTE_COUNT(cg) + 1) & CG_NOTE_MASK(cg)) <= 1) {
- if (!GrowSrcNotes(cx, cg))
- return JS_FALSE;
- sn = CG_NOTES(cg) + index;
- }
- CG_NOTE_COUNT(cg) += 2;
-
- diff = CG_NOTE_COUNT(cg) - (index + 3);
- JS_ASSERT(diff >= 0);
- if (diff > 0)
- memmove(sn + 3, sn + 1, SRCNOTE_SIZE(diff));
- }
- *sn++ = (jssrcnote)(SN_3BYTE_OFFSET_FLAG | (offset >> 16));
- *sn++ = (jssrcnote)(offset >> 8);
- }
- *sn = (jssrcnote)offset;
- return JS_TRUE;
-}
-
-#ifdef DEBUG_brendan
-#define NBINS 10
-static uint32 hist[NBINS];
-
-void DumpSrcNoteSizeHist()
-{
- static FILE *fp;
- int i, n;
-
- if (!fp) {
- fp = fopen("/tmp/srcnotes.hist", "w");
- if (!fp)
- return;
- setlinebuf(fp);
- }
- fprintf(fp, "SrcNote size histogram:\n");
- for (i = 0; i < NBINS; i++) {
- fprintf(fp, "%4u %4u ", JS_BIT(i), hist[i]);
- for (n = (int) JS_HOWMANY(hist[i], 10); n > 0; --n)
- fputc('*', fp);
- fputc('\n', fp);
- }
- fputc('\n', fp);
-}
-#endif
-
-/*
- * Fill in the storage at notes with prolog and main srcnotes; the space at
- * notes was allocated using the CG_COUNT_FINAL_SRCNOTES macro from jsemit.h.
- * SO DON'T CHANGE THIS FUNCTION WITHOUT AT LEAST CHECKING WHETHER jsemit.h's
- * CG_COUNT_FINAL_SRCNOTES MACRO NEEDS CORRESPONDING CHANGES!
- */
-JSBool
-js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes)
-{
- uintN prologCount, mainCount, totalCount;
- ptrdiff_t offset, delta;
- jssrcnote *sn;
-
- JS_ASSERT(cg->current == &cg->main);
-
- prologCount = cg->prolog.noteCount;
- if (prologCount && cg->prolog.currentLine != cg->firstLine) {
- CG_SWITCH_TO_PROLOG(cg);
- if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)cg->firstLine) < 0)
- return JS_FALSE;
- prologCount = cg->prolog.noteCount;
- CG_SWITCH_TO_MAIN(cg);
- } else {
- /*
- * Either no prolog srcnotes, or no line number change over prolog.
- * We don't need a SRC_SETLINE, but we may need to adjust the offset
- * of the first main note, by adding to its delta and possibly even
- * prepending SRC_XDELTA notes to it to account for prolog bytecodes
- * that came at and after the last annotated bytecode.
- */
- offset = CG_PROLOG_OFFSET(cg) - cg->prolog.lastNoteOffset;
- JS_ASSERT(offset >= 0);
- if (offset > 0) {
- /* NB: Use as much of the first main note's delta as we can. */
- sn = cg->main.notes;
- delta = SN_IS_XDELTA(sn)
- ? SN_XDELTA_MASK - (*sn & SN_XDELTA_MASK)
- : SN_DELTA_MASK - (*sn & SN_DELTA_MASK);
- if (offset < delta)
- delta = offset;
- for (;;) {
- if (!js_AddToSrcNoteDelta(cx, cg, sn, delta))
- return JS_FALSE;
- offset -= delta;
- if (offset == 0)
- break;
- delta = JS_MIN(offset, SN_XDELTA_MASK);
- sn = cg->main.notes;
- }
- }
- }
-
- mainCount = cg->main.noteCount;
- totalCount = prologCount + mainCount;
- if (prologCount)
- memcpy(notes, cg->prolog.notes, SRCNOTE_SIZE(prologCount));
- memcpy(notes + prologCount, cg->main.notes, SRCNOTE_SIZE(mainCount));
- SN_MAKE_TERMINATOR(&notes[totalCount]);
-
-#ifdef DEBUG_brendan
- { int bin = JS_CeilingLog2(totalCount);
- if (bin >= NBINS)
- bin = NBINS - 1;
- ++hist[bin];
- }
-#endif
- return JS_TRUE;
-}
-
-JSBool
-js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg)
-{
- size_t size, incr;
- ptrdiff_t delta;
-
- size = TRYNOTE_SIZE(cg->treeContext.tryCount);
- if (size <= cg->tryNoteSpace)
- return JS_TRUE;
-
- /*
- * Allocate trynotes from cx->tempPool.
- * XXX Too much growing and we bloat, as other tempPool allocators block
- * in-place growth, and we never recycle old free space in an arena.
- * YYY But once we consume an entire arena, we'll realloc it, letting the
- * malloc heap recycle old space, while still freeing _en masse_ via the
- * arena pool.
- */
- if (!cg->tryBase) {
- size = JS_ROUNDUP(size, TRYNOTE_SIZE(TRYNOTE_CHUNK));
- JS_ARENA_ALLOCATE_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size);
- if (!cg->tryBase)
- return JS_FALSE;
- cg->tryNoteSpace = size;
- cg->tryNext = cg->tryBase;
- } else {
- delta = PTRDIFF((char *)cg->tryNext, (char *)cg->tryBase, char);
- incr = size - cg->tryNoteSpace;
- incr = JS_ROUNDUP(incr, TRYNOTE_SIZE(TRYNOTE_CHUNK));
- size = cg->tryNoteSpace;
- JS_ARENA_GROW_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size, incr);
- if (!cg->tryBase)
- return JS_FALSE;
- cg->tryNoteSpace = size + incr;
- cg->tryNext = (JSTryNote *)((char *)cg->tryBase + delta);
- }
- return JS_TRUE;
-}
-
-JSTryNote *
-js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
- ptrdiff_t end, ptrdiff_t catchStart)
-{
- JSTryNote *tn;
-
- JS_ASSERT(cg->tryBase <= cg->tryNext);
- JS_ASSERT(catchStart >= 0);
- tn = cg->tryNext++;
- tn->start = start;
- tn->length = end - start;
- tn->catchStart = catchStart;
- return tn;
-}
-
-void
-js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes)
-{
- uintN count;
-
- count = PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote);
- if (!count)
- return;
-
- memcpy(notes, cg->tryBase, TRYNOTE_SIZE(count));
- notes[count].start = 0;
- notes[count].length = CG_OFFSET(cg);
- notes[count].catchStart = 0;
-}
diff --git a/src/extension/script/js/jsemit.h b/src/extension/script/js/jsemit.h
deleted file mode 100644
index 43b520c6e..000000000
--- a/src/extension/script/js/jsemit.h
+++ /dev/null
@@ -1,547 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsemit_h___
-#define jsemit_h___
-/*
- * JS bytecode generation.
- */
-
-#include "jsstddef.h"
-#include "jstypes.h"
-#include "jsatom.h"
-#include "jsopcode.h"
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * NB: If you add non-loop STMT_* enumerators, do so before STMT_DO_LOOP or
- * you will break the STMT_IS_LOOP macro, just below this enum.
- */
-typedef enum JSStmtType {
- STMT_BLOCK = 0, /* compound statement: { s1[;... sN] } */
- STMT_LABEL = 1, /* labeled statement: L: s */
- STMT_IF = 2, /* if (then) statement */
- STMT_ELSE = 3, /* else clause of if statement */
- STMT_SWITCH = 4, /* switch statement */
- STMT_WITH = 5, /* with statement */
- STMT_TRY = 6, /* try statement */
- STMT_CATCH = 7, /* catch block */
- STMT_FINALLY = 8, /* finally statement */
- STMT_SUBROUTINE = 9, /* gosub-target subroutine body */
- STMT_DO_LOOP = 10, /* do/while loop statement */
- STMT_FOR_LOOP = 11, /* for loop statement */
- STMT_FOR_IN_LOOP = 12, /* for/in loop statement */
- STMT_WHILE_LOOP = 13 /* while loop statement */
-} JSStmtType;
-
-#define STMT_IS_LOOP(stmt) ((stmt)->type >= STMT_DO_LOOP)
-
-typedef struct JSStmtInfo JSStmtInfo;
-
-struct JSStmtInfo {
- JSStmtType type; /* statement type */
- ptrdiff_t update; /* loop update offset (top if none) */
- ptrdiff_t breaks; /* offset of last break in loop */
- ptrdiff_t continues; /* offset of last continue in loop */
- ptrdiff_t gosub; /* offset of last GOSUB for this finally */
- ptrdiff_t catchJump; /* offset of last end-of-catch jump */
- JSAtom *label; /* name of LABEL or CATCH var */
- JSStmtInfo *down; /* info for enclosing statement */
-};
-
-#define SET_STATEMENT_TOP(stmt, top) \
- ((stmt)->update = (top), (stmt)->breaks = \
- (stmt)->continues = (stmt)->catchJump = (stmt)->gosub = (-1))
-
-struct JSTreeContext { /* tree context for semantic checks */
- uint32 flags; /* statement state flags, see below */
- uint32 tryCount; /* total count of try statements parsed */
- JSStmtInfo *topStmt; /* top of statement info stack */
- JSAtomList decls; /* function, const, and var declarations */
- JSParseNode *nodeList; /* list of recyclable parse-node structs */
-};
-
-#define TCF_COMPILING 0x01 /* generating bytecode; this tc is a cg */
-#define TCF_IN_FUNCTION 0x02 /* parsing inside function body */
-#define TCF_RETURN_EXPR 0x04 /* function has 'return expr;' */
-#define TCF_RETURN_VOID 0x08 /* function has 'return;' */
-#define TCF_IN_FOR_INIT 0x10 /* parsing init expr of for; exclude 'in' */
-#define TCF_FUN_CLOSURE_VS_VAR 0x20 /* function and var with same name */
-#define TCF_FUN_USES_NONLOCALS 0x40 /* function refers to non-local names */
-#define TCF_FUN_HEAVYWEIGHT 0x80 /* function needs Call object per call */
-#define TCF_FUN_FLAGS 0xE0 /* flags to propagate from FunctionBody */
-
-#define TREE_CONTEXT_INIT(tc) \
- ((tc)->flags = 0, (tc)->tryCount = 0, (tc)->topStmt = NULL, \
- ATOM_LIST_INIT(&(tc)->decls), (tc)->nodeList = NULL)
-
-#define TREE_CONTEXT_FINISH(tc) \
- ((void)0)
-
-/*
- * Span-dependent instructions are jumps whose span (from the jump bytecode to
- * the jump target) may require 2 or 4 bytes of immediate operand.
- */
-typedef struct JSSpanDep JSSpanDep;
-typedef struct JSJumpTarget JSJumpTarget;
-
-struct JSSpanDep {
- ptrdiff_t top; /* offset of first bytecode in an opcode */
- ptrdiff_t offset; /* offset - 1 within opcode of jump operand */
- ptrdiff_t before; /* original offset - 1 of jump operand */
- JSJumpTarget *target; /* tagged target pointer or backpatch delta */
-};
-
-/*
- * Jump targets are stored in an AVL tree, for O(log(n)) lookup with targets
- * sorted by offset from left to right, so that targets after a span-dependent
- * instruction whose jump offset operand must be extended can be found quickly
- * and adjusted upward (toward higher offsets).
- */
-struct JSJumpTarget {
- ptrdiff_t offset; /* offset of span-dependent jump target */
- int balance; /* AVL tree balance number */
- JSJumpTarget *kids[2]; /* left and right AVL tree child pointers */
-};
-
-#define JT_LEFT 0
-#define JT_RIGHT 1
-#define JT_OTHER_DIR(dir) (1 - (dir))
-#define JT_IMBALANCE(dir) (((dir) << 1) - 1)
-#define JT_DIR(imbalance) (((imbalance) + 1) >> 1)
-
-/*
- * Backpatch deltas are encoded in JSSpanDep.target if JT_TAG_BIT is clear,
- * so we can maintain backpatch chains when using span dependency records to
- * hold jump offsets that overflow 16 bits.
- */
-#define JT_TAG_BIT ((jsword) 1)
-#define JT_UNTAG_SHIFT 1
-#define JT_SET_TAG(jt) ((JSJumpTarget *)((jsword)(jt) | JT_TAG_BIT))
-#define JT_CLR_TAG(jt) ((JSJumpTarget *)((jsword)(jt) & ~JT_TAG_BIT))
-#define JT_HAS_TAG(jt) ((jsword)(jt) & JT_TAG_BIT)
-
-#define BITS_PER_PTRDIFF (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE)
-#define BITS_PER_BPDELTA (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT)
-#define BPDELTA_MAX (((ptrdiff_t)1 << BITS_PER_BPDELTA) - 1)
-#define BPDELTA_TO_JT(bp) ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT))
-#define JT_TO_BPDELTA(jt) ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT))
-
-#define SD_SET_TARGET(sd,jt) ((sd)->target = JT_SET_TAG(jt))
-#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp))
-#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \
- JT_TO_BPDELTA((sd)->target))
-#define SD_TARGET_OFFSET(sd) (JS_ASSERT(JT_HAS_TAG((sd)->target)), \
- JT_CLR_TAG((sd)->target)->offset)
-
-struct JSCodeGenerator {
- JSTreeContext treeContext; /* base state: statement info stack, etc. */
- JSArenaPool *codePool; /* pointer to thread code arena pool */
- JSArenaPool *notePool; /* pointer to thread srcnote arena pool */
- void *codeMark; /* low watermark in cg->codePool */
- void *noteMark; /* low watermark in cg->notePool */
- void *tempMark; /* low watermark in cx->tempPool */
- struct {
- jsbytecode *base; /* base of JS bytecode vector */
- jsbytecode *limit; /* one byte beyond end of bytecode */
- jsbytecode *next; /* pointer to next free bytecode */
- jssrcnote *notes; /* source notes, see below */
- uintN noteCount; /* number of source notes so far */
- uintN noteMask; /* growth increment for notes */
- ptrdiff_t lastNoteOffset; /* code offset for last source note */
- uintN currentLine; /* line number for tree-based srcnote gen */
- } prolog, main, *current;
- const char *filename; /* null or weak link to source filename */
- uintN firstLine; /* first line, for js_NewScriptFromCG */
- JSPrincipals *principals; /* principals for constant folding eval */
- JSAtomList atomList; /* literals indexed for mapping */
- intN stackDepth; /* current stack depth in script frame */
- uintN maxStackDepth; /* maximum stack depth so far */
- JSTryNote *tryBase; /* first exception handling note */
- JSTryNote *tryNext; /* next available note */
- size_t tryNoteSpace; /* # of bytes allocated at tryBase */
- JSSpanDep *spanDeps; /* span dependent instruction records */
- JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */
- JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */
- uintN numSpanDeps; /* number of span dependencies */
- uintN numJumpTargets; /* number of jump targets */
- uintN emitLevel; /* js_EmitTree recursion level */
-};
-
-#define CG_BASE(cg) ((cg)->current->base)
-#define CG_LIMIT(cg) ((cg)->current->limit)
-#define CG_NEXT(cg) ((cg)->current->next)
-#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset))
-#define CG_OFFSET(cg) PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecode)
-
-#define CG_NOTES(cg) ((cg)->current->notes)
-#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount)
-#define CG_NOTE_MASK(cg) ((cg)->current->noteMask)
-#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset)
-#define CG_CURRENT_LINE(cg) ((cg)->current->currentLine)
-
-#define CG_PROLOG_BASE(cg) ((cg)->prolog.base)
-#define CG_PROLOG_LIMIT(cg) ((cg)->prolog.limit)
-#define CG_PROLOG_NEXT(cg) ((cg)->prolog.next)
-#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff))
-#define CG_PROLOG_OFFSET(cg) PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE(cg),\
- jsbytecode)
-
-#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main)
-#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog)
-
-/*
- * Initialize cg to allocate bytecode space from codePool, source note space
- * from notePool, and all other arena-allocated temporaries from cx->tempPool.
- * Return true on success. Report an error and return false if the initial
- * code segment can't be allocated.
- */
-extern JS_FRIEND_API(JSBool)
-js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
- JSArenaPool *codePool, JSArenaPool *notePool,
- const char *filename, uintN lineno,
- JSPrincipals *principals);
-
-/*
- * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by
- * js_InitCodeGenerator. Note that cgs are magic: they own the arena pool
- * "tops-of-stack" space above their codeMark, noteMark, and tempMark points.
- * This means you cannot alloc from tempPool and save the pointer beyond the
- * next JS_FinishCodeGenerator.
- */
-extern JS_FRIEND_API(void)
-js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg);
-
-/*
- * Emit one bytecode.
- */
-extern ptrdiff_t
-js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op);
-
-/*
- * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
- */
-extern ptrdiff_t
-js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1);
-
-/*
- * Emit three bytecodes, an opcode with two bytes of immediate operands.
- */
-extern ptrdiff_t
-js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1,
- jsbytecode op2);
-
-/*
- * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
- */
-extern ptrdiff_t
-js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra);
-
-/*
- * Unsafe macro to call js_SetJumpOffset and return false if it does.
- */
-#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \
- JS_BEGIN_MACRO \
- if (!js_SetJumpOffset(cx, cg, pc, off)) \
- return JS_FALSE; \
- JS_END_MACRO
-
-#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \
- CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,off), CG_OFFSET(cg) - (off))
-
-extern JSBool
-js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
- ptrdiff_t off);
-
-/* Test whether we're in a with statement. */
-extern JSBool
-js_InWithStatement(JSTreeContext *tc);
-
-/* Test whether we're in a catch block with exception named by atom. */
-extern JSBool
-js_InCatchBlock(JSTreeContext *tc, JSAtom *atom);
-
-/*
- * Push the C-stack-allocated struct at stmt onto the stmtInfo stack.
- */
-extern void
-js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
- ptrdiff_t top);
-
-/*
- * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it
- * is up to the caller to free it.
- */
-extern void
-js_PopStatement(JSTreeContext *tc);
-
-/*
- * Like js_PopStatement(&cg->treeContext), also patch breaks and continues.
- * May fail if a jump offset overflows.
- */
-extern JSBool
-js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg);
-
-/*
- * Emit code into cg for the tree rooted at pn.
- */
-extern JSBool
-js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);
-
-/*
- * Emit code into cg for the tree rooted at body, then create a persistent
- * script for fun from cg.
- */
-extern JSBool
-js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
- JSFunction *fun);
-
-/*
- * Source notes generated along with bytecode for decompiling and debugging.
- * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of
- * the previous note. If 3 bits of offset aren't enough, extended delta notes
- * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits
- * are emitted before the next note. Some notes have operand offsets encoded
- * immediately after them, in note bytes or byte-triples.
- *
- * Source Note Extended Delta
- * +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+
- * |note-type|delta| |1 1| ext-delta |
- * +---------+-----+ +---+-----------+
- *
- * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
- * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
- *
- * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its
- * initializers need to match the order here.
- */
-typedef enum JSSrcNoteType {
- SRC_NULL = 0, /* terminates a note vector */
- SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */
- SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-else */
- SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */
- SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */
- SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break;
- also used on JSOP_ENDINIT if extra comma
- at end of array literal: [1,2,,] */
- SRC_VAR = 6, /* JSOP_NAME/SETNAME/FORNAME in a var decl */
- SRC_PCDELTA = 7, /* offset from comma-operator to next POP,
- or from CONDSWITCH to first CASE opcode */
- SRC_ASSIGNOP = 8, /* += or another assign-op follows */
- SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */
- SRC_RESERVED0 = 10, /* reserved for future use */
- SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */
- SRC_PCBASE = 12, /* offset of first obj.prop.subprop bytecode */
- SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */
- SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */
- SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */
- SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */
- SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */
- SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch,
- 2nd off to first JSOP_CASE if condswitch */
- SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */
- SRC_CATCH = 20, /* catch block has guard */
- SRC_CONST = 21, /* JSOP_SETCONST in a const decl */
- SRC_NEWLINE = 22, /* bytecode follows a source newline */
- SRC_SETLINE = 23, /* a file-absolute source line number note */
- SRC_XDELTA = 24 /* 24-31 are for extended delta notes */
-} JSSrcNoteType;
-
-#define SN_TYPE_BITS 5
-#define SN_DELTA_BITS 3
-#define SN_XDELTA_BITS 6
-#define SN_TYPE_MASK (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS)
-#define SN_DELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS))
-#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS))
-
-#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \
- (((t) << SN_DELTA_BITS) \
- | ((d) & SN_DELTA_MASK)))
-#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \
- ((SRC_XDELTA << SN_DELTA_BITS) \
- | ((d) & SN_XDELTA_MASK)))
-
-#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA)
-#define SN_TYPE(sn) (SN_IS_XDELTA(sn) ? SRC_XDELTA \
- : *(sn) >> SN_DELTA_BITS)
-#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn))
-#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE)
-
-#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \
- ? *(sn) & SN_XDELTA_MASK \
- : *(sn) & SN_DELTA_MASK))
-#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \
- ? SN_MAKE_XDELTA(sn, delta) \
- : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
-
-#define SN_DELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_DELTA_BITS))
-#define SN_XDELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS))
-
-/*
- * Offset fields follow certain notes and are frequency-encoded: an offset in
- * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and
- * the high bit of the first byte is set.
- */
-#define SN_3BYTE_OFFSET_FLAG 0x80
-#define SN_3BYTE_OFFSET_MASK 0x7f
-
-typedef struct JSSrcNoteSpec {
- const char *name; /* name for disassembly/debugging output */
- uint8 arity; /* number of offset operands */
- uint8 offsetBias; /* bias of offset(s) from annotated pc */
- int8 isSpanDep; /* 1 or -1 if offsets could span extended ops,
- 0 otherwise; sign tells span direction */
-} JSSrcNoteSpec;
-
-extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[];
-extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn);
-
-#define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \
- : js_SrcNoteLength(sn))
-#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn))
-
-/* A source note array is terminated by an all-zero element. */
-#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL)
-#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL)
-
-/*
- * Append a new source note of the given type (and therefore size) to cg's
- * notes dynamic array, updating cg->noteCount. Return the new note's index
- * within the array pointed at by cg->current->notes. Return -1 if out of
- * memory.
- */
-extern intN
-js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type);
-
-extern intN
-js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
- ptrdiff_t offset);
-
-extern intN
-js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
- ptrdiff_t offset1, ptrdiff_t offset2);
-
-/*
- * NB: this function can add at most one extra extended delta note.
- */
-extern jssrcnote *
-js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn,
- ptrdiff_t delta);
-
-/*
- * Get and set the offset operand identified by which (0 for the first, etc.).
- */
-extern JS_FRIEND_API(ptrdiff_t)
-js_GetSrcNoteOffset(jssrcnote *sn, uintN which);
-
-extern JSBool
-js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
- uintN which, ptrdiff_t offset);
-
-/*
- * Finish taking source notes in cx's notePool, copying final notes to the new
- * stable store allocated by the caller and passed in via notes. Return false
- * on malloc failure, which means this function reported an error.
- *
- * To compute the number of jssrcnotes to allocate and pass in via notes, use
- * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of
- * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes
- * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES!
- */
-#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \
- JS_BEGIN_MACRO \
- ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \
- cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \
- if ((cg)->prolog.noteCount && \
- (cg)->prolog.currentLine != (cg)->firstLine) { \
- if (diff_ > SN_DELTA_MASK) \
- cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK); \
- cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \
- } else if (diff_ > 0) { \
- if (cg->main.noteCount) { \
- jssrcnote *sn_ = (cg)->main.notes; \
- diff_ -= SN_IS_XDELTA(sn_) \
- ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK) \
- : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \
- } \
- if (diff_ > 0) \
- cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \
- } \
- JS_END_MACRO
-
-extern JSBool
-js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes);
-
-/*
- * Allocate cg->treeContext.tryCount notes (plus one for the end sentinel)
- * from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount
- * js_NewTryNote calls. The storage is freed by js_FinishCodeGenerator.
- */
-extern JSBool
-js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);
-
-/*
- * Grab the next trynote slot in cg, filling it in appropriately.
- */
-extern JSTryNote *
-js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
- ptrdiff_t end, ptrdiff_t catchStart);
-
-/*
- * Finish generating exception information into the space at notes. As with
- * js_FinishTakingSrcNotes, the caller must use CG_COUNT_FINAL_TRYNOTES(cg) to
- * preallocate enough space in a JSTryNote[] to pass as the notes parameter of
- * js_FinishTakingTryNotes.
- */
-#define CG_COUNT_FINAL_TRYNOTES(cg, cnt) \
- JS_BEGIN_MACRO \
- cnt = ((cg)->tryNext > (cg)->tryBase) \
- ? PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote) + 1 \
- : 0; \
- JS_END_MACRO
-
-extern void
-js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes);
-
-JS_END_EXTERN_C
-
-#endif /* jsemit_h___ */
diff --git a/src/extension/script/js/jsexn.c b/src/extension/script/js/jsexn.c
deleted file mode 100644
index c407c1628..000000000
--- a/src/extension/script/js/jsexn.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS standard exception implementation.
- */
-
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsbit.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsexn.h"
-#include "jsfun.h"
-#include "jsinterp.h"
-#include "jsopcode.h"
-#include "jsnum.h"
-#include "jsscript.h"
-
-#if JS_HAS_ERROR_EXCEPTIONS
-#if !JS_HAS_EXCEPTIONS
-# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"
-#endif
-
-/* XXX consider adding rt->atomState.messageAtom */
-static char js_message_str[] = "message";
-static char js_filename_str[] = "fileName";
-static char js_lineno_str[] = "lineNumber";
-static char js_stack_str[] = "stack";
-
-/* Forward declarations for ExceptionClass's initializer. */
-static JSBool
-Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
-
-static void
-exn_finalize(JSContext *cx, JSObject *obj);
-
-static JSClass ExceptionClass = {
- "Error",
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize,
- NULL, NULL, NULL, Exception,
- NULL, NULL, NULL, 0
-};
-
-/*
- * A copy of the JSErrorReport originally generated.
- */
-typedef struct JSExnPrivate {
- JSErrorReport *errorReport;
-} JSExnPrivate;
-
-/*
- * Undo all the damage done by exn_newPrivate.
- */
-static void
-exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData)
-{
- JSErrorReport *report;
- const jschar **args;
-
- if (!privateData)
- return;
- report = privateData->errorReport;
- if (report) {
- if (report->uclinebuf)
- JS_free(cx, (void *)report->uclinebuf);
- if (report->filename)
- JS_free(cx, (void *)report->filename);
- if (report->ucmessage)
- JS_free(cx, (void *)report->ucmessage);
- if (report->messageArgs) {
- args = report->messageArgs;
- while (*args != NULL)
- JS_free(cx, (void *)*args++);
- JS_free(cx, (void *)report->messageArgs);
- }
- JS_free(cx, report);
- }
- JS_free(cx, privateData);
-}
-
-/*
- * Copy everything interesting about an error into allocated memory.
- */
-static JSExnPrivate *
-exn_newPrivate(JSContext *cx, JSErrorReport *report)
-{
- intN i;
- JSExnPrivate *newPrivate;
- JSErrorReport *newReport;
- size_t capacity;
-
- newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate));
- if (!newPrivate)
- return NULL;
- memset(newPrivate, 0, sizeof (JSExnPrivate));
-
- /* Copy the error report */
- newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));
- if (!newReport)
- goto error;
- memset(newReport, 0, sizeof (JSErrorReport));
- newPrivate->errorReport = newReport;
-
- if (report->filename != NULL) {
- newReport->filename = JS_strdup(cx, report->filename);
- if (!newReport->filename)
- goto error;
- } else {
- newReport->filename = NULL;
- }
-
- newReport->lineno = report->lineno;
-
- /*
- * We don't need to copy linebuf and tokenptr, because they
- * point into the deflated string cache. (currently?)
- */
- newReport->linebuf = report->linebuf;
- newReport->tokenptr = report->tokenptr;
-
- /*
- * But we do need to copy uclinebuf, uctokenptr, because they're
- * pointers into internal tokenstream structs, and may go away.
- */
- if (report->uclinebuf != NULL) {
- capacity = js_strlen(report->uclinebuf) + 1;
- newReport->uclinebuf =
- (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
- if (!newReport->uclinebuf)
- goto error;
- js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity);
- newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
- report->uclinebuf);
- } else {
- newReport->uclinebuf = newReport->uctokenptr = NULL;
- }
-
- if (report->ucmessage != NULL) {
- capacity = js_strlen(report->ucmessage) + 1;
- newReport->ucmessage = (const jschar *)
- JS_malloc(cx, capacity * sizeof(jschar));
- if (!newReport->ucmessage)
- goto error;
- js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity);
-
- if (report->messageArgs) {
- for (i = 0; report->messageArgs[i] != NULL; i++)
- continue;
- JS_ASSERT(i);
- newReport->messageArgs =
- (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *));
- if (!newReport->messageArgs)
- goto error;
- for (i = 0; report->messageArgs[i] != NULL; i++) {
- capacity = js_strlen(report->messageArgs[i]) + 1;
- newReport->messageArgs[i] =
- (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
- if (!newReport->messageArgs[i])
- goto error;
- js_strncpy((jschar *)(newReport->messageArgs[i]),
- report->messageArgs[i], capacity);
- }
- newReport->messageArgs[i] = NULL;
- } else {
- newReport->messageArgs = NULL;
- }
- } else {
- newReport->ucmessage = NULL;
- newReport->messageArgs = NULL;
- }
- newReport->errorNumber = report->errorNumber;
-
- /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
- newReport->flags = report->flags;
-
- return newPrivate;
-error:
- exn_destroyPrivate(cx, newPrivate);
- return NULL;
-}
-
-static void
-exn_finalize(JSContext *cx, JSObject *obj)
-{
- JSExnPrivate *privateData;
- jsval privateValue;
-
- privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
-
- if (!JSVAL_IS_VOID(privateValue)) {
- privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
- if (privateData)
- exn_destroyPrivate(cx, privateData);
- }
-}
-
-JSErrorReport *
-js_ErrorFromException(JSContext *cx, jsval exn)
-{
- JSObject *obj;
- JSExnPrivate *privateData;
- jsval privateValue;
-
- if (JSVAL_IS_PRIMITIVE(exn))
- return NULL;
- obj = JSVAL_TO_OBJECT(exn);
- if (OBJ_GET_CLASS(cx, obj) != &ExceptionClass)
- return NULL;
- privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (JSVAL_IS_VOID(privateValue))
- return NULL;
- privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
- if (!privateData)
- return NULL;
-
- JS_ASSERT(privateData->errorReport);
- return privateData->errorReport;
-}
-
-/*
- * This must be kept in synch with the exceptions array below.
- * XXX use a jsexn.tbl file a la jsopcode.tbl
- */
-typedef enum JSExnType {
- JSEXN_NONE = -1,
- JSEXN_ERR,
- JSEXN_INTERNALERR,
- JSEXN_EVALERR,
- JSEXN_RANGEERR,
- JSEXN_REFERENCEERR,
- JSEXN_SYNTAXERR,
- JSEXN_TYPEERR,
- JSEXN_URIERR,
- JSEXN_LIMIT
-} JSExnType;
-
-struct JSExnSpec {
- int protoIndex;
- const char *name;
- JSNative native;
-};
-
-/*
- * All *Error constructors share the same JSClass, ExceptionClass. But each
- * constructor function for an *Error class must have a distinct native 'call'
- * function pointer, in order for instanceof to work properly across multiple
- * standard class sets. See jsfun.c:fun_hasInstance.
- */
-#define MAKE_EXCEPTION_CTOR(name) \
-const char js_##name##_str[] = #name; \
-static JSBool \
-name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) \
-{ \
- return Exception(cx, obj, argc, argv, rval); \
-}
-
-MAKE_EXCEPTION_CTOR(Error)
-MAKE_EXCEPTION_CTOR(InternalError)
-MAKE_EXCEPTION_CTOR(EvalError)
-MAKE_EXCEPTION_CTOR(RangeError)
-MAKE_EXCEPTION_CTOR(ReferenceError)
-MAKE_EXCEPTION_CTOR(SyntaxError)
-MAKE_EXCEPTION_CTOR(TypeError)
-MAKE_EXCEPTION_CTOR(URIError)
-
-#undef MAKE_EXCEPTION_CTOR
-
-static struct JSExnSpec exceptions[] = {
- { JSEXN_NONE, js_Error_str, Error },
- { JSEXN_ERR, js_InternalError_str, InternalError },
- { JSEXN_ERR, js_EvalError_str, EvalError },
- { JSEXN_ERR, js_RangeError_str, RangeError },
- { JSEXN_ERR, js_ReferenceError_str, ReferenceError },
- { JSEXN_ERR, js_SyntaxError_str, SyntaxError },
- { JSEXN_ERR, js_TypeError_str, TypeError },
- { JSEXN_ERR, js_URIError_str, URIError },
- {0,NULL,NULL}
-};
-
-static JSBool
-InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message,
- JSString *filename, uintN lineno)
-{
- JSCheckAccessOp checkAccess;
- JSErrorReporter older;
- JSExceptionState *state;
- jschar *stackbuf;
- size_t stacklen, stackmax;
- JSStackFrame *fp;
- jsval callerid, v;
- JSBool ok;
- JSString *argsrc, *stack;
- uintN i, ulineno;
- const char *cp;
- char ulnbuf[11];
-
- if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return JS_FALSE;
- }
-
- if (!JS_DefineProperty(cx, obj, js_filename_str,
- STRING_TO_JSVAL(filename),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return JS_FALSE;
- }
-
- if (!JS_DefineProperty(cx, obj, js_lineno_str,
- INT_TO_JSVAL(lineno),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return JS_FALSE;
- }
-
- /*
- * Set the 'stack' property.
- *
- * First, set aside any error reporter for cx and save its exception state
- * so we can suppress any checkAccess failures. Such failures should stop
- * the backtrace procedure, not result in a failure of this constructor.
- */
- checkAccess = cx->runtime->checkObjectAccess;
- if (checkAccess) {
- older = JS_SetErrorReporter(cx, NULL);
- state = JS_SaveExceptionState(cx);
- }
-#ifdef __GNUC__ /* suppress bogus gcc warnings */
- else {
- older = NULL;
- state = NULL;
- }
-#endif
- callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
-
- /*
- * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes
- * the next free jschar slot, and with room for at most stackmax non-null
- * jschars. If stackbuf is non-null, it always contains an extra slot for
- * the null terminator we'll store at the end, as a backstop.
- *
- * All early returns must goto done after this point, till the after-loop
- * cleanup code has run!
- */
- stackbuf = NULL;
- stacklen = stackmax = 0;
- ok = JS_TRUE;
-
-#define APPEND_CHAR_TO_STACK(c) \
- JS_BEGIN_MACRO \
- if (stacklen == stackmax) { \
- void *ptr_; \
- stackmax = stackmax ? 2 * stackmax : 64; \
- ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \
- if (!ptr_) { \
- ok = JS_FALSE; \
- goto done; \
- } \
- stackbuf = ptr_; \
- } \
- stackbuf[stacklen++] = (c); \
- JS_END_MACRO
-
-#define APPEND_STRING_TO_STACK(str) \
- JS_BEGIN_MACRO \
- JSString *str_ = str; \
- size_t length_ = JSSTRING_LENGTH(str_); \
- if (stacklen + length_ > stackmax) { \
- void *ptr_; \
- stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \
- ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \
- if (!ptr_) { \
- ok = JS_FALSE; \
- goto done; \
- } \
- stackbuf = ptr_; \
- } \
- js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_); \
- stacklen += length_; \
- JS_END_MACRO
-
- for (fp = cx->fp; fp; fp = fp->down) {
- if (checkAccess) {
- v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;
- if (!JSVAL_IS_PRIMITIVE(v)) {
- ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v);
- if (!ok) {
- ok = JS_TRUE;
- break;
- }
- }
- }
-
- if (fp->fun) {
- if (fp->fun->atom)
- APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));
-
- APPEND_CHAR_TO_STACK('(');
- for (i = 0; i < fp->argc; i++) {
- /* Avoid toSource bloat and fallibility for object types. */
- v = fp->argv[i];
- if (JSVAL_IS_PRIMITIVE(v)) {
- argsrc = js_ValueToSource(cx, v);
- } else if (JSVAL_IS_FUNCTION(cx, v)) {
- /* XXX Avoid function decompilation bloat for now. */
- argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v));
- if (!argsrc)
- argsrc = js_ValueToSource(cx, v);
- } else {
- /* XXX Avoid toString on objects, it takes too long and
- uses too much memory, for too many classes (see
- Mozilla bug 166743). */
- char buf[100];
- JS_snprintf(buf, sizeof buf, "[object %s]",
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);
- argsrc = JS_NewStringCopyZ(cx, buf);
- }
- if (!argsrc) {
- ok = JS_FALSE;
- goto done;
- }
- if (i > 0)
- APPEND_CHAR_TO_STACK(',');
- APPEND_STRING_TO_STACK(argsrc);
- }
- APPEND_CHAR_TO_STACK(')');
- }
-
- APPEND_CHAR_TO_STACK('@');
- if (fp->script && fp->script->filename) {
- for (cp = fp->script->filename; *cp; cp++)
- APPEND_CHAR_TO_STACK(*cp);
- }
- APPEND_CHAR_TO_STACK(':');
- if (fp->script && fp->pc) {
- ulineno = js_PCToLineNumber(cx, fp->script, fp->pc);
- JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);
- for (cp = ulnbuf; *cp; cp++)
- APPEND_CHAR_TO_STACK(*cp);
- } else {
- APPEND_CHAR_TO_STACK('0');
- }
- APPEND_CHAR_TO_STACK('\n');
- }
-
-#undef APPEND_CHAR_TO_STACK
-#undef APPEND_STRING_TO_STACK
-
-done:
- if (checkAccess) {
- if (ok)
- JS_RestoreExceptionState(cx, state);
- else
- JS_DropExceptionState(cx, state);
- JS_SetErrorReporter(cx, older);
- }
- if (!ok) {
- JS_free(cx, stackbuf);
- return JS_FALSE;
- }
-
- if (!stackbuf) {
- stack = cx->runtime->emptyString;
- } else {
- /* NB: if stackbuf was allocated, it has room for the terminator. */
- JS_ASSERT(stacklen <= stackmax);
- if (stacklen < stackmax) {
- /*
- * Realloc can fail when shrinking on some FreeBSD versions, so
- * don't use JS_realloc here; simply let the oversized allocation
- * be owned by the string in that rare case.
- */
- void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar));
- if (shrunk)
- stackbuf = shrunk;
- }
- stackbuf[stacklen] = 0;
- stack = js_NewString(cx, stackbuf, stacklen, 0);
- if (!stack) {
- JS_free(cx, stackbuf);
- return JS_FALSE;
- }
- }
- return JS_DefineProperty(cx, obj, js_stack_str,
- STRING_TO_JSVAL(stack),
- NULL, NULL, JSPROP_ENUMERATE);
-}
-
-static JSBool
-Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSBool ok;
- jsval pval;
- int32 lineno;
- JSString *message, *filename;
-
- if (cx->creatingException)
- return JS_FALSE;
- cx->creatingException = JS_TRUE;
-
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- /*
- * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
- * called as functions, without operator new. But as we do not give
- * each constructor a distinct JSClass, whose .name member is used by
- * js_NewObject to find the class prototype, we must get the class
- * prototype ourselves.
- */
- ok = OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),
- (jsid)cx->runtime->atomState.classPrototypeAtom,
- &pval);
- if (!ok)
- goto out;
- obj = js_NewObject(cx, &ExceptionClass, JSVAL_TO_OBJECT(pval), NULL);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- *rval = OBJECT_TO_JSVAL(obj);
- }
-
- /*
- * If it's a new object of class Exception, then null out the private
- * data so that the finalizer doesn't attempt to free it.
- */
- if (OBJ_GET_CLASS(cx, obj) == &ExceptionClass)
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_VOID);
-
- /* Set the 'message' property. */
- if (argc != 0) {
- message = js_ValueToString(cx, argv[0]);
- if (!message) {
- ok = JS_FALSE;
- goto out;
- }
- } else {
- message = cx->runtime->emptyString;
- }
-
- /* Set the 'fileName' property. */
- if (argc > 1) {
- filename = js_ValueToString(cx, argv[1]);
- if (!filename) {
- ok = JS_FALSE;
- goto out;
- }
- } else {
- filename = cx->runtime->emptyString;
- }
-
- /* Set the 'lineNumber' property. */
- if (argc > 2) {
- ok = js_ValueToInt32(cx, argv[2], &lineno);
- if (!ok)
- goto out;
- } else {
- lineno = 0;
- }
-
- ok = InitExceptionObject(cx, obj, message, filename, lineno);
-
-out:
- cx->creatingException = JS_FALSE;
- return ok;
-}
-
-/*
- * Convert to string.
- *
- * This method only uses JavaScript-modifiable properties name, message. It
- * is left to the host to check for private data and report filename and line
- * number information along with this message.
- */
-static JSBool
-exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
- JSString *name, *message, *result;
- jschar *chars, *cp;
- size_t name_length, message_length, length;
-
- if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))
- return JS_FALSE;
- name = js_ValueToString(cx, v);
- if (!name)
- return JS_FALSE;
-
- if (!JS_GetProperty(cx, obj, js_message_str, &v) ||
- !(message = js_ValueToString(cx, v))) {
- return JS_FALSE;
- }
-
- if (JSSTRING_LENGTH(message) != 0) {
- name_length = JSSTRING_LENGTH(name);
- message_length = JSSTRING_LENGTH(message);
- length = name_length + message_length + 2;
- cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!chars)
- return JS_FALSE;
-
- js_strncpy(cp, JSSTRING_CHARS(name), name_length);
- cp += name_length;
- *cp++ = ':'; *cp++ = ' ';
- js_strncpy(cp, JSSTRING_CHARS(message), message_length);
- cp += message_length;
- *cp = 0;
-
- result = js_NewString(cx, chars, length, 0);
- if (!result) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- } else {
- result = name;
- }
-
- *rval = STRING_TO_JSVAL(result);
- return JS_TRUE;
-}
-
-#if JS_HAS_TOSOURCE
-/*
- * Return a string that may eval to something similar to the original object.
- */
-static JSBool
-exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
- JSString *name, *message, *filename, *lineno_as_str, *result;
- int32 lineno;
- size_t lineno_length, name_length, message_length, filename_length, length;
- jschar *chars, *cp;
-
- if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))
- return JS_FALSE;
- name = js_ValueToString(cx, v);
- if (!name)
- return JS_FALSE;
-
- if (!JS_GetProperty(cx, obj, js_message_str, &v) ||
- !(message = js_ValueToSource(cx, v))) {
- return JS_FALSE;
- }
-
- if (!JS_GetProperty(cx, obj, js_filename_str, &v) ||
- !(filename = js_ValueToSource(cx, v))) {
- return JS_FALSE;
- }
-
- if (!JS_GetProperty(cx, obj, js_lineno_str, &v) ||
- !js_ValueToInt32 (cx, v, &lineno)) {
- return JS_FALSE;
- }
-
- if (lineno != 0) {
- if (!(lineno_as_str = js_ValueToString(cx, v))) {
- return JS_FALSE;
- }
- lineno_length = JSSTRING_LENGTH(lineno_as_str);
- } else {
- lineno_as_str = NULL;
- lineno_length = 0;
- }
-
- /* Magic 8, for the characters in ``(new ())''. */
- name_length = JSSTRING_LENGTH(name);
- message_length = JSSTRING_LENGTH(message);
- length = 8 + name_length + message_length;
-
- filename_length = JSSTRING_LENGTH(filename);
- if (filename_length != 0) {
- /* append filename as ``, {filename}'' */
- length += 2 + filename_length;
- if (lineno_as_str) {
- /* append lineno as ``, {lineno_as_str}'' */
- length += 2 + lineno_length;
- }
- } else {
- if (lineno_as_str) {
- /*
- * no filename, but have line number,
- * need to append ``, "", {lineno_as_str}''
- */
- length += 6 + lineno_length;
- }
- }
-
- cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!chars)
- return JS_FALSE;
-
- *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
- js_strncpy(cp, JSSTRING_CHARS(name), name_length);
- cp += name_length;
- *cp++ = '(';
- if (message_length != 0) {
- js_strncpy(cp, JSSTRING_CHARS(message), message_length);
- cp += message_length;
- }
-
- if (filename_length != 0) {
- /* append filename as ``, {filename}'' */
- *cp++ = ','; *cp++ = ' ';
- js_strncpy(cp, JSSTRING_CHARS(filename), filename_length);
- cp += filename_length;
- } else {
- if (lineno_as_str) {
- /*
- * no filename, but have line number,
- * need to append ``, "", {lineno_as_str}''
- */
- *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
- }
- }
- if (lineno_as_str) {
- /* append lineno as ``, {lineno_as_str}'' */
- *cp++ = ','; *cp++ = ' ';
- js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length);
- cp += lineno_length;
- }
-
- *cp++ = ')'; *cp++ = ')'; *cp = 0;
-
- result = js_NewString(cx, chars, length, 0);
- if (!result) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(result);
- return JS_TRUE;
-}
-#endif
-
-static JSFunctionSpec exception_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, exn_toSource, 0,0,0},
-#endif
- {js_toString_str, exn_toString, 0,0,0},
- {0,0,0,0,0}
-};
-
-JSObject *
-js_InitExceptionClasses(JSContext *cx, JSObject *obj)
-{
- int i;
- JSObject *protos[JSEXN_LIMIT];
-
- /* Initialize the prototypes first. */
- for (i = 0; exceptions[i].name != 0; i++) {
- JSAtom *atom;
- JSFunction *fun;
- JSString *nameString;
- int protoIndex = exceptions[i].protoIndex;
-
- /* Make the prototype for the current constructor name. */
- protos[i] = js_NewObject(cx, &ExceptionClass,
- (protoIndex != JSEXN_NONE)
- ? protos[protoIndex]
- : NULL,
- obj);
- if (!protos[i])
- return NULL;
-
- /* So exn_finalize knows whether to destroy private data. */
- OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_VOID);
-
- atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0);
- if (!atom)
- return NULL;
-
- /* Make a constructor function for the current name. */
- fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0);
- if (!fun)
- return NULL;
-
- /* Make this constructor make objects of class Exception. */
- fun->clasp = &ExceptionClass;
-
- /* Make the prototype and constructor links. */
- if (!js_SetClassPrototype(cx, fun->object, protos[i],
- JSPROP_READONLY | JSPROP_PERMANENT)) {
- return NULL;
- }
-
- /* proto bootstrap bit from JS_InitClass omitted. */
- nameString = JS_NewStringCopyZ(cx, exceptions[i].name);
- if (!nameString)
- return NULL;
-
- /* Add the name property to the prototype. */
- if (!JS_DefineProperty(cx, protos[i], js_name_str,
- STRING_TO_JSVAL(nameString),
- NULL, NULL,
- JSPROP_ENUMERATE)) {
- return NULL;
- }
- }
-
- /*
- * Add an empty message property. (To Exception.prototype only,
- * because this property will be the same for all the exception
- * protos.)
- */
- if (!JS_DefineProperty(cx, protos[0], js_message_str,
- STRING_TO_JSVAL(cx->runtime->emptyString),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return NULL;
- }
- if (!JS_DefineProperty(cx, protos[0], js_filename_str,
- STRING_TO_JSVAL(cx->runtime->emptyString),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return NULL;
- }
- if (!JS_DefineProperty(cx, protos[0], js_lineno_str,
- INT_TO_JSVAL(0),
- NULL, NULL, JSPROP_ENUMERATE)) {
- return NULL;
- }
-
- /*
- * Add methods only to Exception.prototype, because ostensibly all
- * exception types delegate to that.
- */
- if (!JS_DefineFunctions(cx, protos[0], exception_methods))
- return NULL;
-
- return protos[0];
-}
-
-static JSExnType errorToExceptionNum[] = {
-#define MSG_DEF(name, number, count, exception, format) \
- exception,
-#include "js.msg"
-#undef MSG_DEF
-};
-
-#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
-/* For use below... get character strings for error name and exception name */
-static struct exnname { char *name; char *exception; } errortoexnname[] = {
-#define MSG_DEF(name, number, count, exception, format) \
- {#name, #exception},
-#include "js.msg"
-#undef MSG_DEF
-};
-#endif /* DEBUG */
-
-JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
-{
- JSErrNum errorNumber;
- JSExnType exn;
- JSBool ok;
- JSObject *errProto, *errObject;
- JSString *messageStr, *filenameStr;
- uintN lineno;
- JSExnPrivate *privateData;
-
- /*
- * Tell our caller to report immediately if cx has no active frames, or if
- * this report is just a warning.
- */
- JS_ASSERT(reportp);
- if (!cx->fp || JSREPORT_IS_WARNING(reportp->flags))
- return JS_FALSE;
-
- /* Find the exception index associated with this error. */
- errorNumber = (JSErrNum) reportp->errorNumber;
- exn = errorToExceptionNum[errorNumber];
- JS_ASSERT(exn < JSEXN_LIMIT);
-
-#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
- /* Print the error name and the associated exception name to stderr */
- fprintf(stderr, "%s\t%s\n",
- errortoexnname[errorNumber].name,
- errortoexnname[errorNumber].exception);
-#endif
-
- /*
- * Return false (no exception raised) if no exception is associated
- * with the given error number.
- */
- if (exn == JSEXN_NONE)
- return JS_FALSE;
-
- /*
- * Prevent runaway recursion, just as the Exception native constructor
- * must do, via cx->creatingException. If an out-of-memory error occurs,
- * no exception object will be created, but we don't assume that OOM is
- * the only kind of error that subroutines of this function called below
- * might raise.
- */
- if (cx->creatingException)
- return JS_FALSE;
- cx->creatingException = JS_TRUE;
-
- /*
- * Try to get an appropriate prototype by looking up the corresponding
- * exception constructor name in the scope chain of the current context's
- * top stack frame, or in the global object if no frame is active.
- *
- * XXXbe hack around JSCLASS_NEW_RESOLVE code in js_LookupProperty that
- * checks cx->fp, cx->fp->pc, and js_CodeSpec[*cx->fp->pc] in order
- * to compute resolve flags such as JSRESOLVE_ASSIGNING. The bug
- * is that this "internal" js_GetClassPrototype call may trigger a
- * resolve of exceptions[exn].name if the global object uses a lazy
- * standard class resolver (see JS_ResolveStandardClass), but the
- * current frame and bytecode end up affecting the resolve flags.
- */
- {
- JSStackFrame *fp = cx->fp;
- jsbytecode *pc = NULL;
-
- if (fp) {
- pc = fp->pc;
- fp->pc = NULL;
- }
- ok = js_GetClassPrototype(cx, exceptions[exn].name, &errProto);
- if (pc)
- fp->pc = pc;
- if (!ok)
- goto out;
- }
-
- errObject = js_NewObject(cx, &ExceptionClass, errProto, NULL);
- if (!errObject) {
- ok = JS_FALSE;
- goto out;
- }
-
- /*
- * Set the generated Exception object early, so it won't be GC'd by a last
- * ditch attempt to collect garbage, or a GC that otherwise nests or races
- * under any of the following calls. If one of the following calls fails,
- * it will overwrite this exception object with one of its own (except in
- * case of OOM errors, of course).
- */
- JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
-
- messageStr = JS_NewStringCopyZ(cx, message);
- if (!messageStr) {
- ok = JS_FALSE;
- goto out;
- }
-
- if (reportp) {
- filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
- if (!filenameStr) {
- ok = JS_FALSE;
- goto out;
- }
- lineno = reportp->lineno;
- } else {
- filenameStr = cx->runtime->emptyString;
- lineno = 0;
- }
- ok = InitExceptionObject(cx, errObject, messageStr, filenameStr, lineno);
- if (!ok)
- goto out;
-
- /*
- * Construct a new copy of the error report struct, and store it in the
- * exception object's private data. We can't use the error report struct
- * that was passed in, because it's stack-allocated, and also because it
- * may point to transient data in the JSTokenStream.
- */
- privateData = exn_newPrivate(cx, reportp);
- if (!privateData) {
- ok = JS_FALSE;
- goto out;
- }
- OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData));
-
- /* Flag the error report passed in to indicate an exception was raised. */
- reportp->flags |= JSREPORT_EXCEPTION;
-
-out:
- cx->creatingException = JS_FALSE;
- return ok;
-}
-#endif /* JS_HAS_ERROR_EXCEPTIONS */
-
-#if JS_HAS_EXCEPTIONS
-
-JSBool
-js_ReportUncaughtException(JSContext *cx)
-{
- JSObject *exnObject;
- JSString *str;
- jsval exn;
- JSErrorReport *reportp;
- const char *bytes;
-
- if (!JS_IsExceptionPending(cx))
- return JS_FALSE;
-
- if (!JS_GetPendingException(cx, &exn))
- return JS_FALSE;
-
- /*
- * Because js_ValueToString below could error and an exception object
- * could become unrooted, we root it here.
- */
- if (JSVAL_IS_OBJECT(exn) && exn != JSVAL_NULL) {
- exnObject = JSVAL_TO_OBJECT(exn);
- if (!js_AddRoot(cx, &exnObject, "exn.report.root"))
- return JS_FALSE;
- } else {
- exnObject = NULL;
- }
-
-#if JS_HAS_ERROR_EXCEPTIONS
- reportp = js_ErrorFromException(cx, exn);
-#else
- reportp = NULL;
-#endif
-
- str = js_ValueToString(cx, exn);
- bytes = str ? js_GetStringBytes(str) : "null";
-
- if (reportp == NULL) {
- /*
- * XXXmccabe todo: Instead of doing this, synthesize an error report
- * struct that includes the filename, lineno where the exception was
- * originally thrown.
- */
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_UNCAUGHT_EXCEPTION, bytes);
- } else {
- /* Flag the error as an exception. */
- reportp->flags |= JSREPORT_EXCEPTION;
- js_ReportErrorAgain(cx, bytes, reportp);
- }
-
- if (exnObject != NULL)
- js_RemoveRoot(cx->runtime, &exnObject);
- return JS_TRUE;
-}
-
-#endif /* JS_HAS_EXCEPTIONS */
diff --git a/src/extension/script/js/jsexn.h b/src/extension/script/js/jsexn.h
deleted file mode 100644
index aeaab0a58..000000000
--- a/src/extension/script/js/jsexn.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS runtime exception classes.
- */
-
-#ifndef jsexn_h___
-#define jsexn_h___
-
-JS_BEGIN_EXTERN_C
-
-/*
- * Initialize the exception constructor/prototype hierarchy.
- */
-extern JSObject *
-js_InitExceptionClasses(JSContext *cx, JSObject *obj);
-
-/*
- * String constants naming the exception classes.
- */
-extern const char js_Error_str[];
-extern const char js_InternalError_str[];
-extern const char js_EvalError_str[];
-extern const char js_RangeError_str[];
-extern const char js_ReferenceError_str[];
-extern const char js_SyntaxError_str[];
-extern const char js_TypeError_str[];
-extern const char js_URIError_str[];
-
-/*
- * Given a JSErrorReport, check to see if there is an exception associated with
- * the error number. If there is, then create an appropriate exception object,
- * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
- * error report. Exception-aware host error reporters should probably ignore
- * error reports so flagged. Returns JS_TRUE if an associated exception is
- * found and set, JS_FALSE otherwise..
- */
-extern JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
-
-/*
- * Called if a JS API call to js_Execute or js_InternalCall fails; calls the
- * error reporter with the error report associated with any uncaught exception
- * that has been raised. Returns true if there was an exception pending, and
- * the error reporter was actually called.
- *
- * The JSErrorReport * that the error reporter is called with is currently
- * associated with a JavaScript object, and is not guaranteed to persist after
- * the object is collected. Any persistent uses of the JSErrorReport contents
- * should make their own copy.
- *
- * The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag
- * set; embeddings that want to silently propagate JavaScript exceptions to
- * other contexts may want to use an error reporter that ignores errors with
- * this flag.
- */
-extern JSBool
-js_ReportUncaughtException(JSContext *cx);
-
-extern JSErrorReport *
-js_ErrorFromException(JSContext *cx, jsval exn);
-
-JS_END_EXTERN_C
-
-#endif /* jsexn_h___ */
diff --git a/src/extension/script/js/jsfile.c b/src/extension/script/js/jsfile.c
deleted file mode 100644
index ef5e93b29..000000000
--- a/src/extension/script/js/jsfile.c
+++ /dev/null
@@ -1,2610 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS File object
- */
-#if JS_HAS_FILE_OBJECT
-
-#include "jsstddef.h"
-
-/* ----------------- Platform-specific includes and defines ----------------- */
-#ifdef XP_MAC
-# define FILESEPARATOR ':'
-# define FILESEPARATOR2 '\0'
-# define CURRENT_DIR "HARD DISK:Desktop Folder"
-/* TODO: #include <???> */
-#elif defined(XP_WIN) || defined(XP_OS2)
-# include <direct.h>
-# include <io.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# define FILESEPARATOR '\\'
-# define FILESEPARATOR2 '/'
-# define CURRENT_DIR "c:\\"
-# define POPEN _popen
-# define PCLOSE _pclose
-#elif defined(XP_UNIX) || defined(XP_BEOS)
-# include <strings.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <unistd.h>
-# define FILESEPARATOR '/'
-# define FILESEPARATOR2 '\0'
-# define CURRENT_DIR "/"
-# define POPEN popen
-# define PCLOSE pclose
-#endif
-
-/* --------------- Platform-independent includes and defines ---------------- */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsdate.h"
-#include "jsdbgapi.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jslock.h"
-#include "jsobj.h"
-#include "jsparse.h"
-#include "jsscan.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include <string.h>
-
-/* NSPR dependencies */
-#include "prio.h"
-#include "prerror.h"
-
-#define SPECIAL_FILE_STRING "Special File"
-#define CURRENTDIR_PROPERTY "currentDir"
-#define SEPARATOR_PROPERTY "separator"
-#define FILE_CONSTRUCTOR "File"
-#define PIPE_SYMBOL '|'
-
-#define ASCII 0
-#define UTF8 1
-#define UCS2 2
-
-#define asciistring "text"
-#define utfstring "binary"
-#define unicodestring "unicode"
-
-#define MAX_PATH_LENGTH 1024
-#define MODE_SIZE 256
-#define NUMBER_SIZE 32
-#define MAX_LINE_LENGTH 256
-#define URL_PREFIX "file://"
-
-#define STDINPUT_NAME "Standard input stream"
-#define STDOUTPUT_NAME "Standard output stream"
-#define STDERROR_NAME "Standard error stream"
-
-#define RESOLVE_PATH js_canonicalPath /* js_absolutePath */
-
-/* Error handling */
-typedef enum JSFileErrNum {
-#define MSG_DEF(name, number, count, exception, format) \
- name = number,
-#include "jsfile.msg"
-#undef MSG_DEF
- JSFileErr_Limit
-#undef MSGDEF
-} JSFileErrNum;
-
-#define JSFILE_HAS_DFLT_MSG_STRINGS 1
-
-JSErrorFormatString JSFile_ErrorFormatString[JSFileErr_Limit] = {
-#if JSFILE_HAS_DFLT_MSG_STRINGS
-#define MSG_DEF(name, number, count, exception, format) \
- { format, count } ,
-#else
-#define MSG_DEF(name, number, count, exception, format) \
- { NULL, count } ,
-#endif
-#include "jsfile.msg"
-#undef MSG_DEF
-};
-
-const JSErrorFormatString *
-JSFile_GetErrorMessage(void *userRef, const char *locale,
- const uintN errorNumber)
-{
- if ((errorNumber > 0) && (errorNumber < JSFileErr_Limit))
- return &JSFile_ErrorFormatString[errorNumber];
- else
- return NULL;
-}
-
-#define JSFILE_CHECK_NATIVE(op) \
- if(file->isNative){ \
- JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s", \
- op, file->path); \
- goto out; \
- }
-
-#define JSFILE_CHECK_WRITE \
- if (!file->isOpen){ \
- JS_ReportWarning(cx, \
- "File %s is closed, will open it for writing, proceeding", \
- file->path); \
- js_FileOpen(cx, obj, file, "write,append,create"); \
- }else \
- if(!js_canWrite(cx, file)){ \
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
- JSFILEMSG_CANNOT_WRITE, file->path); \
- goto out; \
- }
-
-#define JSFILE_CHECK_READ \
- if (!file->isOpen){ \
- JS_ReportWarning(cx, \
- "File %s is closed, will open it for reading, proceeding", \
- file->path); \
- js_FileOpen(cx, obj, file, "read"); \
- }else \
- if(!js_canRead(cx, file)){ \
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
- JSFILEMSG_CANNOT_READ, file->path); \
- goto out; \
- }
-
-#define JSFILE_CHECK_OPEN(op) \
- if(!file->isOpen){ \
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
- JSFILEMSG_FILE_MUST_BE_CLOSED, op); \
- goto out; \
- }
-
-#define JSFILE_CHECK_CLOSED(op) \
- if(file->isOpen){ \
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
- JSFILEMSG_FILE_MUST_BE_OPEN, op); \
- goto out; \
- }
-
-#define JSFILE_CHECK_ONE_ARG(op) \
- if (argc!=1){ \
- char str[NUMBER_SIZE]; \
- \
- sprintf(str, "%d", argc); \
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
- JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str); \
- goto out; \
- }
-
-
-/*
- Security mechanism, should define a callback for this.
- The parameters are as follows:
- SECURITY_CHECK(JSContext *cx, JSPrincipals *ps, char *op_name, JSFile *file)
-*/
-#define SECURITY_CHECK(cx, ps, op, file) \
- /* Define a callback here... */
-
-
-/* Structure representing the file internally */
-typedef struct JSFile {
- char *path; /* the path to the file. */
- JSBool isOpen;
- JSString *linebuffer; /* temp buffer used by readln. */
- int32 mode; /* mode used to open the file: read, write, append, create, etc.. */
- int32 type; /* Asciiz, utf, unicode */
- char byteBuffer[3]; /* bytes read in advance by js_FileRead ( UTF8 encoding ) */
- jsint nbBytesInBuf; /* number of bytes stored in the buffer above */
- jschar charBuffer; /* character read in advance by readln ( mac files only ) */
- JSBool charBufferUsed; /* flag indicating if the buffer above is being used */
- JSBool hasRandomAccess; /* can the file be randomly accessed? false for stdin, and
- UTF-encoded files. */
- JSBool hasAutoflush; /* should we force a flush for each line break? */
- JSBool isNative; /* if the file is using OS-specific file FILE type */
- /* We can actually put the following two in a union since they should never be used at the same time */
- PRFileDesc *handle; /* the handle for the file, if open. */
- FILE *nativehandle; /* native handle, for stuff NSPR doesn't do. */
- JSBool isPipe; /* if the file is really an OS pipe */
-} JSFile;
-
-/* a few forward declarations... */
-static JSClass file_class;
-JS_PUBLIC_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename);
-static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
-static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
-
-/* --------------------------- New filename manipulation procesures -------------------------- */
-/* assumes we don't have leading/trailing spaces */
-static JSBool
-js_filenameHasAPipe(const char *filename)
-{
-#ifdef XP_MAC
- /* pipes are not supported on the MAC */
- return JS_FALSE;
-#else
- if(!filename) return JS_FALSE;
- return filename[0]==PIPE_SYMBOL ||
- filename[strlen(filename)-1]==PIPE_SYMBOL;
-#endif
-}
-
-static JSBool
-js_isAbsolute(const char *name)
-{
-#if defined(XP_WIN) || defined(XP_OS2)
- return (strlen(name)>1)?((name[1]==':')?JS_TRUE:JS_FALSE):JS_FALSE;
-#else
- return (name[0]
-# if defined(XP_UNIX) || defined(XP_BEOS)
- ==
-# else
- !=
-# endif
- FILESEPARATOR)?JS_TRUE:JS_FALSE;
-#endif
-}
-
-/*
- Concatinates base and name to produce a valid filename.
- Returned string must be freed.
-*/
-static char*
-js_combinePath(JSContext *cx, const char *base, const char *name)
-{
- int len = strlen(base);
- char* result = (char*)JS_malloc(cx, len+strlen(name)+2);
-
- if (!result) return NULL;
-
- strcpy(result, base);
-
- if (base[len-1]!=FILESEPARATOR
-#if defined(XP_WIN) || defined(XP_OS2)
- && base[len-1]!=FILESEPARATOR2
-#endif
- ) {
- result[len] = FILESEPARATOR;
- result[len+1] = '\0';
- }
- strcat(result, name);
- return result;
-}
-
-/* Extract the last component from a path name. Returned string must be freed */
-static char *
-js_fileBaseName(JSContext *cx, const char *pathname)
-{
- jsint index, aux;
- char *result;
-
-#if defined(XP_WIN) || defined(XP_OS2)
- /* First, get rid of the drive selector */
- if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
- pathname = &pathname[2];
- }
-#endif
- index = strlen(pathname)-1;
- /*
- remove trailing separators -- don't necessarily need to check for
- FILESEPARATOR2, but that's fine
- */
- while ((index>0)&&((pathname[index]==FILESEPARATOR)||
- (pathname[index]==FILESEPARATOR2))) index--;
- aux = index;
- /* now find the next separator */
- while ((index>=0)&&(pathname[index]!=FILESEPARATOR)&&
- (pathname[index]!=FILESEPARATOR2)) index--;
- /* allocate and copy */
- result = (char*)JS_malloc(cx, aux-index+1);
- if (!result) return NULL;
- strncpy(result, &pathname[index+1], aux-index);
- result[aux-index] = '\0';
- return result;
-}
-
-/*
- Returns everytynig but the last component from a path name.
- Returned string must be freed. Returned string must be freed.
-*/
-static char *
-js_fileDirectoryName(JSContext *cx, const char *pathname)
-{
- jsint index;
- char *result;
-
-#if defined(XP_WIN) || defined(XP_OS2)
- char drive = '\0';
- const char *oldpathname = pathname;
-
- /* First, get rid of the drive selector */
- if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
- drive = pathname[0];
- pathname = &pathname[2];
- }
-#endif
- index = strlen(pathname)-1;
- while ((index>0)&&((pathname[index]==FILESEPARATOR)||
- (pathname[index]==FILESEPARATOR2))) index--;
- while ((index>0)&&(pathname[index]!=FILESEPARATOR)&&
- (pathname[index]!=FILESEPARATOR2)) index--;
-
- if (index>=0){
- result = (char*)JS_malloc(cx, index+4);
- if (!result) return NULL;
-#if defined(XP_WIN) || defined(XP_OS2)
- if (drive!='\0') {
- result[0] = toupper(drive);
- result[1] = ':';
- strncpy(&result[2], pathname, index);
- result[index+3] = '\0';
- }else
-#endif
- {
- strncpy(result, pathname, index);
- result[index] = '\0';
- }
-
- /* add terminating separator */
- index = strlen(result)-1;
- result[index] = FILESEPARATOR;
- result[index+1] = '\0';
- } else{
-#if defined(XP_WIN) || defined(XP_OS2)
- result = JS_strdup(cx, oldpathname); /* may include drive selector */
-#else
- result = JS_strdup(cx, pathname);
-#endif
- }
-
- return result;
-}
-
-static char *
-js_absolutePath(JSContext *cx, const char * path)
-{
- JSObject *obj;
- JSString *str;
- jsval prop;
-
- if (js_isAbsolute(path)){
- return JS_strdup(cx, path);
- }else{
- obj = JS_GetGlobalObject(cx);
- if (!JS_GetProperty(cx, obj, FILE_CONSTRUCTOR, &prop)) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
- return JS_strdup(cx, path);
- }
- obj = JSVAL_TO_OBJECT(prop);
- if (!JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, &prop)) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
- return JS_strdup(cx, path);
- }
- str = JS_ValueToString(cx, prop);
- if (!str ) {
- return JS_strdup(cx, path);
- }
- /* should we have an array of curr dirs indexed by drive for windows? */
- return js_combinePath(cx, JS_GetStringBytes(str), path);
- }
-}
-
-/* Side effect: will remove spaces in the beginning/end of the filename */
-static char *
-js_canonicalPath(JSContext *cx, char *oldpath)
-{
- char *tmp;
- char *path = oldpath;
- char *base, *dir, *current, *result;
- jsint c;
- jsint back = 0;
- unsigned int i = 0, j = strlen(path)-1;
-
- /* This is probably optional */
- /* Remove possible spaces in the beginning and end */
- while(i<strlen(path)-1 && path[i]==' ') i++;
- while(j>=0 && path[j]==' ') j--;
-
- tmp = JS_malloc(cx, j-i+2);
- strncpy(tmp, &path[i], j-i+1);
- tmp[j-i+1] = '\0';
-
- path = tmp;
-
- /* pipe support */
- if(js_filenameHasAPipe(path))
- return JS_strdup(cx, path);
- /* file:// support */
- if(!strncmp(path, URL_PREFIX, strlen(URL_PREFIX)))
- return js_canonicalPath(cx, &path[strlen(URL_PREFIX)-1]);
-
- if (!js_isAbsolute(path))
- path = js_absolutePath(cx, path);
- else
- path = JS_strdup(cx, path);
-
- result = JS_strdup(cx, "");
-
- current = path;
-
- base = js_fileBaseName(cx, current);
- dir = js_fileDirectoryName(cx, current);
-
- /* TODO: MAC -- not going to work??? */
- while (strcmp(dir, current)) {
- if (!strcmp(base, "..")) {
- back++;
- } else
- if(!strcmp(base, ".")){
- /* ??? */
- } else {
- if (back>0)
- back--;
- else {
- tmp = result;
- result = JS_malloc(cx, strlen(base)+1+strlen(tmp)+1);
- if (!result) {
- JS_free(cx, dir);
- JS_free(cx, base);
- JS_free(cx, current);
- return NULL;
- }
- strcpy(result, base);
- c = strlen(result);
- if (*tmp) {
- result[c] = FILESEPARATOR;
- result[c+1] = '\0';
- strcat(result, tmp);
- }
- JS_free(cx, tmp);
- }
- }
- JS_free(cx, current);
- JS_free(cx, base);
- current = dir;
- base = js_fileBaseName(cx, current);
- dir = js_fileDirectoryName(cx, current);
- }
-
- tmp = result;
- result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1);
- if (!result) {
- JS_free(cx, dir);
- JS_free(cx, base);
- JS_free(cx, current);
- return NULL;
- }
- strcpy(result, dir);
- c = strlen(result);
- if (tmp[0]!='\0') {
- if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) {
- result[c] = FILESEPARATOR;
- result[c+1] = '\0';
- }
- strcat(result, tmp);
- }
- JS_free(cx, tmp);
- JS_free(cx, dir);
- JS_free(cx, base);
- JS_free(cx, current);
-
- return result;
-}
-
-/* -------------------------- Text conversion ------------------------------- */
-/* The following is ripped from libi18n/unicvt.c and include files.. */
-
-/*
- * UTF8 defines and macros
- */
-#define ONE_OCTET_BASE 0x00 /* 0xxxxxxx */
-#define ONE_OCTET_MASK 0x7F /* x1111111 */
-#define CONTINUING_OCTET_BASE 0x80 /* 10xxxxxx */
-#define CONTINUING_OCTET_MASK 0x3F /* 00111111 */
-#define TWO_OCTET_BASE 0xC0 /* 110xxxxx */
-#define TWO_OCTET_MASK 0x1F /* 00011111 */
-#define THREE_OCTET_BASE 0xE0 /* 1110xxxx */
-#define THREE_OCTET_MASK 0x0F /* 00001111 */
-#define FOUR_OCTET_BASE 0xF0 /* 11110xxx */
-#define FOUR_OCTET_MASK 0x07 /* 00000111 */
-#define FIVE_OCTET_BASE 0xF8 /* 111110xx */
-#define FIVE_OCTET_MASK 0x03 /* 00000011 */
-#define SIX_OCTET_BASE 0xFC /* 1111110x */
-#define SIX_OCTET_MASK 0x01 /* 00000001 */
-
-#define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK ) == ONE_OCTET_BASE)
-#define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK ) == TWO_OCTET_BASE)
-#define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE)
-#define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE)
-#define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE)
-#define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK ) == SIX_OCTET_BASE)
-#define IS_UTF8_2ND_THRU_6TH(x) \
- (( (x)&~CONTINUING_OCTET_MASK ) == CONTINUING_OCTET_BASE)
-#define IS_UTF8_1ST_OF_UCS2(x) \
- IS_UTF8_1ST_OF_1(x) \
- || IS_UTF8_1ST_OF_2(x) \
- || IS_UTF8_1ST_OF_3(x)
-
-
-#define MAX_UCS2 0xFFFF
-#define DEFAULT_CHAR 0x003F /* Default char is "?" */
-#define BYTE_MASK 0xBF
-#define BYTE_MARK 0x80
-
-
-/* Function: one_ucs2_to_utf8_char
- *
- * Function takes one UCS-2 char and writes it to a UTF-8 buffer.
- * We need a UTF-8 buffer because we don't know before this
- * function how many bytes of utf-8 data will be written. It also
- * takes a pointer to the end of the UTF-8 buffer so that we don't
- * overwrite data. This function returns the number of UTF-8 bytes
- * of data written, or -1 if the buffer would have been overrun.
- */
-
-#define LINE_SEPARATOR 0x2028
-#define PARAGRAPH_SEPARATOR 0x2029
-static int16 one_ucs2_to_utf8_char(unsigned char *tobufp,
- unsigned char *tobufendp, uint16 onechar)
-{
-
- int16 numUTF8bytes = 0;
-
- if((onechar == LINE_SEPARATOR)||(onechar == PARAGRAPH_SEPARATOR))
- {
- strcpy((char*)tobufp, "\n");
- return strlen((char*)tobufp);;
- }
-
- if (onechar < 0x80) { numUTF8bytes = 1;
- } else if (onechar < 0x800) { numUTF8bytes = 2;
- } else if (onechar <= MAX_UCS2) { numUTF8bytes = 3;
- } else { numUTF8bytes = 2;
- onechar = DEFAULT_CHAR;
- }
-
- tobufp += numUTF8bytes;
-
- /* return error if we don't have space for the whole character */
- if (tobufp > tobufendp) {
- return(-1);
- }
-
-
- switch(numUTF8bytes) {
-
- case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
- *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
- *--tobufp = onechar | THREE_OCTET_BASE;
- break;
-
- case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
- *--tobufp = onechar | TWO_OCTET_BASE;
- break;
- case 1: *--tobufp = (unsigned char)onechar; break;
- }
-
- return(numUTF8bytes);
-}
-
-/*
- * utf8_to_ucs2_char
- *
- * Convert a utf8 multibyte character to ucs2
- *
- * inputs: pointer to utf8 character(s)
- * length of utf8 buffer ("read" length limit)
- * pointer to return ucs2 character
- *
- * outputs: number of bytes in the utf8 character
- * -1 if not a valid utf8 character sequence
- * -2 if the buffer is too short
- */
-static int16
-utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p)
-{
- uint16 lead, cont1, cont2;
-
- /*
- * Check for minimum buffer length
- */
- if ((buflen < 1) || (utf8p == NULL)) {
- return -2;
- }
- lead = (uint16) (*utf8p);
-
- /*
- * Check for a one octet sequence
- */
- if (IS_UTF8_1ST_OF_1(lead)) {
- *ucs2p = lead & ONE_OCTET_MASK;
- return 1;
- }
-
- /*
- * Check for a two octet sequence
- */
- if (IS_UTF8_1ST_OF_2(*utf8p)) {
- if (buflen < 2)
- return -2;
- cont1 = (uint16) *(utf8p+1);
- if (!IS_UTF8_2ND_THRU_6TH(cont1))
- return -1;
- *ucs2p = (lead & TWO_OCTET_MASK) << 6;
- *ucs2p |= cont1 & CONTINUING_OCTET_MASK;
- return 2;
- }
-
- /*
- * Check for a three octet sequence
- */
- else if (IS_UTF8_1ST_OF_3(lead)) {
- if (buflen < 3)
- return -2;
- cont1 = (uint16) *(utf8p+1);
- cont2 = (uint16) *(utf8p+2);
- if ( (!IS_UTF8_2ND_THRU_6TH(cont1))
- || (!IS_UTF8_2ND_THRU_6TH(cont2)))
- return -1;
- *ucs2p = (lead & THREE_OCTET_MASK) << 12;
- *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6;
- *ucs2p |= cont2 & CONTINUING_OCTET_MASK;
- return 3;
- }
- else { /* not a valid utf8/ucs2 character */
- return -1;
- }
-}
-
-/* ----------------------------- Helper functions --------------------------- */
-/* Ripped off from lm_win.c .. */
-/* where is strcasecmp?.. for now, it's case sensitive..
- *
- * strcasecmp is in strings.h, but on windows it's called _stricmp...
- * will need to #ifdef this
-*/
-
-static int32
-js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name)
-{
- char *comma, *equal, *current;
- char *options = JS_strdup(cx, oldoptions);
- int32 found = 0;
-
- current = options;
- for (;;) {
- comma = strchr(current, ',');
- if (comma) *comma = '\0';
- equal = strchr(current, '=');
- if (equal) *equal = '\0';
- if (strcmp(current, name) == 0) {
- if (!equal || strcmp(equal + 1, "yes") == 0)
- found = 1;
- else
- found = atoi(equal + 1);
- }
- if (equal) *equal = '=';
- if (comma) *comma = ',';
- if (found || !comma)
- break;
- current = comma + 1;
- }
- JS_free(cx, options);
- return found;
-}
-
-/* empty the buffer */
-static void
-js_ResetBuffers(JSFile * file)
-{
- file->charBufferUsed = JS_FALSE;
- file->nbBytesInBuf = 0;
- file->linebuffer = NULL; /* TODO: check for mem. leak? */
-}
-
-/* Reset file attributes */
-static void
-js_ResetAttributes(JSFile * file){
- file->mode = file->type = 0;
- file->isOpen = JS_FALSE;
- file->handle = NULL;
- file->nativehandle = NULL;
- file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */
- file->hasAutoflush = JS_FALSE;
- file->isNative = JS_FALSE;
- file->isPipe = JS_FALSE;
-
- js_ResetBuffers(file);
-}
-
-static JSBool
-js_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){
- JSString *type, *mask;
- jsval v[2];
- jsval rval;
-
- type = JS_InternString(cx, asciistring);
- mask = JS_NewStringCopyZ(cx, mode);
- v[0] = STRING_TO_JSVAL(mask);
- v[1] = STRING_TO_JSVAL(type);
-
- if (!file_open(cx, obj, 2, v, &rval)) {
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-/* Buffered version of PR_Read. Used by js_FileRead */
-static int32
-js_BufferedRead(JSFile * f, char *buf, int32 len)
-{
- int32 count = 0;
-
- while (f->nbBytesInBuf>0&&len>0) {
- buf[0] = f->byteBuffer[0];
- f->byteBuffer[0] = f->byteBuffer[1];
- f->byteBuffer[1] = f->byteBuffer[2];
- f->nbBytesInBuf--;
- len--;
- buf+=1;
- count++;
- }
-
- if (len>0) {
- count+= (!f->isNative)?
- PR_Read(f->handle, buf, len):
- fread(buf, 1, len, f->nativehandle);
- }
- return count;
-}
-
-static int32
-js_FileRead(JSContext *cx, JSFile * file, jschar*buf, int32 len, int32 mode)
-{
- unsigned char*aux;
- int32 count, i;
- jsint remainder;
- unsigned char utfbuf[3];
-
- if (file->charBufferUsed) {
- buf[0] = file->charBuffer;
- buf++;
- len--;
- file->charBufferUsed = JS_FALSE;
- }
-
- switch (mode) {
- case ASCII:
- aux = (unsigned char*)JS_malloc(cx, len);
- if (!aux) {
- return 0;
- }
- count = js_BufferedRead(file, aux, len);
- if (count==-1) {
- JS_free(cx, aux);
- return 0;
- }
- for (i = 0;i<len;i++) {
- buf[i] = (jschar)aux[i];
- }
- JS_free(cx, aux);
- break;
- case UTF8:
- remainder = 0;
- for (count = 0;count<len;count++) {
- i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
- if (i<=0) {
- return count;
- }
- i = utf8_to_ucs2_char(utfbuf, (int16)i, &buf[count] );
- if (i<0) {
- return count;
- } else {
- if (i==1) {
- utfbuf[0] = utfbuf[1];
- utfbuf[1] = utfbuf[2];
- remainder = 2;
- } else
- if (i==2) {
- utfbuf[0] = utfbuf[2];
- remainder = 1;
- } else
- if (i==3)
- remainder = 0;
- }
- }
- while (remainder>0) {
- file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
- file->nbBytesInBuf++;
- utfbuf[0] = utfbuf[1];
- utfbuf[1] = utfbuf[2];
- remainder--;
- }
- break;
- case UCS2:
- count = js_BufferedRead(file, (char*)buf, len*2)>>1;
- if (count==-1) {
- return 0;
- }
- break;
- }
-
- if(count==-1){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "read", file->path);
- }
-
- return count;
-}
-
-static int32
-js_FileSeek(JSContext *cx, JSFile *file, int32 len, int32 mode)
-{
- int32 count, i;
- jsint remainder;
- unsigned char utfbuf[3];
- jschar tmp;
-
- switch (mode) {
- case ASCII:
- count = PR_Seek(file->handle, len, PR_SEEK_CUR);
- break;
- case UTF8:
- remainder = 0;
- for (count = 0;count<len;count++) {
- i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
- if (i<=0) {
- return 0;
- }
- i = utf8_to_ucs2_char(utfbuf, (int16)i, &tmp );
- if (i<0) {
- return 0;
- } else {
-
- if (i==1) {
- utfbuf[0] = utfbuf[1];
- utfbuf[1] = utfbuf[2];
- remainder = 2;
- } else
- if (i==2) {
- utfbuf[0] = utfbuf[2];
- remainder = 1;
- } else
- if (i==3)
- remainder = 0;
- }
- }
- while (remainder>0) {
- file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
- file->nbBytesInBuf++;
- utfbuf[0] = utfbuf[1];
- utfbuf[1] = utfbuf[2];
- remainder--;
- }
- break;
- case UCS2:
- count = PR_Seek(file->handle, len*2, PR_SEEK_CUR)/2;
- break;
- }
-
- if(count==-1){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "seek", file->path);
- }
-
- return count;
-}
-
-static int32
-js_FileWrite(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
-{
- unsigned char *aux;
- int32 count, i, j;
- unsigned char *utfbuf;
-
- switch (mode) {
- case ASCII:
- aux = (unsigned char*)JS_malloc(cx, len);
- if (!aux) return 0;
-
- for (i = 0; i<len; i++) {
- aux[i]=buf[i]%256;
- }
-
- count = (!file->isNative)?
- PR_Write(file->handle, aux, len):
- fwrite(aux, 1, len, file->nativehandle);
-
- if (count==-1) {
- JS_free(cx, aux);
- return 0;
- }
- JS_free(cx, aux);
- break;
- case UTF8:
- utfbuf = (unsigned char*)JS_malloc(cx, len*3);
- if (!utfbuf) return 0;
- i = 0;
- for (count = 0;count<len;count++) {
- j = one_ucs2_to_utf8_char(utfbuf+i, utfbuf+len*3, buf[count]);
- if (j==-1) {
- JS_free(cx, utfbuf);
- return 0;
- }
- i+=j;
- }
- j = (!file->isNative)?
- PR_Write(file->handle, utfbuf, i):
- fwrite(utfbuf, 1, i, file->nativehandle);
-
- if (j<i) {
- JS_free(cx, utfbuf);
- return 0;
- }
- JS_free(cx, utfbuf);
- break;
- case UCS2:
- count = (!file->isNative)?
- PR_Write(file->handle, buf, len*2)>>1:
- fwrite(buf, 1, len*2, file->nativehandle)>>1;
-
- if (count==-1) {
- return 0;
- }
- break;
- }
- if(count==-1){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "write", file->path);
- }
- return count;
-}
-
-/* ----------------------------- Property checkers -------------------------- */
-static JSBool
-js_exists(JSContext *cx, JSFile *file)
-{
- if(!file->isNative){
- return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
- }else{
- /* doesn't make sense for a pipe of stdstream */
- return JS_FALSE;
- }
-}
-
-static JSBool
-js_canRead(JSContext *cx, JSFile *file)
-{
- if(!file->isNative){
- if(file->isOpen&&!(file->mode&PR_RDONLY)) return JS_FALSE;
- return (PR_Access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
- }else{
- if(file->isPipe){
- /* pipe open for reading */
- return file->path[0]==PIPE_SYMBOL;
- }else{
- return !strcmp(file->path, STDINPUT_NAME);
- }
- }
-}
-
-static JSBool
-js_canWrite(JSContext *cx, JSFile *file)
-{
- if(!file->isNative){
- if(file->isOpen&&!(file->mode&PR_WRONLY)) return JS_FALSE;
- return (PR_Access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
- }else{
- if(file->isPipe){
- /* pipe open for writing */
- return file->path[strlen(file->path)-1]==PIPE_SYMBOL;
- }else{
- return !strcmp(file->path, STDOUTPUT_NAME) ||
- !strcmp(file->path, STDERROR_NAME);
- }
- }
-}
-
-static JSBool
-js_isFile(JSContext *cx, JSFile *file)
-{
- if(!file->isNative){
- PRFileInfo info;
-
- if ((file->isOpen)?
- PR_GetOpenFileInfo(file->handle, &info):
- PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
- return JS_FALSE;
- }else
- return (info.type==PR_FILE_FILE);
- }else{
- /* doesn't make sense for a pipe of stdstream */
- return JS_FALSE;
- }
-}
-
-static JSBool
-js_isDirectory(JSContext *cx, JSFile *file)
-{
- if(!file->isNative){
- PRFileInfo info;
-
- /* hack needed to get get_property to work */
- if(!js_exists(cx, file)) return JS_FALSE;
-
- if ((file->isOpen)?
- PR_GetOpenFileInfo(file->handle, &info):
- PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
- return JS_FALSE;
- }else
- return (info.type==PR_FILE_DIRECTORY);
- }else{
- /* doesn't make sense for a pipe of stdstream */
- return JS_FALSE;
- }
-}
-
-static jsval
-js_size(JSContext *cx, JSFile *file)
-{
- PRFileInfo info;
-
- JSFILE_CHECK_NATIVE("size");
-
- if ((file->isOpen)?
- PR_GetOpenFileInfo(file->handle, &info):
- PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
- goto out;
- }else
- return INT_TO_JSVAL(info.size);
-out:
- return JSVAL_VOID;
-}
-
-/* Return the parent object */
-static jsval
-js_parent(JSContext *cx, JSFile *file)
-{
- char *str;
-
- /* since we only care about pipes and native files, return NULL */
- if(file->isNative) return JSVAL_VOID;
-
- str = js_fileDirectoryName(cx, file->path);
- /* root.parent = null ??? */
- if(!strcmp(file->path, str) ||
- (!strncmp(str, file->path, strlen(str)-1)&&
- file->path[strlen(file->path)]-1)==FILESEPARATOR){
- return JSVAL_NULL;
- }else{
- return OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
- JS_free(cx, str);
- }
-}
-
-static jsval
-js_name(JSContext *cx, JSFile *file){
- return file->isPipe?
- JSVAL_VOID:
- STRING_TO_JSVAL(JS_NewStringCopyZ(cx, js_fileBaseName(cx, file->path)));
-}
-
-/* ------------------------------ File object methods ---------------------------- */
-static JSBool
-file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSString *strmode, *strtype;
- char *ctype, *mode;
- int32 mask, type;
- int len;
-
- SECURITY_CHECK(cx, NULL, "open", file);
-
- /* A native file that is already open */
- if(file->isOpen && file->isNative){
- JS_ReportWarning(cx, "Native file %s is already open, proceeding",
- file->path);
- goto good;
- }
-
- /* Close before proceeding */
- if (file->isOpen) {
- JS_ReportWarning(cx,
- "File %s is already open, we will close it and reopen, proceeding",
- file->path);
- if(!file_close(cx, obj, 0, NULL, rval)) goto out;
- }
-
- if(js_isDirectory(cx, file)){
- JS_ReportWarning(cx, "%s seems to be a directory, there is no point in "
- "trying to open it, proceeding", file->path);
- goto good;
- }
-
- /* Path must be defined at this point */
- len = strlen(file->path);
-
- /* Mode */
- if (argc>=1){
- strmode = JS_ValueToString(cx, argv[0]);
- if (!strmode){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[0]);
- goto out;
- }
- mode = JS_strdup(cx, JS_GetStringBytes(strmode));
- }else{
- if(file->path[0]==PIPE_SYMBOL){
- /* pipe default mode */
- mode = JS_strdup(cx, "read");
- }else
- if(file->path[len-1]==PIPE_SYMBOL){
- /* pipe default mode */
- mode = JS_strdup(cx, "write");
- }else{
- /* non-destructive, permissive defaults. */
- mode = JS_strdup(cx, "readWrite,append,create");
- }
- }
-
- /* Process the mode */
- mask = 0;
- /* TODO: this is pretty ugly, BTW, we walk thru the string too many times */
- mask|=(js_FileHasOption(cx, mode, "read"))? PR_RDONLY : 0;
- mask|=(js_FileHasOption(cx, mode, "write"))? PR_WRONLY : 0;
- mask|=(js_FileHasOption(cx, mode, "readWrite"))? PR_RDWR : 0;
- mask|=(js_FileHasOption(cx, mode, "append"))? PR_APPEND : 0;
- mask|=(js_FileHasOption(cx, mode, "create"))? PR_CREATE_FILE : 0;
- mask|=(js_FileHasOption(cx, mode, "replace"))? PR_TRUNCATE : 0;
-
- if((mask&PR_RDWR)) mask|=(PR_RDONLY|PR_WRONLY);
- if((mask&PR_RDONLY)&&(mask&PR_WRONLY)) mask|=PR_RDWR;
-
- file->hasAutoflush|=(js_FileHasOption(cx, mode, "autoflush"));
-
- /* Type */
- if (argc>1) {
- strtype = JS_ValueToString(cx, argv[1]);
- if (!strtype) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[1]);
- goto out;
- }
- ctype = JS_GetStringBytes(strtype);
-
- if(!strcmp(ctype, utfstring))
- type = UTF8;
- else
- if (!strcmp(ctype, unicodestring))
- type = UCS2;
- else{
- if(strcmp(ctype, asciistring)){
- JS_ReportWarning(cx, "File type %s is not supported, using "
- "'text' instead, proceeding", ctype);
- }
- type = ASCII;
- }
- }else{
- type = ASCII;
- }
-
- /* Save the relevant fields */
- file->type = type;
- file->mode = mask;
- file->nativehandle = NULL;
- file->hasRandomAccess = (type!=UTF8);
-
- /*
- Deal with pipes here. We can't use NSPR for pipes,
- so we have to use POPEN.
- */
- if(file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL){
- if(file->path[0]==PIPE_SYMBOL && file->path[len-1]==PIPE_SYMBOL){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
- goto out;
- }else{
- char pipemode[3];
- SECURITY_CHECK(cx, NULL, "pipe_open", file);
-
- if(file->path[0] == PIPE_SYMBOL){
- if(mask & (PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
- mode, file->path);
- goto out;
- }
- /* open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") -- pipe for writing */
- pipemode[0] = 'r';
- pipemode[1] = file->type==UTF8?'b':'t';
- pipemode[2] = '\0';
- file->nativehandle = POPEN(&file->path[1], pipemode);
- }else
- if(file->path[len-1] == PIPE_SYMBOL){
- char *command = JS_malloc(cx, len);
-
- strncpy(command, file->path, len-1);
- command[len-1] = '\0';
- /* open(STATUS, "netstat -an 2>&1 |") */
- pipemode[0] = 'w';
- pipemode[1] = file->type==UTF8?'b':'t';
- pipemode[2] = '\0';
- file->nativehandle = POPEN(command, pipemode);
- JS_free(cx, command);
- }
- /* set the flags */
- file->isNative = JS_TRUE;
- file->isPipe = JS_TRUE;
- file->hasRandomAccess = JS_FALSE;
- }
- }else{
- /* TODO: what about the permissions?? Java ignores the problem... */
- file->handle = PR_Open(file->path, mask, 0644);
- }
-
- js_ResetBuffers(file);
- JS_free(cx, mode);
- mode = NULL;
-
- /* Set the open flag and return result */
- if (file->handle==NULL && file->nativehandle==NULL){
- file->isOpen = JS_FALSE;
-
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "open", file->path);
- goto out;
- }else
- goto good;
-good:
- file->isOpen = JS_TRUE;
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- if(mode) JS_free(cx, mode);
- *rval = JSVAL_VOID;
- return JS_FALSE;
-}
-
-static JSBool
-file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- SECURITY_CHECK(cx, NULL, "close", file);
-
- if(!file->isOpen){
- JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding",
- file->path);
- goto out;
- }
-
- if(!file->isPipe){
- if(file->isNative){
- JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path);
- goto out;
- }else{
- if(file->handle && PR_Close(file->handle)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "close", file->path);
-
- goto out;
- }
- }
- }else{
- if(PCLOSE(file->nativehandle)==-1){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "pclose", file->path);
- goto out;
- }
- }
-
- js_ResetAttributes(file);
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-
-static JSBool
-file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- SECURITY_CHECK(cx, NULL, "remove", file);
- JSFILE_CHECK_NATIVE("remove");
- JSFILE_CHECK_CLOSED("remove");
-
- if ((js_isDirectory(cx, file) ?
- PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
- js_ResetAttributes(file);
- *rval = JSVAL_TRUE;
- return JS_TRUE;
- } else {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "remove", file->path);
- goto out;
- }
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-/* Raw PR-based function. No text processing. Just raw data copying. */
-static JSBool
-file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- char *dest = NULL;
- PRFileDesc *handle = NULL;
- char *buffer;
- jsval count, size;
- JSBool fileInitiallyOpen=JS_FALSE;
-
- SECURITY_CHECK(cx, NULL, "copyTo", file); /* may need a second argument!*/
- JSFILE_CHECK_ONE_ARG("copyTo");
- JSFILE_CHECK_NATIVE("copyTo");
- /* remeber the state */
- fileInitiallyOpen = file->isOpen;
- JSFILE_CHECK_READ;
-
- dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-
- /* make sure we are not reading a file open for writing */
- if (file->isOpen && !js_canRead(cx, file)) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path);
- goto out;
- }
-
- if (file->handle==NULL){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "open", file->path);
- goto out;
- }
-
- handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644);
-
- if(!handle){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "open", dest);
- goto out;
- }
-
- if ((size=js_size(cx, file))==JSVAL_VOID) {
- goto out;
- }
-
- buffer = JS_malloc(cx, size);
-
- count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size));
-
- /* reading panic */
- if (count!=size) {
- JS_free(cx, buffer);
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_COPY_READ_ERROR, file->path);
- goto out;
- }
-
- count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size)));
-
- /* writing panic */
- if (count!=size) {
- JS_free(cx, buffer);
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_COPY_WRITE_ERROR, file->path);
- goto out;
- }
-
- JS_free(cx, buffer);
-
- if(!fileInitiallyOpen){
- if(!file_close(cx, obj, 0, NULL, rval)) goto out;
- }
-
- if(PR_Close(handle)!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "close", dest);
- goto out;
- }
-
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- if(file->isOpen && !fileInitiallyOpen){
- if(PR_Close(file->handle)!=PR_SUCCESS){
- JS_ReportWarning(cx, "Can't close %s, proceeding", file->path);
- }
- }
-
- if(handle && PR_Close(handle)!=PR_SUCCESS){
- JS_ReportWarning(cx, "Can't close %s, proceeding", dest);
- }
-
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- char *dest;
-
- SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/
- JSFILE_CHECK_ONE_ARG("renameTo");
- JSFILE_CHECK_NATIVE("renameTo");
- JSFILE_CHECK_CLOSED("renameTo");
-
- dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
-
- if (PR_Rename(file->path, dest)==PR_SUCCESS){
- /* copy the new filename */
- JS_free(cx, file->path);
- file->path = dest;
- *rval = JSVAL_TRUE;
- return JS_TRUE;
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_RENAME_FAILED, file->path, dest);
- goto out;
- }
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- SECURITY_CHECK(cx, NULL, "flush", file);
- JSFILE_CHECK_NATIVE("flush");
- JSFILE_CHECK_OPEN("flush");
-
- if (PR_Sync(file->handle)==PR_SUCCESS){
- *rval = JSVAL_TRUE;
- return JS_TRUE;
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "flush", file->path);
- goto out;
- }
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSString *str;
- int32 count;
- uintN i;
-
- SECURITY_CHECK(cx, NULL, "write", file);
- JSFILE_CHECK_WRITE;
-
- for (i = 0; i<argc; i++) {
- str = JS_ValueToString(cx, argv[i]);
- count = js_FileWrite(cx, file, JS_GetStringChars(str),
- JS_GetStringLength(str), file->type);
- if (count==-1){
- *rval = JSVAL_FALSE;
- return JS_FALSE;
- }
- }
-
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSString *str;
-
- SECURITY_CHECK(cx, NULL, "writeln", file);
- JSFILE_CHECK_WRITE;
-
- /* don't report an error here */
- if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE;
- /* don't do security here -- we passed the check in file_write */
- str = JS_NewStringCopyZ(cx, "\n");
-
- if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str),
- file->type)==-1){
- *rval = JSVAL_FALSE;
- return JS_FALSE;
- }
-
- /* eol causes flush if hasAutoflush is turned on */
- if (file->hasAutoflush)
- file_flush(cx, obj, 0, NULL, rval);
-
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- jsuint i;
- jsuint limit;
- JSObject *array;
- JSObject *elem;
- jsval elemval;
-
- SECURITY_CHECK(cx, NULL, "writeAll", file);
- JSFILE_CHECK_ONE_ARG("writeAll");
- JSFILE_CHECK_WRITE;
-
- if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR);
- goto out;
- }
-
- array = JSVAL_TO_OBJECT(argv[0]);
-
- JS_GetArrayLength(cx, array, &limit);
-
- for (i = 0; i<limit; i++) {
- if (!JS_GetElement(cx, array, i, &elemval)) return JS_FALSE;
- elem = JSVAL_TO_OBJECT(elemval);
- file_writeln(cx, obj, 1, &elemval, rval);
- }
-
- *rval = JSVAL_TRUE;
- return JS_TRUE;
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSString *str;
- int32 want, count;
- jschar *buf;
-
- SECURITY_CHECK(cx, NULL, "read", file);
- JSFILE_CHECK_ONE_ARG("read");
- JSFILE_CHECK_READ;
-
- if (!JS_ValueToInt32(cx, argv[0], &want)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "read", argv[0]);
- goto out;
- }
-
- /* want = (want>262144)?262144:want; * arbitrary size limitation */
-
- buf = JS_malloc(cx, want*sizeof buf[0]);
- if (!buf) goto out;
-
- count = js_FileRead(cx, file, buf, want, file->type);
- if (count>0) {
- str = JS_NewUCStringCopyN(cx, buf, count);
- *rval = STRING_TO_JSVAL(str);
- JS_free(cx, buf);
- return JS_TRUE;
- } else {
- JS_free(cx, buf);
- goto out;
- }
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSString *str;
- jschar *buf;
- int32 offset;
- intN room;
- jschar data, data2;
- JSBool endofline;
-
- SECURITY_CHECK(cx, NULL, "readln", file);
- JSFILE_CHECK_READ;
-
- if (!file->linebuffer) {
- buf = JS_malloc(cx, MAX_LINE_LENGTH*(sizeof data));
- if (!buf) goto out;
- file->linebuffer = JS_NewUCString(cx, buf, MAX_LINE_LENGTH);
- }
- room = JS_GetStringLength(file->linebuffer);
- offset = 0;
-
- /* XXX TEST ME!! TODO: yes, please do */
- for(;;) {
- if (!js_FileRead(cx, file, &data, 1, file->type)) {
- endofline = JS_FALSE;
- goto loop;
- }
- switch (data) {
- case '\n' :
- endofline = JS_TRUE;
- goto loop;
- case '\r' :
- if (!js_FileRead(cx, file, &data2, 1, file->type)) {
- endofline = JS_TRUE;
- goto loop;
- }
- if (data2!='\n') { /* We read one char too far. Buffer it. */
- file->charBuffer = data2;
- file->charBufferUsed = JS_TRUE;
- }
- endofline = JS_TRUE;
- goto loop;
- default:
- if (--room < 0) {
- buf = JS_malloc(cx, (offset+MAX_LINE_LENGTH)*sizeof data);
- if (!buf) return JS_FALSE;
- room = MAX_LINE_LENGTH-1;
- memcpy(buf, JS_GetStringChars(file->linebuffer),
- JS_GetStringLength(file->linebuffer));
- /* what follows may not be the cleanest way. */
- file->linebuffer->chars = buf;
- file->linebuffer->length = offset+MAX_LINE_LENGTH;
- }
- file->linebuffer->chars[offset++] = data;
- break;
- }
- }
-loop:
- file->linebuffer->chars[offset] = 0;
- if ((endofline==JS_TRUE)) {
- str = JS_NewUCStringCopyN(cx, JS_GetStringChars(file->linebuffer),
- offset);
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
- }else{
- goto out;
- }
-out:
- *rval = JSVAL_NULL;
- return JS_FALSE;
-}
-
-static JSBool
-file_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSObject *array;
- jsint len;
- jsval line;
-
- SECURITY_CHECK(cx, NULL, "readAll", file);
- JSFILE_CHECK_READ;
-
- array = JS_NewArrayObject(cx, 0, NULL);
- len = 0;
-
- while(file_readln(cx, obj, 0, NULL, &line)){
- JS_SetElement(cx, array, len, &line);
- len++;
- }
-
- *rval = OBJECT_TO_JSVAL(array);
- return JS_TRUE;
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- int32 toskip;
- int32 pos;
-
- SECURITY_CHECK(cx, NULL, "seek", file);
- JSFILE_CHECK_ONE_ARG("seek");
- JSFILE_CHECK_NATIVE("seek");
- JSFILE_CHECK_READ;
-
- if (!JS_ValueToInt32(cx, argv[0], &toskip)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "seek", argv[0]);
- goto out;
- }
-
- if(!file->hasRandomAccess){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_NO_RANDOM_ACCESS, file->path);
- goto out;
- }
-
- if(js_isDirectory(cx, file)){
- JS_ReportWarning(cx,"Seek on directories is not supported, proceeding");
- goto out;
- }
-
- pos = js_FileSeek(cx, file, toskip, file->type);
-
- if (pos!=-1) {
- *rval = INT_TO_JSVAL(pos);
- return JS_TRUE;
- }
-out:
- *rval = JSVAL_VOID;
- return JS_FALSE;
-}
-
-static JSBool
-file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- PRDir *dir;
- PRDirEntry *entry;
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- JSObject *array;
- JSObject *eachFile;
- jsint len;
- jsval v;
- JSRegExp *re = NULL;
- JSFunction *func = NULL;
- JSString *str;
- jsval args[1];
- char *filePath;
-
- SECURITY_CHECK(cx, NULL, "list", file);
- JSFILE_CHECK_NATIVE("list");
-
- if (argc==1) {
- if (JSVAL_IS_REGEXP(cx, argv[0])) {
- re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
- }else
- if (JSVAL_IS_FUNCTION(cx, argv[0])) {
- func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, argv[0]);
- goto out;
- }
- }
-
- if (!js_isDirectory(cx, file)) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, file->path);
- goto out;
- }
-
- dir = PR_OpenDir(file->path);
- if(!dir){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "open", file->path);
- goto out;
- }
-
- /* create JSArray here... */
- array = JS_NewArrayObject(cx, 0, NULL);
- len = 0;
-
- while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) {
- /* first, check if we have a regexp */
- if (re!=NULL) {
- size_t index = 0;
-
- str = JS_NewStringCopyZ(cx, entry->name);
- if(!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &v)){
- /* don't report anything here */
- goto out;
- }
- /* not matched! */
- if (JSVAL_IS_NULL(v)) {
- continue;
- }
- }else
- if (func!=NULL) {
- str = JS_NewStringCopyZ(cx, entry->name);
- args[0] = STRING_TO_JSVAL(str);
- if(!JS_CallFunction(cx, obj, func, 1, args, &v)){
- goto out;
- }
-
- if (v==JSVAL_FALSE) {
- continue;
- }
- }
-
- filePath = js_combinePath(cx, file->path, (char*)entry->name);
-
- eachFile = js_NewFileObject(cx, filePath);
- JS_free(cx, filePath);
- if (!eachFile){
- JS_ReportWarning(cx, "File %s cannot be retrieved", filePath);
- continue;
- }
- v = OBJECT_TO_JSVAL(eachFile);
- JS_SetElement(cx, array, len, &v);
- JS_SetProperty(cx, array, entry->name, &v);
- len++;
- }
-
- if(PR_CloseDir(dir)!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "close", file->path);
- goto out;
- }
- *rval = OBJECT_TO_JSVAL(array);
- return JS_TRUE;
-out:
- *rval = JSVAL_NULL;
- return JS_FALSE;
-}
-
-static JSBool
-file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- SECURITY_CHECK(cx, NULL, "mkdir", file);
- JSFILE_CHECK_ONE_ARG("mkdir");
- JSFILE_CHECK_NATIVE("mkdir");
-
- /* if the current file is not a directory, find out the directory name */
- if (!js_isDirectory(cx, file)) {
- char *dir = js_fileDirectoryName(cx, file->path);
- JSObject *dirObj = js_NewFileObject(cx, dir);
-
- JS_free(cx, dir);
-
- /* call file_mkdir with the right set of parameters if needed */
- if (file_mkdir(cx, dirObj, argc, argv, rval))
- return JS_TRUE;
- else
- goto out;
- }else{
- char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *fullName;
-
- fullName = js_combinePath(cx, file->path, dirName);
- if (PR_MkDir(fullName, 0755)==PR_SUCCESS){
- *rval = JSVAL_TRUE;
- JS_free(cx, fullName);
- return JS_TRUE;
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "mkdir", fullName);
- JS_free(cx, fullName);
- goto out;
- }
- }
-out:
- *rval = JSVAL_FALSE;
- return JS_FALSE;
-}
-
-static JSBool
-file_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
- return JS_TRUE;
-}
-
-static JSBool
-file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- char url[MAX_PATH_LENGTH];
- jschar *urlChars;
-
- JSFILE_CHECK_NATIVE("toURL");
-
- sprintf(url, "file://%s", file->path);
- /* TODO: js_escape in jsstr.h may go away at some point */
-
- urlChars = js_InflateString(cx, url, strlen(url));
- if (urlChars == NULL) return JS_FALSE;
- *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, strlen(url), 0));
- if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE;
-
- return JS_TRUE;
-out:
- *rval = JSVAL_VOID;
- return JS_FALSE;
-}
-
-
-static void
-file_finalize(JSContext *cx, JSObject *obj)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
-
- if(file){
- /* close the file before exiting */
- if(file->isOpen && !file->isNative){
- jsval vp;
- file_close(cx, obj, 0, NULL, &vp);
- }
-
- if (file->path)
- JS_free(cx, file->path);
-
- JS_free(cx, file);
- }
-}
-
-/*
- Allocates memory for the file object, sets fields to defaults.
-*/
-static JSFile*
-file_init(JSContext *cx, JSObject *obj, char *bytes)
-{
- JSFile *file;
-
- file = JS_malloc(cx, sizeof *file);
- if (!file) return NULL;
- memset(file, 0 , sizeof *file);
-
- js_ResetAttributes(file);
-
- file->path = RESOLVE_PATH(cx, bytes);
-
- if (!JS_SetPrivate(cx, obj, file)) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
- JS_free(cx, file);
- return NULL;
- }else
- return file;
-}
-
-/* Returns a JSObject. This function is globally visible */
-JS_PUBLIC_API(JSObject*)
-js_NewFileObject(JSContext *cx, char *filename)
-{
- JSObject *obj;
- JSFile *file;
-
- obj = JS_NewObject(cx, &file_class, NULL, NULL);
- if (!obj){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObject");
- return NULL;
- }
- file = file_init(cx, obj, filename);
- if(!file) return NULL;
- return obj;
-}
-
-/* Internal function, used for cases which NSPR file support doesn't cover */
-JSObject*
-js_NewFileObjectFromFILE(JSContext *cx, FILE *nativehandle, char *filename,
- int32 mode, JSBool open, JSBool randomAccess)
-{
- JSObject *obj;
- JSFile *file;
-#ifdef XP_MAC
- JS_ReportWarning(cx, "Native files are not fully supported on the MAC");
-#endif
-
- obj = JS_NewObject(cx, &file_class, NULL, NULL);
- if (!obj){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObjectFromFILE");
- return NULL;
- }
- file = file_init(cx, obj, filename);
- if(!file) return NULL;
-
- file->nativehandle = nativehandle;
-
- /* free result of RESOLVE_PATH from file_init. */
- JS_ASSERT(file->path != NULL);
- JS_free(cx, file->path);
-
- file->path = strdup(filename);
- file->isOpen = open;
- file->mode = mode;
- file->hasRandomAccess = randomAccess;
- file->isNative = JS_TRUE;
- return obj;
-}
-
-/*
- Real file constructor that is called from JavaScript.
- Basically, does error processing and calls file_init.
-*/
-static JSBool
-file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
- JSFile *file;
-
- str = (argc==0)?JS_InternString(cx, ""):JS_ValueToString(cx, argv[0]);
-
- if (!str){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR, argv[0]);
- goto out;
- }
-
- file = file_init(cx, obj, JS_GetStringBytes(str));
- if (!file) goto out;
-
- SECURITY_CHECK(cx, NULL, "constructor", file);
-
- return JS_TRUE;
-out:
- *rval = JSVAL_VOID;
- return JS_FALSE;
-}
-
-/* -------------------- File methods and properties ------------------------- */
-static JSFunctionSpec file_functions[] = {
- { "open", file_open, 0},
- { "close", file_close, 0},
- { "remove", file_remove, 0},
- { "copyTo", file_copyTo, 0},
- { "renameTo", file_renameTo, 0},
- { "flush", file_flush, 0},
- { "seek", file_seek, 0},
- { "read", file_read, 0},
- { "readln", file_readln, 0},
- { "readAll", file_readAll, 0},
- { "write", file_write, 0},
- { "writeln", file_writeln, 0},
- { "writeAll", file_writeAll, 0},
- { "list", file_list, 0},
- { "mkdir", file_mkdir, 0},
- { "toString", file_toString, 0},
- { "toURL", file_toURL, 0},
- {0}
-};
-
-enum file_tinyid {
- FILE_LENGTH = -2,
- FILE_PARENT = -3,
- FILE_PATH = -4,
- FILE_NAME = -5,
- FILE_ISDIR = -6,
- FILE_ISFILE = -7,
- FILE_EXISTS = -8,
- FILE_CANREAD = -9,
- FILE_CANWRITE = -10,
- FILE_OPEN = -11,
- FILE_TYPE = -12,
- FILE_MODE = -13,
- FILE_CREATED = -14,
- FILE_MODIFIED = -15,
- FILE_SIZE = -16,
- FILE_RANDOMACCESS = -17,
- FILE_POSITION = -18,
- FILE_APPEND = -19,
- FILE_REPLACE = -20,
- FILE_AUTOFLUSH = -21,
- FILE_ISNATIVE = -22,
-};
-
-static JSPropertySpec file_props[] = {
- {"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"canAppend", FILE_APPEND, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"canReplace", FILE_REPLACE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"creationTime", FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"lastModified", FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"hasRandomAccess", FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"hasAutoFlush", FILE_AUTOFLUSH, JSPROP_ENUMERATE | JSPROP_READONLY },
- {"position", FILE_POSITION, JSPROP_ENUMERATE },
- {"isNative", FILE_ISNATIVE, JSPROP_ENUMERATE | JSPROP_READONLY },
- {0}
-};
-
-/* ------------------------- Property getter/setter ------------------------- */
-static JSBool
-file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- char *str;
- jsint tiny;
- PRFileInfo info;
- JSBool flag;
- PRExplodedTime
- expandedTime;
-
- tiny = JSVAL_TO_INT(id);
- if(!file) return JS_TRUE;
-
- switch (tiny) {
- case FILE_PARENT:
- SECURITY_CHECK(cx, NULL, "parent", file);
- *vp = js_parent(cx, file);
- break;
- case FILE_PATH:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
- break;
- case FILE_NAME:
- *vp = js_name(cx, file);
- break;
- case FILE_ISDIR:
- SECURITY_CHECK(cx, NULL, "isDirectory", file);
- *vp = BOOLEAN_TO_JSVAL(js_isDirectory(cx, file));
- break;
- case FILE_ISFILE:
- SECURITY_CHECK(cx, NULL, "isFile", file);
- *vp = BOOLEAN_TO_JSVAL(js_isFile(cx, file));
- break;
- case FILE_EXISTS:
- SECURITY_CHECK(cx, NULL, "exists", file);
- *vp = BOOLEAN_TO_JSVAL(js_exists(cx, file));
- break;
- case FILE_ISNATIVE:
- SECURITY_CHECK(cx, NULL, "isNative", file);
- *vp = BOOLEAN_TO_JSVAL(file->isNative);
- break;
- case FILE_CANREAD:
- SECURITY_CHECK(cx, NULL, "canRead", file);
- *vp = BOOLEAN_TO_JSVAL(js_canRead(cx, file));
- break;
- case FILE_CANWRITE:
- SECURITY_CHECK(cx, NULL, "canWrite", file);
- *vp = BOOLEAN_TO_JSVAL(js_canWrite(cx, file));
- break;
- case FILE_OPEN:
- SECURITY_CHECK(cx, NULL, "isOpen", file);
- *vp = BOOLEAN_TO_JSVAL(file->isOpen);
- break;
- case FILE_APPEND :
- SECURITY_CHECK(cx, NULL, "canAppend", file);
- JSFILE_CHECK_OPEN("canAppend");
- *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
- (file->mode&PR_APPEND)==PR_APPEND);
- break;
- case FILE_REPLACE :
- SECURITY_CHECK(cx, NULL, "canReplace", file);
- JSFILE_CHECK_OPEN("canReplace");
- *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
- (file->mode&PR_TRUNCATE)==PR_TRUNCATE);
- break;
- case FILE_AUTOFLUSH :
- SECURITY_CHECK(cx, NULL, "hasAutoFlush", file);
- JSFILE_CHECK_OPEN("hasAutoFlush");
- *vp = BOOLEAN_TO_JSVAL(!file->isNative && file->hasAutoflush);
- break;
- case FILE_TYPE:
- SECURITY_CHECK(cx, NULL, "type", file);
- JSFILE_CHECK_OPEN("type");
- if(js_isDirectory(cx, file)){
- *vp = JSVAL_VOID;
- break;
- }
-
- switch (file->type) {
- case ASCII:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, asciistring));
- break;
- case UTF8:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, utfstring));
- break;
- case UCS2:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, unicodestring));
- break;
- default:
- JS_ReportWarning(cx, "Unsupported file type %d, proceeding",
- file->type);
- }
- break;
- case FILE_MODE:
- SECURITY_CHECK(cx, NULL, "mode", file);
- JSFILE_CHECK_OPEN("mode");
- str = (char*)JS_malloc(cx, MODE_SIZE);
- str[0] = '\0';
- flag = JS_FALSE;
-
- if ((file->mode&PR_RDONLY)==PR_RDONLY) {
- if (flag) strcat(str, ",");
- strcat(str, "read");
- flag = JS_TRUE;
- }
- if ((file->mode&PR_WRONLY)==PR_WRONLY) {
- if (flag) strcat(str, ",");
- strcat(str, "write");
- flag = JS_TRUE;
- }
- if ((file->mode&PR_RDWR)==PR_RDWR) {
- if (flag) strcat(str, ",");
- strcat(str, "readWrite");
- flag = JS_TRUE;
- }
- if ((file->mode&PR_APPEND)==PR_APPEND) {
- if (flag) strcat(str, ",");
- strcat(str, "append");
- flag = JS_TRUE;
- }
- if ((file->mode&PR_CREATE_FILE)==PR_CREATE_FILE) {
- if (flag) strcat(str, ",");
- strcat(str, "create");
- flag = JS_TRUE;
- }
- if ((file->mode&PR_TRUNCATE)==PR_TRUNCATE) {
- if (flag) strcat(str, ",");
- strcat(str, "replace");
- flag = JS_TRUE;
- }
- if (file->hasAutoflush) {
- if (flag) strcat(str, ",");
- strcat(str, "hasAutoFlush");
- flag = JS_TRUE;
- }
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
- JS_free(cx, str);
- break;
- case FILE_CREATED:
- SECURITY_CHECK(cx, NULL, "creationTime", file);
- JSFILE_CHECK_NATIVE("creationTime");
- if(((file->isOpen)?
- PR_GetOpenFileInfo(file->handle, &info):
- PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
- goto out;
- }
-
- PR_ExplodeTime(info.creationTime, PR_LocalTimeParameters,&expandedTime);
- *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
- expandedTime.tm_month,
- expandedTime.tm_mday,
- expandedTime.tm_hour,
- expandedTime.tm_min,
- expandedTime.tm_sec));
- break;
- case FILE_MODIFIED:
- SECURITY_CHECK(cx, NULL, "lastModified", file);
- JSFILE_CHECK_NATIVE("lastModified");
- if(((file->isOpen)?
- PR_GetOpenFileInfo(file->handle, &info):
- PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
- goto out;
- }
-
- PR_ExplodeTime(info.modifyTime, PR_LocalTimeParameters, &expandedTime);
- *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
- expandedTime.tm_month,
- expandedTime.tm_mday,
- expandedTime.tm_hour,
- expandedTime.tm_min,
- expandedTime.tm_sec));
- break;
- case FILE_SIZE:
- SECURITY_CHECK(cx, NULL, "size", file);
- *vp = js_size(cx, file);
- break;
- case FILE_LENGTH:
- SECURITY_CHECK(cx, NULL, "length", file);
- JSFILE_CHECK_NATIVE("length");
-
- if (js_isDirectory(cx, file)) { /* XXX debug me */
- PRDir *dir;
- PRDirEntry *entry;
- jsint count = 0;
-
- if(!(dir = PR_OpenDir(file->path))){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_OPEN_DIR, file->path);
- goto out;
- }
-
- while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
- count++;
- }
-
- if(!PR_CloseDir(dir)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_OP_FAILED, "close", file->path);
-
- goto out;
- }
-
- *vp = INT_TO_JSVAL(count);
- break;
- }else{
- /* return file size */
- *vp = js_size(cx, file);
- }
- break;
- case FILE_RANDOMACCESS:
- SECURITY_CHECK(cx, NULL, "hasRandomAccess", file);
- JSFILE_CHECK_OPEN("hasRandomAccess");
- *vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess);
- break;
- case FILE_POSITION:
- SECURITY_CHECK(cx, NULL, "position", file);
- JSFILE_CHECK_NATIVE("position");
- JSFILE_CHECK_OPEN("position");
-
- if(!file->hasRandomAccess){
- JS_ReportWarning(cx, "File %s doesn't support random access, can't report the position, proceeding");
- *vp = JSVAL_VOID;
- break;
- }
-
- if (file->isOpen && js_isFile(cx, file)) {
- int pos = PR_Seek(file->handle, 0, PR_SEEK_CUR);
- if(pos!=-1){
- *vp = INT_TO_JSVAL(pos);
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_REPORT_POSITION, file->path);
- goto out;
- }
- }else {
- JS_ReportWarning(cx, "File %s is closed or not a plain file,"
- " can't report position, proceeding");
- goto out;
- }
- break;
- default:
- SECURITY_CHECK(cx, NULL, "file_access", file);
- /* this is some other property -- try to use the dir["file"] syntax */
- if(js_isDirectory(cx, file)){
- PRDir *dir = NULL;
- PRDirEntry *entry = NULL;
- char *prop_name = JS_GetStringBytes(JS_ValueToString(cx, id));
-
- /* no native files past this point */
- dir = PR_OpenDir(file->path);
- if(!dir) {
- /* This is probably not a directory */
- JS_ReportWarning(cx, "Can't open directory %s", file->path);
- return JS_FALSE;
- }
-
- while((entry = PR_ReadDir(dir, PR_SKIP_NONE))!=NULL){
- if(!strcmp(entry->name, prop_name)){
- str = js_combinePath(cx, file->path, prop_name);
- *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
- JS_free(cx, str);
- return JS_TRUE;
- }
- }
- }
- }
- return JS_TRUE;
-out:
- *vp = JSVAL_VOID;
- return JS_FALSE;
-}
-
-static JSBool
-file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
- jsint slot;
-
- if (JSVAL_IS_STRING(id)){
- return JS_TRUE;
- }
-
- slot = JSVAL_TO_INT(id);
-
- switch (slot) {
- /* File.position = 10 */
- case FILE_POSITION:
- SECURITY_CHECK(cx, NULL, "set_position", file);
- JSFILE_CHECK_NATIVE("set_position");
-
- if(!file->hasRandomAccess){
- JS_ReportWarning(cx, "File %s doesn't support random access, can't "
- "report the position, proceeding");
- goto out;
- }
-
- if (file->isOpen && js_isFile(cx, file)) {
- int32 pos;
- int32 offset;
-
- if (!JS_ValueToInt32(cx, *vp, &offset)){
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "position", *vp);
- goto out;
- }
-
- pos = PR_Seek(file->handle, offset, PR_SEEK_SET);
-
- if(pos!=-1){
- *vp = INT_TO_JSVAL(pos);
- }else{
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_CANNOT_SET_POSITION, file->path);
- goto out;
- }
- } else {
- JS_ReportWarning(cx, "File %s is closed or not a file, can't set "
- "position, proceeding", file->path);
- goto out;
- }
- }
-
- return JS_TRUE;
-out:
- *vp = JSVAL_VOID;
- return JS_FALSE;
-}
-
-/*
- File.currentDir = new File("D:\") or File.currentDir = "D:\"
-*/
-static JSBool
-file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSObject *rhsObject;
- char *path;
- JSFile *file = JS_GetInstancePrivate(cx, rhsObject, &file_class, NULL);
-
- /* Look at the rhs and extract a file object from it */
- if (JSVAL_IS_OBJECT(*vp)){
- if (JS_InstanceOf(cx, rhsObject, &file_class, NULL)){
- /* Braindamaged rhs -- just return the old value */
- if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))){
- JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
- goto out;
- }else{
- rhsObject = JSVAL_TO_OBJECT(*vp);
- chdir(file->path);
- return JS_TRUE;
- }
- }else
- goto out;
- }else{
- path = JS_GetStringBytes(JS_ValueToString(cx, *vp));
- rhsObject = js_NewFileObject(cx, path);
- if (!rhsObject) goto out;
-
- if (!file || !js_exists(cx, file) || !js_isDirectory(cx, file)){
- JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
- }else{
- *vp = OBJECT_TO_JSVAL(rhsObject);
- chdir(path);
- }
- }
- return JS_TRUE;
-out:
- *vp = JSVAL_VOID;
- return JS_FALSE;
-}
-
-/* Declare class */
-static JSClass file_class = {
- FILE_CONSTRUCTOR, JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, file_getProperty, file_setProperty,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, file_finalize
-};
-
-/* -------------------- Functions exposed to the outside -------------------- */
-JS_PUBLIC_API(JSObject*)
-js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams)
-{
- JSObject *file, *ctor, *afile;
- jsval vp;
- char *currentdir;
- char separator[2];
-
- file = JS_InitClass(cx, obj, NULL, &file_class, file_constructor, 1,
- file_props, file_functions, NULL, NULL);
- if (!file) {
- JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
- JSFILEMSG_INIT_FAILED);
- return NULL;
- }
-
- ctor = JS_GetConstructor(cx, file);
- if (!ctor) return NULL;
-
- /* Define CURRENTDIR property. We are doing this to get a
- slash at the end of the current dir */
- afile = js_NewFileObject(cx, CURRENT_DIR);
- currentdir = JS_malloc(cx, MAX_PATH_LENGTH);
- currentdir = getcwd(currentdir, MAX_PATH_LENGTH);
- afile = js_NewFileObject(cx, currentdir);
- JS_free(cx, currentdir);
- vp = OBJECT_TO_JSVAL(afile);
- JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp,
- JS_PropertyStub, file_currentDirSetter,
- JSPROP_ENUMERATE | JSPROP_READONLY );
-
- if(initStandardStreams){
- /* Code to create stdin, stdout, and stderr. Insert in the appropriate place. */
- /* Define input */
- vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
- STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
- JS_SetProperty(cx, ctor, "input", &vp);
-
- /* Define output */
- vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
- STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
- JS_SetProperty(cx, ctor, "output", &vp);
-
- /* Define error */
- vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
- STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
- JS_SetProperty(cx, ctor, "error", &vp);
- }
- separator[0] = FILESEPARATOR;
- separator[1] = '\0';
- vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, separator));
- JS_DefinePropertyWithTinyId(cx, ctor, SEPARATOR_PROPERTY, 0, vp,
- JS_PropertyStub, JS_PropertyStub,
- JSPROP_ENUMERATE | JSPROP_READONLY );
- return file;
-}
-#endif /* JS_HAS_FILE_OBJECT */
diff --git a/src/extension/script/js/jsfile.h b/src/extension/script/js/jsfile.h
deleted file mode 100644
index 47a8692d8..000000000
--- a/src/extension/script/js/jsfile.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef _jsfile_h__
-#define _jsfile_h__
-
-#if JS_HAS_FILE_OBJECT
-extern JS_PUBLIC_API(JSObject*)
-js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams);
-
-extern JS_PUBLIC_API(JSObject*)
-js_NewFileObject(JSContext *cx, char *bytes);
-#endif /* JS_HAS_FILE_OBJECT */
-#endif /* _jsfile_h__ */
diff --git a/src/extension/script/js/jsfun.c b/src/extension/script/js/jsfun.c
deleted file mode 100644
index 93cd4009d..000000000
--- a/src/extension/script/js/jsfun.c
+++ /dev/null
@@ -1,2059 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS function support.
- */
-#include "jsstddef.h"
-#include <string.h>
-#include "jstypes.h"
-#include "jsbit.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsparse.h"
-#include "jsscan.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-#include "jsexn.h"
-
-/* Generic function/call/arguments tinyids -- also reflected bit numbers. */
-enum {
- CALL_ARGUMENTS = -1, /* predefined arguments local variable */
- CALL_CALLEE = -2, /* reference to active function's object */
- ARGS_LENGTH = -3, /* number of actual args, arity if inactive */
- ARGS_CALLEE = -4, /* reference from arguments to active funobj */
- FUN_ARITY = -5, /* number of formal parameters; desired argc */
- FUN_NAME = -6, /* function name, "" if anonymous */
- FUN_CALLER = -7 /* Function.prototype.caller, backward compat */
-};
-
-#if JSFRAME_OVERRIDE_BITS < 8
-# error "not enough override bits in JSStackFrame.flags!"
-#endif
-
-#define TEST_OVERRIDE_BIT(fp, tinyid) \
- ((fp)->flags & JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
-
-#define SET_OVERRIDE_BIT(fp, tinyid) \
- ((fp)->flags |= JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
-
-#if JS_HAS_ARGS_OBJECT
-
-JSBool
-js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp)
-{
- JSObject *argsobj;
-
- if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
- JS_ASSERT(fp->callobj);
- return OBJ_GET_PROPERTY(cx, fp->callobj,
- (jsid) cx->runtime->atomState.argumentsAtom,
- vp);
- }
- argsobj = js_GetArgsObject(cx, fp);
- if (!argsobj)
- return JS_FALSE;
- *vp = OBJECT_TO_JSVAL(argsobj);
- return JS_TRUE;
-}
-
-static JSBool
-MarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
-{
- JSObject *argsobj;
- jsval bmapval, bmapint;
- size_t nbits, nbytes;
- jsbitmap *bitmap;
-
- argsobj = fp->argsobj;
- (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
- nbits = JS_MAX(fp->argc, fp->fun->nargs);
- JS_ASSERT(slot < nbits);
- if (JSVAL_IS_VOID(bmapval)) {
- if (nbits <= JSVAL_INT_BITS) {
- bmapint = 0;
- bitmap = (jsbitmap *) &bmapint;
- } else {
- nbytes = JS_HOWMANY(nbits, JS_BITS_PER_WORD) * sizeof(jsbitmap);
- bitmap = (jsbitmap *) JS_malloc(cx, nbytes);
- if (!bitmap)
- return JS_FALSE;
- memset(bitmap, 0, nbytes);
- bmapval = PRIVATE_TO_JSVAL(bitmap);
- JS_SetReservedSlot(cx, argsobj, 0, bmapval);
- }
- } else {
- if (nbits <= JSVAL_INT_BITS) {
- bmapint = JSVAL_TO_INT(bmapval);
- bitmap = (jsbitmap *) &bmapint;
- } else {
- bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
- }
- }
- JS_SET_BIT(bitmap, slot);
- if (bitmap == (jsbitmap *) &bmapint) {
- bmapval = INT_TO_JSVAL(bmapint);
- JS_SetReservedSlot(cx, argsobj, 0, bmapval);
- }
- return JS_TRUE;
-}
-
-/* NB: Infallible predicate, false does not mean error/exception. */
-static JSBool
-ArgWasDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
-{
- JSObject *argsobj;
- jsval bmapval, bmapint;
- jsbitmap *bitmap;
-
- argsobj = fp->argsobj;
- (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
- if (JSVAL_IS_VOID(bmapval))
- return JS_FALSE;
- if (JS_MAX(fp->argc, fp->fun->nargs) <= JSVAL_INT_BITS) {
- bmapint = JSVAL_TO_INT(bmapval);
- bitmap = (jsbitmap *) &bmapint;
- } else {
- bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
- }
- return JS_TEST_BIT(bitmap, slot) != 0;
-}
-
-JSBool
-js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
- JSObject **objp, jsval *vp)
-{
- jsval val;
- JSObject *obj;
- uintN slot;
-
- if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
- JS_ASSERT(fp->callobj);
- if (!OBJ_GET_PROPERTY(cx, fp->callobj,
- (jsid) cx->runtime->atomState.argumentsAtom,
- &val)) {
- return JS_FALSE;
- }
- if (JSVAL_IS_PRIMITIVE(val)) {
- obj = js_ValueToNonNullObject(cx, val);
- if (!obj)
- return JS_FALSE;
- } else {
- obj = JSVAL_TO_OBJECT(val);
- }
- *objp = obj;
- return OBJ_GET_PROPERTY(cx, obj, id, vp);
- }
-
- *objp = NULL;
- *vp = JSVAL_VOID;
- if (JSVAL_IS_INT(id)) {
- slot = (uintN) JSVAL_TO_INT(id);
- if (slot < JS_MAX(fp->argc, fp->fun->nargs)) {
- if (fp->argsobj && ArgWasDeleted(cx, fp, slot))
- return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
- *vp = fp->argv[slot];
- }
- } else {
- if (id == (jsid) cx->runtime->atomState.lengthAtom) {
- if (fp->argsobj && TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))
- return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
- *vp = INT_TO_JSVAL((jsint) fp->argc);
- }
- }
- return JS_TRUE;
-}
-
-JSObject *
-js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
-{
- JSObject *argsobj;
-
- /* Create an arguments object for fp only if it lacks one. */
- JS_ASSERT(fp->fun);
- argsobj = fp->argsobj;
- if (argsobj)
- return argsobj;
-
- /* Link the new object to fp so it can get actual argument values. */
- argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);
- if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- fp->argsobj = argsobj;
- return argsobj;
-}
-
-static JSBool
-args_enumerate(JSContext *cx, JSObject *obj);
-
-JSBool
-js_PutArgsObject(JSContext *cx, JSStackFrame *fp)
-{
- JSObject *argsobj;
- jsval bmapval, rval;
- JSBool ok;
- JSRuntime *rt;
-
- /*
- * Reuse args_enumerate here to reflect fp's actual arguments as indexed
- * elements of argsobj. Do this first, before clearing and freeing the
- * deleted argument slot bitmap, because args_enumerate depends on that.
- */
- argsobj = fp->argsobj;
- ok = args_enumerate(cx, argsobj);
-
- /*
- * Now clear the deleted argument number bitmap slot and free the bitmap,
- * if one was actually created due to 'delete arguments[0]' or similar.
- */
- (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
- if (!JSVAL_IS_VOID(bmapval)) {
- JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID);
- if (JS_MAX(fp->argc, fp->fun->nargs) > JSVAL_INT_BITS)
- JS_free(cx, JSVAL_TO_PRIVATE(bmapval));
- }
-
- /*
- * Now get the prototype properties so we snapshot fp->fun and fp->argc
- * before fp goes away.
- */
- rt = cx->runtime;
- ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval);
- ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval);
- ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval);
- ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval);
-
- /*
- * Clear the private pointer to fp, which is about to go away (js_Invoke).
- * Do this last because the args_enumerate and js_GetProperty calls above
- * need to follow the private slot to find fp.
- */
- ok &= JS_SetPrivate(cx, argsobj, NULL);
- fp->argsobj = NULL;
- return ok;
-}
-
-static JSBool
-args_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsint slot;
- JSStackFrame *fp;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- fp = (JSStackFrame *)
- JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->argsobj);
- JS_ASSERT(fp->fun);
-
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case ARGS_CALLEE:
- case ARGS_LENGTH:
- SET_OVERRIDE_BIT(fp, slot);
- break;
-
- default:
- if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
- !MarkArgDeleted(cx, fp, slot)) {
- return JS_FALSE;
- }
- break;
- }
- return JS_TRUE;
-}
-
-static JSBool
-args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsint slot;
- JSStackFrame *fp;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- fp = (JSStackFrame *)
- JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->argsobj);
- JS_ASSERT(fp->fun);
-
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case ARGS_CALLEE:
- if (!TEST_OVERRIDE_BIT(fp, slot))
- *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
- break;
-
- case ARGS_LENGTH:
- if (!TEST_OVERRIDE_BIT(fp, slot))
- *vp = INT_TO_JSVAL((jsint)fp->argc);
- break;
-
- default:
- if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
- !ArgWasDeleted(cx, fp, slot)) {
- *vp = fp->argv[slot];
- }
- break;
- }
- return JS_TRUE;
-}
-
-static JSBool
-args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSStackFrame *fp;
- jsint slot;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- fp = (JSStackFrame *)
- JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->argsobj);
- JS_ASSERT(fp->fun);
-
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case ARGS_CALLEE:
- case ARGS_LENGTH:
- SET_OVERRIDE_BIT(fp, slot);
- break;
-
- default:
- if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
- !ArgWasDeleted(cx, fp, slot)) {
- fp->argv[slot] = *vp;
- }
- break;
- }
- return JS_TRUE;
-}
-
-static JSBool
-args_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
- JSObject **objp)
-{
- JSStackFrame *fp;
- uintN slot;
- JSString *str;
- JSAtom *atom;
- intN tinyid;
- jsval value;
-
- *objp = NULL;
- fp = (JSStackFrame *)
- JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->argsobj);
- JS_ASSERT(fp->fun);
-
- if (JSVAL_IS_INT(id)) {
- slot = JSVAL_TO_INT(id);
- if (slot < JS_MAX(fp->argc, fp->fun->nargs) &&
- !ArgWasDeleted(cx, fp, slot)) {
- /* XXX ECMA specs DontEnum, contrary to other array-like objects */
- if (!js_DefineProperty(cx, obj, (jsid) id, fp->argv[slot],
- args_getProperty, args_setProperty,
- JSVERSION_IS_ECMA(cx->version)
- ? 0
- : JSPROP_ENUMERATE,
- NULL)) {
- return JS_FALSE;
- }
- *objp = obj;
- }
- } else {
- str = JSVAL_TO_STRING(id);
- atom = cx->runtime->atomState.lengthAtom;
- if (str == ATOM_TO_STRING(atom)) {
- tinyid = ARGS_LENGTH;
- value = INT_TO_JSVAL(fp->argc);
- } else {
- atom = cx->runtime->atomState.calleeAtom;
- if (str == ATOM_TO_STRING(atom)) {
- tinyid = ARGS_CALLEE;
- value = fp->argv ? fp->argv[-2]
- : OBJECT_TO_JSVAL(fp->fun->object);
- } else {
- atom = NULL;
-
- /* Quell GCC overwarnings. */
- tinyid = 0;
- value = JSVAL_NULL;
- }
- }
-
- if (atom && !TEST_OVERRIDE_BIT(fp, tinyid)) {
- if (!js_DefineNativeProperty(cx, obj, (jsid) atom, value,
- args_getProperty, args_setProperty, 0,
- SPROP_HAS_SHORTID, tinyid, NULL)) {
- return JS_FALSE;
- }
- *objp = obj;
- }
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-args_enumerate(JSContext *cx, JSObject *obj)
-{
- JSStackFrame *fp;
- JSObject *pobj;
- JSProperty *prop;
- uintN slot, nargs;
-
- fp = (JSStackFrame *)
- JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->argsobj);
- JS_ASSERT(fp->fun);
-
- /*
- * Trigger reflection with value snapshot in args_resolve using a series
- * of js_LookupProperty calls. We handle length, callee, and the indexed
- * argument properties. We know that args_resolve covers all these cases
- * and creates direct properties of obj, but that it may fail to resolve
- * length or callee if overridden.
- */
- if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.lengthAtom,
- &pobj, &prop)) {
- return JS_FALSE;
- }
- if (prop)
- OBJ_DROP_PROPERTY(cx, pobj, prop);
-
- if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.calleeAtom,
- &pobj, &prop)) {
- return JS_FALSE;
- }
- if (prop)
- OBJ_DROP_PROPERTY(cx, pobj, prop);
-
- nargs = JS_MAX(fp->argc, fp->fun->nargs);
- for (slot = 0; slot < nargs; slot++) {
- if (!js_LookupProperty(cx, obj, (jsid) INT_TO_JSVAL((jsint)slot),
- &pobj, &prop)) {
- return JS_FALSE;
- }
- if (prop)
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- }
- return JS_TRUE;
-}
-
-/*
- * The Arguments class is not initialized via JS_InitClass, and must not be,
- * because its name is "Object". Per ECMA, that causes instances of it to
- * delegate to the object named by Object.prototype. It also ensures that
- * arguments.toString() returns "[object Object]".
- *
- * The JSClass functions below collaborate to lazily reflect and synchronize
- * actual argument values, argument count, and callee function object stored
- * in a JSStackFrame with their corresponding property values in the frame's
- * arguments object.
- */
-JSClass js_ArgumentsClass = {
- js_Object_str,
- JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1),
- JS_PropertyStub, args_delProperty,
- args_getProperty, args_setProperty,
- args_enumerate, (JSResolveOp) args_resolve,
- JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-#endif /* JS_HAS_ARGS_OBJECT */
-
-#if JS_HAS_CALL_OBJECT
-
-JSObject *
-js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
-{
- JSObject *callobj, *funobj;
-
- /* Create a call object for fp only if it lacks one. */
- JS_ASSERT(fp->fun);
- callobj = fp->callobj;
- if (callobj)
- return callobj;
- JS_ASSERT(fp->fun);
-
- /* The default call parent is its function's parent (static link). */
- if (!parent) {
- funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
- if (funobj)
- parent = OBJ_GET_PARENT(cx, funobj);
- }
-
- /* Create the call object and link it to its stack frame. */
- callobj = js_NewObject(cx, &js_CallClass, NULL, parent);
- if (!callobj || !JS_SetPrivate(cx, callobj, fp)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- fp->callobj = callobj;
-
- /* Make callobj be the scope chain and the variables object. */
- fp->scopeChain = callobj;
- fp->varobj = callobj;
- return callobj;
-}
-
-static JSBool
-call_enumerate(JSContext *cx, JSObject *obj);
-
-JSBool
-js_PutCallObject(JSContext *cx, JSStackFrame *fp)
-{
- JSObject *callobj;
- JSBool ok;
- jsid argsid;
- jsval aval;
-
- /*
- * Reuse call_enumerate here to reflect all actual args and vars into the
- * call object from fp.
- */
- callobj = fp->callobj;
- if (!callobj)
- return JS_TRUE;
- ok = call_enumerate(cx, callobj);
-
- /*
- * Get the arguments object to snapshot fp's actual argument values.
- */
- if (fp->argsobj) {
- argsid = (jsid) cx->runtime->atomState.argumentsAtom;
- ok &= js_GetProperty(cx, callobj, argsid, &aval);
- ok &= js_SetProperty(cx, callobj, argsid, &aval);
- ok &= js_PutArgsObject(cx, fp);
- }
-
- /*
- * Clear the private pointer to fp, which is about to go away (js_Invoke).
- * Do this last because the call_enumerate and js_GetProperty calls above
- * need to follow the private slot to find fp.
- */
- ok &= JS_SetPrivate(cx, callobj, NULL);
- fp->callobj = NULL;
- return ok;
-}
-
-static JSPropertySpec call_props[] = {
- {js_arguments_str, CALL_ARGUMENTS, JSPROP_PERMANENT,0,0},
- {"__callee__", CALL_CALLEE, 0,0,0},
- {0,0,0,0,0}
-};
-
-static JSBool
-call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSStackFrame *fp;
- jsint slot;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->fun);
-
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case CALL_ARGUMENTS:
- if (!TEST_OVERRIDE_BIT(fp, slot)) {
- JSObject *argsobj = js_GetArgsObject(cx, fp);
- if (!argsobj)
- return JS_FALSE;
- *vp = OBJECT_TO_JSVAL(argsobj);
- }
- break;
-
- case CALL_CALLEE:
- if (!TEST_OVERRIDE_BIT(fp, slot))
- *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
- break;
-
- default:
- if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs))
- *vp = fp->argv[slot];
- break;
- }
- return JS_TRUE;
-}
-
-static JSBool
-call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSStackFrame *fp;
- jsint slot;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->fun);
-
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case CALL_ARGUMENTS:
- case CALL_CALLEE:
- SET_OVERRIDE_BIT(fp, slot);
- break;
-
- default:
- if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs))
- fp->argv[slot] = *vp;
- break;
- }
- return JS_TRUE;
-}
-
-JSBool
-js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSStackFrame *fp;
-
- JS_ASSERT(JSVAL_IS_INT(id));
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (fp) {
- /* XXX no jsint slot commoning here to avoid MSVC1.52 crashes */
- if ((uintN)JSVAL_TO_INT(id) < fp->nvars)
- *vp = fp->vars[JSVAL_TO_INT(id)];
- }
- return JS_TRUE;
-}
-
-JSBool
-js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSStackFrame *fp;
-
- JS_ASSERT(JSVAL_IS_INT(id));
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (fp) {
- /* XXX jsint slot is block-local here to avoid MSVC1.52 crashes */
- jsint slot = JSVAL_TO_INT(id);
- if ((uintN)slot < fp->nvars)
- fp->vars[slot] = *vp;
- }
- return JS_TRUE;
-}
-
-static JSBool
-call_enumerate(JSContext *cx, JSObject *obj)
-{
- JSStackFrame *fp;
- JSObject *funobj;
- JSScope *scope;
- JSScopeProperty *sprop, *cprop;
- JSPropertyOp getter;
- jsval *vec;
- JSProperty *prop;
-
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (!fp)
- return JS_TRUE;
-
- /*
- * Do not enumerate a cloned function object at fp->argv[-2], it may have
- * gained its own (mutable) scope (e.g., a brutally-shared XUL script sets
- * the clone's prototype property). We must enumerate the function object
- * that was decorated with parameter and local variable properties by the
- * compiler when the compiler created fp->fun, namely fp->fun->object.
- *
- * Contrast with call_resolve, where we prefer fp->argv[-2], because we'll
- * use js_LookupProperty to find any overridden properties in that object,
- * if it was a mutated clone; and if not, we will search its prototype,
- * fp->fun->object, to find compiler-created params and locals.
- */
- funobj = fp->fun->object;
- if (!funobj)
- return JS_TRUE;
-
- /*
- * Reflect actual args from fp->argv for formal parameters, and local vars
- * and functions in fp->vars for declared variables and nested-at-top-level
- * local functions.
- */
- scope = OBJ_SCOPE(funobj);
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- getter = sprop->getter;
- if (getter == js_GetArgument)
- vec = fp->argv;
- else if (getter == js_GetLocalVariable)
- vec = fp->vars;
- else
- continue;
-
- /* Trigger reflection in call_resolve by doing a lookup. */
- if (!js_LookupProperty(cx, obj, sprop->id, &obj, &prop))
- return JS_FALSE;
- JS_ASSERT(obj && prop);
- cprop = (JSScopeProperty *)prop;
- LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[sprop->shortid]);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
- JSObject **objp)
-{
- JSStackFrame *fp;
- JSObject *funobj;
- JSString *str;
- JSAtom *atom;
- JSObject *obj2;
- JSScopeProperty *sprop;
- jsid propid;
- JSPropertyOp getter, setter;
- uintN attrs, slot, nslots, spflags;
- jsval *vp, value;
- intN shortid;
-
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (!fp)
- return JS_TRUE;
- JS_ASSERT(fp->fun);
-
- if (!JSVAL_IS_STRING(id))
- return JS_TRUE;
-
- funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
- if (!funobj)
- return JS_TRUE;
-
- str = JSVAL_TO_STRING(id);
- atom = js_AtomizeString(cx, str, 0);
- if (!atom)
- return JS_FALSE;
- if (!js_LookupProperty(cx, funobj, (jsid)atom, &obj2,
- (JSProperty **)&sprop)) {
- return JS_FALSE;
- }
-
- if (sprop && OBJ_IS_NATIVE(obj2)) {
- propid = sprop->id;
- getter = sprop->getter;
- attrs = sprop->attrs & ~JSPROP_SHARED;
- slot = (uintN) sprop->shortid;
- OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
- if (getter == js_GetArgument || getter == js_GetLocalVariable) {
- if (getter == js_GetArgument) {
- vp = fp->argv;
- nslots = JS_MAX(fp->argc, fp->fun->nargs);
- getter = setter = NULL;
- } else {
- vp = fp->vars;
- nslots = fp->nvars;
- getter = js_GetCallVariable;
- setter = js_SetCallVariable;
- }
- if (slot < nslots) {
- value = vp[slot];
- spflags = SPROP_HAS_SHORTID;
- shortid = (intN) slot;
- } else {
- value = JSVAL_VOID;
- spflags = 0;
- shortid = 0;
- }
- if (!js_DefineNativeProperty(cx, obj, propid, value,
- getter, setter, attrs,
- spflags, shortid, NULL)) {
- return JS_FALSE;
- }
- *objp = obj;
- }
- }
- return JS_TRUE;
-}
-
-static JSBool
-call_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
-{
- JSStackFrame *fp;
-
- if (type == JSTYPE_FUNCTION) {
- fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
- if (fp) {
- JS_ASSERT(fp->fun);
- *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
- }
- }
- return JS_TRUE;
-}
-
-JSClass js_CallClass = {
- js_Call_str,
- JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
- JS_PropertyStub, JS_PropertyStub,
- call_getProperty, call_setProperty,
- call_enumerate, (JSResolveOp)call_resolve,
- call_convert, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-#endif /* JS_HAS_CALL_OBJECT */
-
-/* SHARED because fun_getProperty always computes a new value. */
-#define FUNCTION_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
-
-static JSPropertySpec function_props[] = {
- {js_arguments_str, CALL_ARGUMENTS, FUNCTION_PROP_ATTRS,0,0},
- {js_arity_str, FUN_ARITY, FUNCTION_PROP_ATTRS,0,0},
- {js_length_str, ARGS_LENGTH, FUNCTION_PROP_ATTRS,0,0},
- {js_name_str, FUN_NAME, FUNCTION_PROP_ATTRS,0,0},
- {js_caller_str, FUN_CALLER, FUNCTION_PROP_ATTRS,0,0},
- {0,0,0,0,0}
-};
-
-static JSBool
-fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsint slot;
- JSFunction *fun;
- JSStackFrame *fp;
-#if defined _MSC_VER &&_MSC_VER <= 800
- /* MSVC1.5 coredumps */
- jsval bogus = *vp;
-#endif
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- slot = JSVAL_TO_INT(id);
-
- /* No valid function object should lack private data, but check anyway. */
- fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
- if (!fun)
- return JS_TRUE;
-
- /* Find fun's top-most activation record. */
- for (fp = cx->fp; fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL));
- fp = fp->down) {
- continue;
- }
-
- switch (slot) {
- case CALL_ARGUMENTS:
-#if JS_HAS_ARGS_OBJECT
- /* Warn if strict about f.arguments or equivalent unqualified uses. */
- if (!JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_DEPRECATED_USAGE,
- js_arguments_str)) {
- return JS_FALSE;
- }
- if (fp) {
- if (!js_GetArgsValue(cx, fp, vp))
- return JS_FALSE;
- } else {
- *vp = JSVAL_NULL;
- }
- break;
-#else /* !JS_HAS_ARGS_OBJECT */
- *vp = OBJECT_TO_JSVAL(fp ? obj : NULL);
- break;
-#endif /* !JS_HAS_ARGS_OBJECT */
-
- case ARGS_LENGTH:
- if (!JSVERSION_IS_ECMA(cx->version))
- *vp = INT_TO_JSVAL((jsint)(fp && fp->fun ? fp->argc : fun->nargs));
- else
- case FUN_ARITY:
- *vp = INT_TO_JSVAL((jsint)fun->nargs);
- break;
-
- case FUN_NAME:
- *vp = fun->atom
- ? ATOM_KEY(fun->atom)
- : STRING_TO_JSVAL(cx->runtime->emptyString);
- break;
-
- case FUN_CALLER:
- while (fp && (fp->flags & JSFRAME_SKIP_CALLER) && fp->down)
- fp = fp->down;
- if (fp && fp->down && fp->down->fun && fp->down->argv)
- *vp = fp->down->argv[-2];
- else
- *vp = JSVAL_NULL;
- if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) {
- id = ATOM_KEY(cx->runtime->atomState.callerAtom);
- if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
- return JS_FALSE;
- }
- break;
-
- default:
- /* XXX fun[0] and fun.arguments[0] are equivalent. */
- if (fp && fp->fun && (uintN)slot < fp->fun->nargs)
-#if defined _MSC_VER &&_MSC_VER <= 800
- /* MSVC1.5 coredumps */
- if (bogus == *vp)
-#endif
- *vp = fp->argv[slot];
- break;
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
- JSObject **objp)
-{
- JSFunction *fun;
- JSString *str;
- JSAtom *prototypeAtom;
-
- if (!JSVAL_IS_STRING(id))
- return JS_TRUE;
-
- /* No valid function object should lack private data, but check anyway. */
- fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
- if (!fun || !fun->object)
- return JS_TRUE;
-
- /* No need to reflect fun.prototype in 'fun.prototype = ...'. */
- if (flags & JSRESOLVE_ASSIGNING)
- return JS_TRUE;
-
- /*
- * Ok, check whether id is 'prototype' and bootstrap the function object's
- * prototype property.
- */
- str = JSVAL_TO_STRING(id);
- prototypeAtom = cx->runtime->atomState.classPrototypeAtom;
- if (str == ATOM_TO_STRING(prototypeAtom)) {
- JSObject *proto, *parentProto;
- jsval pval;
-
- proto = parentProto = NULL;
- if (fun->object != obj && fun->object) {
- /*
- * Clone of a function: make its prototype property value have the
- * same class as the clone-parent's prototype.
- */
- if (!OBJ_GET_PROPERTY(cx, fun->object, (jsid)prototypeAtom, &pval))
- return JS_FALSE;
- if (JSVAL_IS_OBJECT(pval))
- parentProto = JSVAL_TO_OBJECT(pval);
- }
-
- /*
- * Beware of the wacky case of a user function named Object -- trying
- * to find a prototype for that will recur back here ad perniciem.
- */
- if (!parentProto && fun->atom == cx->runtime->atomState.ObjectAtom)
- return JS_TRUE;
-
- /*
- * If resolving "prototype" in a clone, clone the parent's prototype.
- * Pass the constructor's (obj's) parent as the prototype parent, to
- * avoid defaulting to parentProto.constructor.__parent__.
- */
- proto = js_NewObject(cx, &js_ObjectClass, parentProto,
- OBJ_GET_PARENT(cx, obj));
- if (!proto)
- return JS_FALSE;
-
- /*
- * ECMA says that constructor.prototype is DontEnum | DontDelete for
- * user-defined functions, but DontEnum | ReadOnly | DontDelete for
- * native "system" constructors such as Object or Function. So lazily
- * set the former here in fun_resolve, but eagerly define the latter
- * in JS_InitClass, with the right attributes.
- */
- if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return JS_FALSE;
- }
- *objp = obj;
- }
-
- return JS_TRUE;
-}
-
-static JSBool
-fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
-{
- switch (type) {
- case JSTYPE_FUNCTION:
- *vp = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
- default:
- return js_TryValueOf(cx, obj, type, vp);
- }
-}
-
-static void
-fun_finalize(JSContext *cx, JSObject *obj)
-{
- JSFunction *fun;
-
- /* No valid function object should lack private data, but check anyway. */
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- if (!fun)
- return;
- if (fun->object == obj)
- fun->object = NULL;
- JS_ATOMIC_DECREMENT(&fun->nrefs);
- if (fun->nrefs)
- return;
- if (fun->script)
- js_DestroyScript(cx, fun->script);
- JS_free(cx, fun);
-}
-
-#if JS_HAS_XDR
-
-#include "jsxdrapi.h"
-
-enum {
- JSXDR_FUNARG = 1,
- JSXDR_FUNVAR = 2,
- JSXDR_FUNCONST = 3
-};
-
-/* XXX store parent and proto, if defined */
-static JSBool
-fun_xdrObject(JSXDRState *xdr, JSObject **objp)
-{
- JSContext *cx;
- JSFunction *fun;
- JSString *atomstr;
- char *propname;
- JSScopeProperty *sprop;
- uint32 userid; /* NB: holds a signed int-tagged jsval */
- JSAtom *atom;
- uintN i, n, dupflag;
- uint32 type;
-#ifdef DEBUG
- uintN nvars = 0, nargs = 0;
-#endif
-
- cx = xdr->cx;
- if (xdr->mode == JSXDR_ENCODE) {
- /*
- * No valid function object should lack private data, but fail soft
- * (return true, no error report) in case one does due to API pilot
- * or internal error.
- */
- fun = (JSFunction *) JS_GetPrivate(cx, *objp);
- if (!fun)
- return JS_TRUE;
- atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
- } else {
- fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL);
- if (!fun)
- return JS_FALSE;
- atomstr = NULL;
- }
-
- if (!JS_XDRStringOrNull(xdr, &atomstr) ||
- !JS_XDRUint16(xdr, &fun->nargs) ||
- !JS_XDRUint16(xdr, &fun->extra) ||
- !JS_XDRUint16(xdr, &fun->nvars) ||
- !JS_XDRUint8(xdr, &fun->flags)) {
- return JS_FALSE;
- }
-
- /* do arguments and local vars */
- if (fun->object) {
- n = fun->nargs + fun->nvars;
- if (xdr->mode == JSXDR_ENCODE) {
- JSScope *scope;
- JSScopeProperty **spvec, *auto_spvec[8];
- void *mark;
-
- if (n <= sizeof auto_spvec / sizeof auto_spvec[0]) {
- spvec = auto_spvec;
- mark = NULL;
- } else {
- mark = JS_ARENA_MARK(&cx->tempPool);
- JS_ARENA_ALLOCATE_CAST(spvec, JSScopeProperty **, &cx->tempPool,
- n * sizeof(JSScopeProperty *));
- if (!spvec) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- }
- scope = OBJ_SCOPE(fun->object);
- for (sprop = SCOPE_LAST_PROP(scope); sprop;
- sprop = sprop->parent) {
- if (sprop->getter == js_GetArgument) {
- JS_ASSERT(nargs++ <= fun->nargs);
- spvec[sprop->shortid] = sprop;
- } else if (sprop->getter == js_GetLocalVariable) {
- JS_ASSERT(nvars++ <= fun->nvars);
- spvec[fun->nargs + sprop->shortid] = sprop;
- }
- }
- for (i = 0; i < n; i++) {
- sprop = spvec[i];
- JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
- type = (i < fun->nargs)
- ? JSXDR_FUNARG
- : (sprop->attrs & JSPROP_READONLY)
- ? JSXDR_FUNCONST
- : JSXDR_FUNVAR;
- userid = INT_TO_JSVAL(sprop->shortid);
- /* XXX lossy conversion, need new XDR version for ECMAv3 */
- propname = JS_GetStringBytes(ATOM_TO_STRING((JSAtom *)sprop->id));
- if (!propname ||
- !JS_XDRUint32(xdr, &type) ||
- !JS_XDRUint32(xdr, &userid) ||
- !JS_XDRCString(xdr, &propname)) {
- if (mark)
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return JS_FALSE;
- }
- }
- if (mark)
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- } else {
- JSPropertyOp getter, setter;
-
- for (i = n; i != 0; i--) {
- uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
-
- if (!JS_XDRUint32(xdr, &type) ||
- !JS_XDRUint32(xdr, &userid) ||
- !JS_XDRCString(xdr, &propname)) {
- return JS_FALSE;
- }
- JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR ||
- type == JSXDR_FUNCONST);
- if (type == JSXDR_FUNARG) {
- getter = js_GetArgument;
- setter = js_SetArgument;
- JS_ASSERT(nargs++ <= fun->nargs);
- } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) {
- getter = js_GetLocalVariable;
- setter = js_SetLocalVariable;
- if (type == JSXDR_FUNCONST)
- attrs |= JSPROP_READONLY;
- JS_ASSERT(nvars++ <= fun->nvars);
- } else {
- getter = NULL;
- setter = NULL;
- }
- atom = js_Atomize(cx, propname, strlen(propname), 0);
- JS_free(cx, propname);
- if (!atom)
- return JS_FALSE;
-
- /* Flag duplicate argument if atom is bound in fun->object. */
- dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), (jsid)atom)
- ? SPROP_IS_DUPLICATE
- : 0;
-
- if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,
- getter, setter, SPROP_INVALID_SLOT,
- attrs | JSPROP_SHARED,
- SPROP_HAS_SHORTID | dupflag,
- JSVAL_TO_INT(userid))) {
- return JS_FALSE;
- }
- }
- }
- }
-
- if (!js_XDRScript(xdr, &fun->script, NULL))
- return JS_FALSE;
-
- if (xdr->mode == JSXDR_DECODE) {
- *objp = fun->object;
- if (atomstr) {
- fun->atom = js_AtomizeString(cx, atomstr, 0);
- if (!fun->atom)
- return JS_FALSE;
-
- if (!OBJ_DEFINE_PROPERTY(cx, cx->globalObject,
- (jsid)fun->atom, OBJECT_TO_JSVAL(*objp),
- NULL, NULL, JSPROP_ENUMERATE,
- NULL)) {
- return JS_FALSE;
- }
- }
-
- js_CallNewScriptHook(cx, fun->script, fun);
- }
-
- return JS_TRUE;
-}
-
-#else /* !JS_HAS_XDR */
-
-#define fun_xdrObject NULL
-
-#endif /* !JS_HAS_XDR */
-
-#if JS_HAS_INSTANCEOF
-
-/*
- * [[HasInstance]] internal method for Function objects: fetch the .prototype
- * property of its 'this' parameter, and walks the prototype chain of v (only
- * if v is an object) returning true if .prototype is found.
- */
-static JSBool
-fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
-{
- jsval pval, cval;
- JSString *str;
- JSObject *proto, *obj2;
- JSFunction *cfun, *ofun;
-
- if (!OBJ_GET_PROPERTY(cx, obj,
- (jsid)cx->runtime->atomState.classPrototypeAtom,
- &pval)) {
- return JS_FALSE;
- }
-
- if (JSVAL_IS_PRIMITIVE(pval)) {
- /*
- * Throw a runtime error if instanceof is called on a function that
- * has a non-object as its .prototype value.
- */
- str = js_DecompileValueGenerator(cx, -1, OBJECT_TO_JSVAL(obj), NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_PROTOTYPE, JS_GetStringBytes(str));
- }
- return JS_FALSE;
- }
-
- proto = JSVAL_TO_OBJECT(pval);
- if (!js_IsDelegate(cx, proto, v, bp))
- return JS_FALSE;
-
- if (!*bp && !JSVAL_IS_PRIMITIVE(v)) {
- /*
- * Extension for "brutal sharing" of standard class constructors: if
- * a script is compiled using a single, shared set of constructors, in
- * particular Function and RegExp, but executed many times using other
- * sets of standard constructors, then (/re/ instanceof RegExp), e.g.,
- * will be false.
- *
- * We extend instanceof in this case to look for a matching native or
- * script underlying the function object found in the 'constructor'
- * property of the object in question (which is JSVAL_TO_OBJECT(v)),
- * or found in the 'constructor' property of one of its prototypes.
- *
- * See also jsexn.c, where the *Error constructors are defined, each
- * with its own native function, to satisfy (e instanceof Error) even
- * when exceptions cross standard-class sharing boundaries. Note that
- * Error.prototype may not lie on e's __proto__ chain in that case.
- */
- obj2 = JSVAL_TO_OBJECT(v);
- do {
- if (!OBJ_GET_PROPERTY(cx, obj2,
- (jsid)cx->runtime->atomState.constructorAtom,
- &cval)) {
- return JS_FALSE;
- }
-
- if (JSVAL_IS_FUNCTION(cx, cval)) {
- cfun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(cval));
- ofun = (JSFunction *) JS_GetPrivate(cx, obj);
- if (cfun->native == ofun->native &&
- cfun->script == ofun->script) {
- *bp = JS_TRUE;
- break;
- }
- }
- } while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL);
- }
-
- return JS_TRUE;
-}
-
-#else /* !JS_HAS_INSTANCEOF */
-
-#define fun_hasInstance NULL
-
-#endif /* !JS_HAS_INSTANCEOF */
-
-static uint32
-fun_mark(JSContext *cx, JSObject *obj, void *arg)
-{
- JSFunction *fun;
-
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- if (fun) {
- if (fun->atom)
- GC_MARK_ATOM(cx, fun->atom, arg);
- if (fun->script)
- js_MarkScript(cx, fun->script, arg);
- }
- return 0;
-}
-
-/*
- * Reserve two slots in all function objects for XPConnect. Note that this
- * does not bloat every instance, only those on which reserved slots are set,
- * and those on which ad-hoc properties are defined.
- */
-JSClass js_FunctionClass = {
- js_Function_str,
- JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2),
- JS_PropertyStub, JS_PropertyStub,
- fun_getProperty, JS_PropertyStub,
- JS_EnumerateStub, (JSResolveOp)fun_resolve,
- fun_convert, fun_finalize,
- NULL, NULL,
- NULL, NULL,
- fun_xdrObject, fun_hasInstance,
- fun_mark, 0
-};
-
-JSBool
-js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
- uintN argc, jsval *argv, jsval *rval)
-{
- jsval fval;
- JSFunction *fun;
- JSString *str;
-
- if (!argv) {
- JS_ASSERT(JS_ObjectIsFunction(cx, obj));
- } else {
- fval = argv[-1];
- if (!JSVAL_IS_FUNCTION(cx, fval)) {
- /*
- * If we don't have a function to start off with, try converting
- * the object to a function. If that doesn't work, complain.
- */
- if (JSVAL_IS_OBJECT(fval)) {
- obj = JSVAL_TO_OBJECT(fval);
- if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,
- &fval)) {
- return JS_FALSE;
- }
- }
- if (!JSVAL_IS_FUNCTION(cx, fval)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_INCOMPATIBLE_PROTO,
- js_Function_str, js_toString_str,
- JS_GetTypeName(cx,
- JS_TypeOfValue(cx, fval)));
- return JS_FALSE;
- }
- }
-
- obj = JSVAL_TO_OBJECT(fval);
- }
-
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- if (!fun)
- return JS_TRUE;
- if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
- return JS_FALSE;
- str = JS_DecompileFunction(cx, fun, (uintN)indent);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-fun_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return js_fun_toString(cx, obj, 0, argc, argv, rval);
-}
-
-#if JS_HAS_TOSOURCE
-static JSBool
-fun_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return js_fun_toString(cx, obj, JS_DONT_PRETTY_PRINT, argc, argv, rval);
-}
-#endif
-
-static const char js_call_str[] = "call";
-
-#if JS_HAS_CALL_FUNCTION
-static JSBool
-fun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval fval, *sp, *oldsp;
- void *mark;
- uintN i;
- JSStackFrame *fp;
- JSBool ok;
-
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
- return JS_FALSE;
- fval = argv[-1];
-
- if (!JSVAL_IS_FUNCTION(cx, fval)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_INCOMPATIBLE_PROTO,
- js_Function_str, js_call_str,
- JS_GetStringBytes(JS_ValueToString(cx, fval)));
- return JS_FALSE;
- }
-
- if (argc == 0) {
- /* Call fun with its parent as the 'this' parameter if no args. */
- obj = OBJ_GET_PARENT(cx, obj);
- } else {
- /* Otherwise convert the first arg to 'this' and skip over it. */
- if (!js_ValueToObject(cx, argv[0], &obj))
- return JS_FALSE;
- argc--;
- argv++;
- }
-
- /* Allocate stack space for fval, obj, and the args. */
- sp = js_AllocStack(cx, 2 + argc, &mark);
- if (!sp)
- return JS_FALSE;
-
- /* Push fval, obj, and the args. */
- *sp++ = fval;
- *sp++ = OBJECT_TO_JSVAL(obj);
- for (i = 0; i < argc; i++)
- *sp++ = argv[i];
-
- /* Lift current frame to include the args and do the call. */
- fp = cx->fp;
- oldsp = fp->sp;
- fp->sp = sp;
- ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
-
- /* Store rval and pop stack back to our frame's sp. */
- *rval = fp->sp[-1];
- fp->sp = oldsp;
- js_FreeStack(cx, mark);
- return ok;
-}
-#endif /* JS_HAS_CALL_FUNCTION */
-
-#if JS_HAS_APPLY_FUNCTION
-static JSBool
-fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval fval, *sp, *oldsp;
- JSObject *aobj;
- jsuint length;
- void *mark;
- uintN i;
- JSBool ok;
- JSStackFrame *fp;
-
- if (argc == 0) {
- /* Will get globalObject as 'this' and no other agurments. */
- return fun_call(cx, obj, argc, argv, rval);
- }
-
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
- return JS_FALSE;
- fval = argv[-1];
-
- if (!JSVAL_IS_FUNCTION(cx, fval)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_INCOMPATIBLE_PROTO,
- js_Function_str, "apply",
- JS_GetStringBytes(JS_ValueToString(cx, fval)));
- return JS_FALSE;
- }
-
- /* Quell GCC overwarnings. */
- aobj = NULL;
- length = 0;
-
- if (argc >= 2) {
- /* If the 2nd arg is null or void, call the function with 0 args. */
- if (JSVAL_IS_NULL(argv[1]) || JSVAL_IS_VOID(argv[1])) {
- argc = 0;
- } else {
- /* The second arg must be an array (or arguments object). */
- if (JSVAL_IS_PRIMITIVE(argv[1]) ||
- (aobj = JSVAL_TO_OBJECT(argv[1]),
- OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass &&
- OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass))
- {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_APPLY_ARGS);
- return JS_FALSE;
- }
- if (!js_GetLengthProperty(cx, aobj, &length))
- return JS_FALSE;
- }
- }
-
- /* Convert the first arg to 'this' and skip over it. */
- if (!js_ValueToObject(cx, argv[0], &obj))
- return JS_FALSE;
-
- /* Allocate stack space for fval, obj, and the args. */
- argc = (uintN)JS_MIN(length, ARGC_LIMIT - 1);
- sp = js_AllocStack(cx, 2 + argc, &mark);
- if (!sp)
- return JS_FALSE;
-
- /* Push fval, obj, and aobj's elements as args. */
- *sp++ = fval;
- *sp++ = OBJECT_TO_JSVAL(obj);
- for (i = 0; i < argc; i++) {
- ok = JS_GetElement(cx, aobj, (jsint)i, sp);
- if (!ok)
- goto out;
- sp++;
- }
-
- /* Lift current frame to include the args and do the call. */
- fp = cx->fp;
- oldsp = fp->sp;
- fp->sp = sp;
- ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
-
- /* Store rval and pop stack back to our frame's sp. */
- *rval = fp->sp[-1];
- fp->sp = oldsp;
-out:
- js_FreeStack(cx, mark);
- return ok;
-}
-#endif /* JS_HAS_APPLY_FUNCTION */
-
-static JSFunctionSpec function_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, fun_toSource, 0,0,0},
-#endif
- {js_toString_str, fun_toString, 1,0,0},
-#if JS_HAS_APPLY_FUNCTION
- {"apply", fun_apply, 2,0,0},
-#endif
-#if JS_HAS_CALL_FUNCTION
- {js_call_str, fun_call, 1,0,0},
-#endif
- {0,0,0,0,0}
-};
-
-JSBool
-js_IsIdentifier(JSString *str)
-{
- size_t n;
- jschar *s, c;
-
- n = JSSTRING_LENGTH(str);
- if (n == 0)
- return JS_FALSE;
- s = JSSTRING_CHARS(str);
- c = *s;
- if (!JS_ISIDENT_START(c))
- return JS_FALSE;
- for (n--; n != 0; n--) {
- c = *++s;
- if (!JS_ISIDENT(c))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-static JSBool
-Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSStackFrame *fp, *caller;
- JSFunction *fun;
- JSObject *parent;
- uintN i, n, lineno, dupflag;
- JSAtom *atom;
- const char *filename;
- JSObject *obj2;
- JSScopeProperty *sprop;
- JSString *str, *arg;
- void *mark;
- JSTokenStream *ts;
- JSPrincipals *principals;
- jschar *collected_args, *cp;
- size_t arg_length, args_length;
- JSTokenType tt;
- JSBool ok;
-
- fp = cx->fp;
- if (fp && !(fp->flags & JSFRAME_CONSTRUCTING)) {
- obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(obj);
- }
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- if (fun)
- return JS_TRUE;
-
-#if JS_HAS_CALL_OBJECT
- /*
- * NB: (new Function) is not lexically closed by its caller, it's just an
- * anonymous function in the top-level scope that its constructor inhabits.
- * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,
- * and so would a call to f from another top-level's script or function.
- *
- * In older versions, before call objects, a new Function was adopted by
- * its running context's globalObject, which might be different from the
- * top-level reachable from scopeChain (in HTML frames, e.g.).
- */
- parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]));
-#else
- /* Set up for dynamic parenting (see js_Invoke in jsinterp.c). */
- parent = NULL;
-#endif
-
- fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent,
- JSVERSION_IS_ECMA(cx->version)
- ? cx->runtime->atomState.anonymousAtom
- : NULL);
-
- if (!fun)
- return JS_FALSE;
-
- /*
- * Function is static and not called directly by other functions in this
- * file, therefore it is callable only as a native function by js_Invoke.
- * Find the scripted caller, possibly skipping other native frames such as
- * are built for Function.prototype.call or .apply activations that invoke
- * Function indirectly from a script.
- */
- JS_ASSERT(!fp->script && fp->fun && fp->fun->native == Function);
- caller = JS_GetScriptedCaller(cx, fp);
- if (caller) {
- filename = caller->script->filename;
- lineno = js_PCToLineNumber(cx, caller->script, caller->pc);
- principals = JS_EvalFramePrincipals(cx, fp, caller);
- } else {
- filename = NULL;
- lineno = 0;
- principals = NULL;
- }
-
- n = argc ? argc - 1 : 0;
- if (n > 0) {
- /*
- * Collect the function-argument arguments into one string, separated
- * by commas, then make a tokenstream from that string, and scan it to
- * get the arguments. We need to throw the full scanner at the
- * problem, because the argument string can legitimately contain
- * comments and linefeeds. XXX It might be better to concatenate
- * everything up into a function definition and pass it to the
- * compiler, but doing it this way is less of a delta from the old
- * code. See ECMA 15.3.2.1.
- */
- args_length = 0;
- for (i = 0; i < n; i++) {
- /* Collect the lengths for all the function-argument arguments. */
- arg = js_ValueToString(cx, argv[i]);
- if (!arg)
- return JS_FALSE;
- argv[i] = STRING_TO_JSVAL(arg);
- args_length += JSSTRING_LENGTH(arg);
- }
- /* Add 1 for each joining comma. */
- args_length += n - 1;
-
- /*
- * Allocate a string to hold the concatenated arguments, including room
- * for a terminating 0. Mark cx->tempPool for later release, to free
- * collected_args and its tokenstream in one swoop.
- */
- mark = JS_ARENA_MARK(&cx->tempPool);
- JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,
- (args_length+1) * sizeof(jschar));
- if (!cp)
- return JS_FALSE;
- collected_args = cp;
-
- /*
- * Concatenate the arguments into the new string, separated by commas.
- */
- for (i = 0; i < n; i++) {
- arg = JSVAL_TO_STRING(argv[i]);
- arg_length = JSSTRING_LENGTH(arg);
- (void) js_strncpy(cp, JSSTRING_CHARS(arg), arg_length);
- cp += arg_length;
-
- /* Add separating comma or terminating 0. */
- *cp++ = (i + 1 < n) ? ',' : 0;
- }
-
- /*
- * Make a tokenstream (allocated from cx->tempPool) that reads from
- * the given string.
- */
- ts = js_NewTokenStream(cx, collected_args, args_length, filename,
- lineno, principals);
- if (!ts) {
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return JS_FALSE;
- }
-
- /* The argument string may be empty or contain no tokens. */
- tt = js_GetToken(cx, ts);
- if (tt != TOK_EOF) {
- for (;;) {
- /*
- * Check that it's a name. This also implicitly guards against
- * TOK_ERROR, which was already reported.
- */
- if (tt != TOK_NAME)
- goto bad_formal;
-
- /*
- * Get the atom corresponding to the name from the tokenstream;
- * we're assured at this point that it's a valid identifier.
- */
- atom = CURRENT_TOKEN(ts).t_atom;
- if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2,
- (JSProperty **)&sprop)) {
- goto bad_formal;
- }
- dupflag = 0;
- if (sprop) {
- ok = JS_TRUE;
- if (obj2 == obj) {
- const char *name = js_AtomToPrintableString(cx, atom);
-
- /*
- * A duplicate parameter name. We force a duplicate
- * node on the SCOPE_LAST_PROP(scope) list with the
- * same id, distinguished by the SPROP_IS_DUPLICATE
- * flag, and not mapped by an entry in scope.
- */
- JS_ASSERT(sprop->getter == js_GetArgument);
- ok = name &&
- js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_DUPLICATE_FORMAL,
- name);
-
- dupflag = SPROP_IS_DUPLICATE;
- }
- OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
- if (!ok)
- goto bad_formal;
- sprop = NULL;
- }
- if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,
- js_GetArgument, js_SetArgument,
- SPROP_INVALID_SLOT,
- JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_SHARED,
- SPROP_HAS_SHORTID | dupflag,
- fun->nargs)) {
- goto bad_formal;
- }
- fun->nargs++;
-
- /*
- * Get the next token. Stop on end of stream. Otherwise
- * insist on a comma, get another name, and iterate.
- */
- tt = js_GetToken(cx, ts);
- if (tt == TOK_EOF)
- break;
- if (tt != TOK_COMMA)
- goto bad_formal;
- tt = js_GetToken(cx, ts);
- }
- }
-
- /* Clean up. */
- ok = js_CloseTokenStream(cx, ts);
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- if (!ok)
- return JS_FALSE;
- }
-
- if (argc) {
- str = js_ValueToString(cx, argv[argc-1]);
- } else {
- /* Can't use cx->runtime->emptyString because we're called too early. */
- str = js_NewStringCopyZ(cx, js_empty_ucstr, 0);
- }
- if (!str)
- return JS_FALSE;
- if (argv) {
- /* Use the last arg (or this if argc == 0) as a local GC root. */
- argv[(intN)(argc-1)] = STRING_TO_JSVAL(str);
- }
-
- mark = JS_ARENA_MARK(&cx->tempPool);
- ts = js_NewTokenStream(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
- filename, lineno, principals);
- if (!ts) {
- ok = JS_FALSE;
- } else {
- ok = js_CompileFunctionBody(cx, ts, fun) &&
- js_CloseTokenStream(cx, ts);
- }
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return ok;
-
-bad_formal:
- /*
- * Report "malformed formal parameter" iff no illegal char or similar
- * scanner error was already reported.
- */
- if (!(ts->flags & TSF_ERROR))
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_FORMAL);
-
- /*
- * Clean up the arguments string and tokenstream if we failed to parse
- * the arguments.
- */
- (void)js_CloseTokenStream(cx, ts);
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return JS_FALSE;
-}
-
-JSObject *
-js_InitFunctionClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
- JSAtom *atom;
- JSFunction *fun;
-
- proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1,
- function_props, function_methods, NULL, NULL);
- if (!proto)
- return NULL;
- atom = js_Atomize(cx, js_FunctionClass.name, strlen(js_FunctionClass.name),
- 0);
- if (!atom)
- goto bad;
- fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL);
- if (!fun)
- goto bad;
- fun->script = js_NewScript(cx, 0, 0, 0);
- if (!fun->script)
- goto bad;
- return proto;
-
-bad:
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
-}
-
-#if JS_HAS_CALL_OBJECT
-JSObject *
-js_InitCallClass(JSContext *cx, JSObject *obj)
-{
- return JS_InitClass(cx, obj, NULL, &js_CallClass, NULL, 0,
- call_props, NULL, NULL, NULL);
-}
-#endif
-
-JSFunction *
-js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
- uintN flags, JSObject *parent, JSAtom *atom)
-{
- JSFunction *fun;
-
- /* Allocate a function struct. */
- fun = (JSFunction *) JS_malloc(cx, sizeof *fun);
- if (!fun)
- return NULL;
-
- /* If funobj is null, allocate an object for it. */
- if (funobj) {
- OBJ_SET_PARENT(cx, funobj, parent);
- } else {
- funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent);
- if (!funobj) {
- JS_free(cx, fun);
- return NULL;
- }
- }
-
- /* Initialize all function members. */
- fun->nrefs = 0;
- fun->object = NULL;
- fun->native = native;
- fun->script = NULL;
- fun->nargs = nargs;
- fun->extra = 0;
- fun->nvars = 0;
- fun->flags = flags & JSFUN_FLAGS_MASK;
- fun->spare = 0;
- fun->atom = atom;
- fun->clasp = NULL;
-
- /* Link fun to funobj and vice versa. */
- if (!js_LinkFunctionObject(cx, fun, funobj)) {
- cx->newborn[GCX_OBJECT] = NULL;
- JS_free(cx, fun);
- return NULL;
- }
- return fun;
-}
-
-JSObject *
-js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
-{
- JSObject *newfunobj;
- JSFunction *fun;
-
- JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
- newfunobj = js_NewObject(cx, &js_FunctionClass, funobj, parent);
- if (!newfunobj)
- return NULL;
- fun = (JSFunction *) JS_GetPrivate(cx, funobj);
- if (!js_LinkFunctionObject(cx, fun, newfunobj)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- return newfunobj;
-}
-
-JSBool
-js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj)
-{
- if (!fun->object)
- fun->object = funobj;
- if (!JS_SetPrivate(cx, funobj, fun))
- return JS_FALSE;
- JS_ATOMIC_INCREMENT(&fun->nrefs);
- return JS_TRUE;
-}
-
-JSFunction *
-js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
- uintN nargs, uintN attrs)
-{
- JSFunction *fun;
-
- fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom);
- if (!fun)
- return NULL;
- if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(fun->object),
- NULL, NULL, attrs & ~JSFUN_FLAGS_MASK, NULL)) {
- return NULL;
- }
- return fun;
-}
-
-#if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK)
-# error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!"
-#endif
-
-JSFunction *
-js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
-{
- jsval v;
- JSObject *obj;
-
- v = *vp;
- obj = NULL;
- if (JSVAL_IS_OBJECT(v)) {
- obj = JSVAL_TO_OBJECT(v);
- if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) {
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v))
- return NULL;
- obj = JSVAL_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
- }
- }
- if (!obj) {
- js_ReportIsNotFunction(cx, vp, flags);
- return NULL;
- }
- return (JSFunction *) JS_GetPrivate(cx, obj);
-}
-
-void
-js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
-{
- JSType type;
- JSString *fallback;
- JSString *str;
-
- /*
- * We provide the typename as the fallback to handle the case when
- * valueOf is not a function, which prevents ValueToString from being
- * called as the default case inside js_DecompileValueGenerator (and
- * so recursing back to here).
- */
- type = JS_TypeOfValue(cx, *vp);
- fallback = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
- str = js_DecompileValueGenerator(cx,
- (flags & JSV2F_SEARCH_STACK)
- ? JSDVG_SEARCH_STACK
- : cx->fp
- ? vp - cx->fp->sp
- : JSDVG_IGNORE_STACK,
- *vp,
- fallback);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- (uintN)((flags & JSV2F_CONSTRUCT)
- ? JSMSG_NOT_CONSTRUCTOR
- : JSMSG_NOT_FUNCTION),
- JS_GetStringBytes(str));
- }
-}
diff --git a/src/extension/script/js/jsfun.h b/src/extension/script/js/jsfun.h
deleted file mode 100644
index 0a3237921..000000000
--- a/src/extension/script/js/jsfun.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsfun_h___
-#define jsfun_h___
-/*
- * JS function definitions.
- */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-struct JSFunction {
- jsrefcount nrefs; /* number of referencing objects */
- JSObject *object; /* back-pointer to GC'ed object header */
- JSNative native; /* native method pointer or null */
- JSScript *script; /* interpreted bytecode descriptor 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 */
- JSClass *clasp; /* if non-null, constructor for this class */
-};
-
-extern JSClass js_ArgumentsClass;
-extern JSClass js_CallClass;
-
-/* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */
-extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
-
-/*
- * NB: jsapi.h and jsobj.h must be included before any call to this macro.
- */
-#define JSVAL_IS_FUNCTION(cx, v) \
- (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass)
-
-extern JSBool
-js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
- uintN argc, jsval *argv, jsval *rval);
-
-extern JSBool
-js_IsIdentifier(JSString *str);
-
-extern JSObject *
-js_InitFunctionClass(JSContext *cx, JSObject *obj);
-
-extern JSObject *
-js_InitArgumentsClass(JSContext *cx, JSObject *obj);
-
-extern JSObject *
-js_InitCallClass(JSContext *cx, JSObject *obj);
-
-extern JSFunction *
-js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
- uintN flags, JSObject *parent, JSAtom *atom);
-
-extern JSObject *
-js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
-
-extern JSBool
-js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);
-
-extern JSFunction *
-js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
- uintN nargs, uintN flags);
-
-/*
- * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on the
- * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
- * with #if/#error in jsfun.c.
- */
-#define JSV2F_CONSTRUCT JSINVOKE_CONSTRUCT
-#define JSV2F_SEARCH_STACK 2
-
-extern JSFunction *
-js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags);
-
-extern void
-js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
-
-extern JSObject *
-js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent);
-
-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 JSBool
-js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
-
-extern JSBool
-js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
- JSObject **objp, jsval *vp);
-
-extern JSObject *
-js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
-
-extern JSBool
-js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
-
-extern JSBool
-js_XDRFunction(JSXDRState *xdr, JSObject **objp);
-
-JS_END_EXTERN_C
-
-#endif /* jsfun_h___ */
diff --git a/src/extension/script/js/jsgc.c b/src/extension/script/js/jsgc.c
deleted file mode 100644
index a0efec4d7..000000000
--- a/src/extension/script/js/jsgc.c
+++ /dev/null
@@ -1,1423 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS Mark-and-Sweep Garbage Collector.
- *
- * This GC allocates only fixed-sized things big enough to contain two words
- * (pointers) on any host architecture. It allocates from an arena pool (see
- * jsarena.h). It uses an ideally parallel array of flag bytes to hold the
- * mark bit, finalizer type index, etc.
- *
- * XXX swizzle page to freelist for better locality of reference
- */
-#include "jsstddef.h"
-#include <stdlib.h> /* for free, called by JS_ARENA_DESTROY */
-#include <string.h> /* for memset, called by jsarena.h macros if DEBUG */
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jshash.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-/*
- * GC arena sizing depends on amortizing arena overhead using a large number
- * of things per arena, and on the thing/flags ratio of 8:1 on most platforms.
- *
- * On 64-bit platforms, we would have half as many things per arena because
- * pointers are twice as big, so we double the bytes for things per arena.
- * This preserves the 1024 byte flags sub-arena size, which relates to the
- * GC_PAGE_SIZE (see below for why).
- */
-#if JS_BYTES_PER_WORD == 8
-# define GC_THINGS_SHIFT 14 /* 16KB for things on Alpha, etc. */
-#else
-# define GC_THINGS_SHIFT 13 /* 8KB for things on most platforms */
-#endif
-#define GC_THINGS_SIZE JS_BIT(GC_THINGS_SHIFT)
-#define GC_FLAGS_SIZE (GC_THINGS_SIZE / sizeof(JSGCThing))
-#define GC_ARENA_SIZE (GC_THINGS_SIZE + GC_FLAGS_SIZE)
-
-/*
- * The private JSGCThing struct, which describes a gcFreeList element.
- */
-struct JSGCThing {
- JSGCThing *next;
- uint8 *flagp;
-};
-
-/*
- * A GC arena contains one flag byte for each thing in its heap, and supports
- * O(1) lookup of a flag given its thing's address.
- *
- * To implement this, we take advantage of the thing/flags numerology: given
- * the 8K bytes worth of GC-things, there are 1K flag bytes. We mask a thing's
- * address with ~1023 to find a JSGCPageInfo record at the front of a mythical
- * "GC page" within the larger 8K thing arena. That JSGCPageInfo contains a
- * pointer to the 128 flag bytes corresponding to the things in the page, so we
- * index into this flags array using the thing's index within its page.
- *
- * To align thing pages on 1024-byte boundaries, we must allocate the 9KB of
- * flags+things arena payload, then find the first 0 mod 1024 boundary after
- * the first payload address. That's where things start, with a JSGCPageInfo
- * taking up the first thing-slot, as usual for 0 mod 1024 byte boundaries.
- * The effect of this alignment trick is to split the flags into at most 2
- * discontiguous spans, one before the things and one after (if we're really
- * lucky, and the arena payload starts on a 0 mod 1024 byte boundary, no need
- * to split).
- *
- * The overhead of this scheme for most platforms is (16+8*(8+1))/(16+9K) or
- * .95% (assuming 16 byte JSArena header size, and 8 byte JSGCThing size).
- *
- * Here's some ASCII art showing an arena:
- *
- * split
- * |
- * V
- * +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
- * |fB| tp0 | tp1 | tp2 | tp3 | tp4 | tp5 | tp6 | tp7 | fA |
- * +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
- * ^ ^
- * tI ---------+ |
- * tJ -------------------------------------------+
- *
- * - fB are the "before split" flags, fA are the "after split" flags
- * - tp0-tp7 are the 8 thing pages
- * - thing tI points into tp1, whose flags are below the split, in fB
- * - thing tJ points into tp5, clearly above the split
- *
- * In general, one of the thing pages will have some of its things' flags on
- * the low side of the split, and the rest of its things' flags on the high
- * side. All the other pages have flags only below or only above. Therefore
- * we'll have to test something to decide whether the split divides flags in
- * a given thing's page. So we store the split pointer (the pointer to tp0)
- * in each JSGCPageInfo, along with the flags pointer for the 128 flag bytes
- * ideally starting, for tp0 things, at the beginning of the arena's payload
- * (at the start of fB).
- *
- * That is, each JSGCPageInfo's flags pointer is 128 bytes from the previous,
- * or at the start of the arena if there is no previous page in this arena.
- * Thus these ideal 128-byte flag pages run contiguously from the start of the
- * arena (right over the split!), and the JSGCPageInfo flags pointers contain
- * no discontinuities over the split created by the thing pages. So if, for a
- * given JSGCPageInfo *pi, we find that
- *
- * pi->flags + ((jsuword)thing % 1024) / sizeof(JSGCThing) >= pi->split
- *
- * then we must add GC_THINGS_SIZE to the nominal flags pointer to jump over
- * all the thing pages that split the flags into two discontiguous spans.
- *
- * (If we need to implement card-marking for an incremental GC write barrier,
- * we can use the low byte of the pi->split pointer as the card-mark, for an
- * extremely efficient write barrier: when mutating an object obj, just store
- * a 1 byte at (uint8 *) ((jsuword)obj & ~1023) for little-endian platforms.
- * When finding flags, we'll of course have to mask split with ~255, but it is
- * guaranteed to be 1024-byte aligned, so no information is lost by overlaying
- * the card-mark byte on split's low byte.)
- */
-#define GC_PAGE_SHIFT 10
-#define GC_PAGE_MASK ((jsuword) JS_BITMASK(GC_PAGE_SHIFT))
-#define GC_PAGE_SIZE JS_BIT(GC_PAGE_SHIFT)
-
-typedef struct JSGCPageInfo {
- uint8 *split;
- uint8 *flags;
-} JSGCPageInfo;
-
-#define FIRST_THING_PAGE(a) (((a)->base + GC_FLAGS_SIZE) & ~GC_PAGE_MASK)
-
-static JSGCThing *
-gc_new_arena(JSArenaPool *pool)
-{
- uint8 *flagp, *split, *pagep, *limit;
- JSArena *a;
- JSGCThing *thing;
- JSGCPageInfo *pi;
-
- /* Use JS_ArenaAllocate to grab another 9K-net-size hunk of space. */
- flagp = (uint8 *) JS_ArenaAllocate(pool, GC_ARENA_SIZE);
- if (!flagp)
- return NULL;
- a = pool->current;
-
- /* Reset a->avail to start at the flags split, aka the first thing page. */
- a->avail = FIRST_THING_PAGE(a);
- split = pagep = (uint8 *) a->avail;
- a->avail += sizeof(JSGCPageInfo);
- thing = (JSGCThing *) a->avail;
- a->avail += sizeof(JSGCThing);
-
- /* Initialize the JSGCPageInfo records at the start of every thing page. */
- limit = pagep + GC_THINGS_SIZE;
- do {
- pi = (JSGCPageInfo *) pagep;
- pi->split = split;
- pi->flags = flagp;
- flagp += GC_PAGE_SIZE >> (GC_THINGS_SHIFT - GC_PAGE_SHIFT);
- pagep += GC_PAGE_SIZE;
- } while (pagep < limit);
- return thing;
-}
-
-uint8 *
-js_GetGCThingFlags(void *thing)
-{
- JSGCPageInfo *pi;
- uint8 *flagp;
-
- pi = (JSGCPageInfo *) ((jsuword)thing & ~GC_PAGE_MASK);
- flagp = pi->flags + ((jsuword)thing & GC_PAGE_MASK) / sizeof(JSGCThing);
- if (flagp >= pi->split)
- flagp += GC_THINGS_SIZE;
- return flagp;
-}
-
-JSBool
-js_IsAboutToBeFinalized(JSContext *cx, void *thing)
-{
- uint8 flags = *js_GetGCThingFlags(thing);
-
- return !(flags & (GCF_MARK | GCF_LOCKMASK | GCF_FINAL));
-}
-
-typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing);
-
-static GCFinalizeOp gc_finalizers[GCX_NTYPES];
-
-intN
-js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
- JSStringFinalizeOp newop)
-{
- uintN i;
-
- for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) {
- if (gc_finalizers[i] == (GCFinalizeOp) oldop) {
- gc_finalizers[i] = (GCFinalizeOp) newop;
- return (intN) i;
- }
- }
- return -1;
-}
-
-#ifdef JS_GCMETER
-#define METER(x) x
-#else
-#define METER(x) /* nothing */
-#endif
-
-/* Initial size of the gcRootsHash table (SWAG, small enough to amortize). */
-#define GC_ROOTS_SIZE 256
-#define GC_FINALIZE_LEN 1024
-
-JSBool
-js_InitGC(JSRuntime *rt, uint32 maxbytes)
-{
- JS_ASSERT(sizeof(JSGCThing) == sizeof(JSGCPageInfo));
- JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSObject));
- JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSString));
- JS_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble));
- JS_ASSERT(GC_FLAGS_SIZE >= GC_PAGE_SIZE);
- JS_ASSERT(sizeof(JSStackHeader) >= 2 * sizeof(jsval));
-
- if (!gc_finalizers[GCX_OBJECT]) {
- gc_finalizers[GCX_OBJECT] = (GCFinalizeOp)js_FinalizeObject;
- gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
-#ifdef DEBUG
- gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
-#endif
- gc_finalizers[GCX_MUTABLE_STRING] = (GCFinalizeOp)js_FinalizeString;
- }
-
- JS_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
- sizeof(JSGCThing));
- if (!JS_DHashTableInit(&rt->gcRootsHash, JS_DHashGetStubOps(), NULL,
- sizeof(JSGCRootHashEntry), GC_ROOTS_SIZE)) {
- rt->gcRootsHash.ops = NULL;
- return JS_FALSE;
- }
- rt->gcLocksHash = NULL; /* create lazily */
- rt->gcMaxBytes = maxbytes;
- return JS_TRUE;
-}
-
-#ifdef JS_GCMETER
-void
-js_DumpGCStats(JSRuntime *rt, FILE *fp)
-{
- fprintf(fp, "\nGC allocation statistics:\n");
- fprintf(fp, " bytes currently allocated: %lu\n", rt->gcBytes);
- fprintf(fp, " alloc attempts: %lu\n", rt->gcStats.alloc);
- fprintf(fp, " GC freelist length: %lu\n", rt->gcStats.freelen);
- fprintf(fp, " recycles through GC freelist: %lu\n", rt->gcStats.recycle);
- fprintf(fp, "alloc retries after running GC: %lu\n", rt->gcStats.retry);
- fprintf(fp, " allocation failures: %lu\n", rt->gcStats.fail);
- fprintf(fp, " valid lock calls: %lu\n", rt->gcStats.lock);
- fprintf(fp, " valid unlock calls: %lu\n", rt->gcStats.unlock);
- fprintf(fp, " locks that hit stuck counts: %lu\n", rt->gcStats.stuck);
- fprintf(fp, " unlocks that saw stuck counts: %lu\n", rt->gcStats.unstuck);
- fprintf(fp, " mark recursion depth: %lu\n", rt->gcStats.depth);
- fprintf(fp, " maximum mark recursion depth: %lu\n", rt->gcStats.maxdepth);
- fprintf(fp, " maximum GC nesting level: %lu\n", rt->gcStats.maxlevel);
- fprintf(fp, " potentially useful GC calls: %lu\n", rt->gcStats.poke);
- fprintf(fp, " useless GC calls: %lu\n", rt->gcStats.nopoke);
- fprintf(fp, " thing arenas freed so far: %lu\n", rt->gcStats.afree);
- fprintf(fp, " extra stack segments scanned: %lu\n", rt->gcStats.stackseg);
- fprintf(fp, " stack segment slots scanned: %lu\n", rt->gcStats.segslots);
-#ifdef JS_ARENAMETER
- JS_DumpArenaStats(fp);
-#endif
-}
-#endif
-
-#ifdef DEBUG
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg)
-{
- uint32 *leakedroots = (uint32 *)arg;
- JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
-
- (*leakedroots)++;
- fprintf(stderr,
- "JS engine warning: leaking GC root \'%s\' at %p\n",
- rhe->name ? (char *)rhe->name : "", rhe->root);
-
- return JS_DHASH_NEXT;
-}
-#endif
-
-void
-js_FinishGC(JSRuntime *rt)
-{
-#ifdef JS_ARENAMETER
- JS_DumpArenaStats(stdout);
-#endif
-#ifdef JS_GCMETER
- js_DumpGCStats(rt, stdout);
-#endif
- JS_FinishArenaPool(&rt->gcArenaPool);
- JS_ArenaFinish();
-
- if (rt->gcRootsHash.ops) {
-#ifdef DEBUG
- uint32 leakedroots = 0;
-
- /* Warn (but don't assert) debug builds of any remaining roots. */
- JS_DHashTableEnumerate(&rt->gcRootsHash, js_root_printer,
- &leakedroots);
- if (leakedroots > 0) {
- if (leakedroots == 1) {
- fprintf(stderr,
-"JS engine warning: 1 GC root remains after destroying the JSRuntime.\n"
-" This root may point to freed memory. Objects reachable\n"
-" through it have not been finalized.\n");
- } else {
- fprintf(stderr,
-"JS engine warning: %lu GC roots remain after destroying the JSRuntime.\n"
-" These roots may point to freed memory. Objects reachable\n"
-" through them have not been finalized.\n",
- (unsigned long) leakedroots);
- }
- }
-#endif
-
- JS_DHashTableFinish(&rt->gcRootsHash);
- rt->gcRootsHash.ops = NULL;
- }
- if (rt->gcLocksHash) {
- JS_DHashTableDestroy(rt->gcLocksHash);
- rt->gcLocksHash = NULL;
- }
- rt->gcFreeList = NULL;
-}
-
-JSBool
-js_AddRoot(JSContext *cx, void *rp, const char *name)
-{
- JSBool ok = js_AddRootRT(cx->runtime, rp, name);
- if (!ok)
- JS_ReportOutOfMemory(cx);
- return ok;
-}
-
-JSBool
-js_AddRootRT(JSRuntime *rt, void *rp, const char *name)
-{
- JSBool ok;
- JSGCRootHashEntry *rhe;
-
- /*
- * Due to the long-standing, but now removed, use of rt->gcLock across the
- * bulk of js_GC, API users have come to depend on JS_AddRoot etc. locking
- * properly with a racing GC, without calling JS_AddRoot from a request.
- * We have to preserve API compatibility here, now that we avoid holding
- * rt->gcLock across the mark phase (including the root hashtable mark).
- *
- * If the GC is running and we're called on another thread, wait for this
- * GC activation to finish. We can safely wait here (in the case where we
- * are called within a request on another thread's context) without fear
- * of deadlock because the GC doesn't set rt->gcRunning until after it has
- * waited for all active requests to end.
- */
- JS_LOCK_GC(rt);
-#ifdef JS_THREADSAFE
- JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
- if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
- do {
- JS_AWAIT_GC_DONE(rt);
- } while (rt->gcLevel > 0);
- }
-#endif
- rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp,
- JS_DHASH_ADD);
- if (rhe) {
- rhe->root = rp;
- rhe->name = name;
- ok = JS_TRUE;
- } else {
- ok = JS_FALSE;
- }
- JS_UNLOCK_GC(rt);
- return ok;
-}
-
-JSBool
-js_RemoveRoot(JSRuntime *rt, void *rp)
-{
- /*
- * Due to the JS_RemoveRootRT API, we may be called outside of a request.
- * Same synchronization drill as above in js_AddRoot.
- */
- JS_LOCK_GC(rt);
-#ifdef JS_THREADSAFE
- JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
- if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
- do {
- JS_AWAIT_GC_DONE(rt);
- } while (rt->gcLevel > 0);
- }
-#endif
- (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE);
- rt->gcPoke = JS_TRUE;
- JS_UNLOCK_GC(rt);
- return JS_TRUE;
-}
-
-void *
-js_AllocGCThing(JSContext *cx, uintN flags)
-{
- JSBool tried_gc;
- JSRuntime *rt;
- JSGCThing *thing;
- uint8 *flagp;
-
-#ifdef TOO_MUCH_GC
- js_GC(cx, GC_KEEP_ATOMS);
- tried_gc = JS_TRUE;
-#else
- tried_gc = JS_FALSE;
-#endif
-
- rt = cx->runtime;
- JS_LOCK_GC(rt);
- JS_ASSERT(!rt->gcRunning);
- if (rt->gcRunning) {
- METER(rt->gcStats.finalfail++);
- JS_UNLOCK_GC(rt);
- return NULL;
- }
- METER(rt->gcStats.alloc++);
-retry:
- thing = rt->gcFreeList;
- if (thing) {
- rt->gcFreeList = thing->next;
- flagp = thing->flagp;
- METER(rt->gcStats.freelen--);
- METER(rt->gcStats.recycle++);
- } else {
- if (rt->gcBytes < rt->gcMaxBytes &&
- (tried_gc || rt->gcMallocBytes < rt->gcMaxBytes))
- {
- /*
- * Inline form of JS_ARENA_ALLOCATE adapted to truncate the current
- * arena's limit to a GC_PAGE_SIZE boundary, and to skip over every
- * GC_PAGE_SIZE-byte-aligned thing (which is actually not a thing,
- * it's a JSGCPageInfo record).
- */
- JSArenaPool *pool = &rt->gcArenaPool;
- JSArena *a = pool->current;
- size_t nb = sizeof(JSGCThing);
- jsuword p = a->avail;
- jsuword q = p + nb;
-
- if (q > (a->limit & ~GC_PAGE_MASK)) {
- thing = gc_new_arena(pool);
- } else {
- if ((p & GC_PAGE_MASK) == 0) {
- /* Beware, p points to a JSGCPageInfo record! */
- p = q;
- q += nb;
- JS_ArenaCountAllocation(pool, nb);
- }
- a->avail = q;
- thing = (JSGCThing *)p;
- }
- JS_ArenaCountAllocation(pool, nb);
- }
-
- /*
- * Consider doing a "last ditch" GC if thing couldn't be allocated.
- *
- * Keep rt->gcLock across the call into js_GC so we don't starve and
- * lose to racing threads who deplete the heap just after js_GC has
- * replenished it (or has synchronized with a racing GC that collected
- * a bunch of garbage). This unfair scheduling can happen on certain
- * operating systems. For the gory details, see Mozilla bug 162779
- * (http://bugzilla.mozilla.org/show_bug.cgi?id=162779).
- */
- if (!thing) {
- if (!tried_gc) {
- rt->gcPoke = JS_TRUE;
- js_GC(cx, GC_KEEP_ATOMS | GC_ALREADY_LOCKED);
- tried_gc = JS_TRUE;
- METER(rt->gcStats.retry++);
- goto retry;
- }
- METER(rt->gcStats.fail++);
- JS_UNLOCK_GC(rt);
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
-
- /* Find the flags pointer given thing's address. */
- flagp = js_GetGCThingFlags(thing);
- }
- *flagp = (uint8)flags;
- rt->gcBytes += sizeof(JSGCThing) + sizeof(uint8);
- cx->newborn[flags & GCF_TYPEMASK] = thing;
-
- /*
- * Clear thing before unlocking in case a GC run is about to scan it,
- * finding it via cx->newborn[].
- */
- thing->next = NULL;
- thing->flagp = NULL;
- JS_UNLOCK_GC(rt);
- return thing;
-}
-
-JSBool
-js_LockGCThing(JSContext *cx, void *thing)
-{
- JSBool ok = js_LockGCThingRT(cx->runtime, thing);
- if (!ok)
- JS_ReportOutOfMemory(cx);
- return ok;
-}
-
-JSBool
-js_LockGCThingRT(JSRuntime *rt, void *thing)
-{
- uint8 *flagp, flags, lockbits;
- JSBool ok;
- JSGCLockHashEntry *lhe;
-
- if (!thing)
- return JS_TRUE;
- flagp = js_GetGCThingFlags(thing);
- flags = *flagp;
-
- ok = JS_FALSE;
- JS_LOCK_GC(rt);
- lockbits = (flags & GCF_LOCKMASK);
-
- if (lockbits != GCF_LOCKMASK) {
- if ((flags & GCF_TYPEMASK) == GCX_OBJECT) {
- /* Objects may require "deep locking", i.e., rooting by value. */
- if (lockbits == 0) {
- if (!rt->gcLocksHash) {
- rt->gcLocksHash =
- JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
- sizeof(JSGCLockHashEntry),
- GC_ROOTS_SIZE);
- if (!rt->gcLocksHash)
- goto error;
- } else {
-#ifdef DEBUG
- JSDHashEntryHdr *hdr =
- JS_DHashTableOperate(rt->gcLocksHash, thing,
- JS_DHASH_LOOKUP);
- JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr));
-#endif
- }
- lhe = (JSGCLockHashEntry *)
- JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD);
- if (!lhe)
- goto error;
- lhe->thing = thing;
- lhe->count = 1;
- *flagp = (uint8)(flags + GCF_LOCK);
- } else {
- JS_ASSERT(lockbits == GCF_LOCK);
- lhe = (JSGCLockHashEntry *)
- JS_DHashTableOperate(rt->gcLocksHash, thing,
- JS_DHASH_LOOKUP);
- JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr));
- if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr)) {
- JS_ASSERT(lhe->count >= 1);
- lhe->count++;
- }
- }
- } else {
- *flagp = (uint8)(flags + GCF_LOCK);
- }
- } else {
- METER(rt->gcStats.stuck++);
- }
-
- METER(rt->gcStats.lock++);
- ok = JS_TRUE;
-error:
- JS_UNLOCK_GC(rt);
- return ok;
-}
-
-JSBool
-js_UnlockGCThingRT(JSRuntime *rt, void *thing)
-{
- uint8 *flagp, flags, lockbits;
- JSGCLockHashEntry *lhe;
-
- if (!thing)
- return JS_TRUE;
- flagp = js_GetGCThingFlags(thing);
- flags = *flagp;
-
- JS_LOCK_GC(rt);
- lockbits = (flags & GCF_LOCKMASK);
-
- if (lockbits != GCF_LOCKMASK) {
- if ((flags & GCF_TYPEMASK) == GCX_OBJECT) {
- /* Defend against a call on an unlocked object. */
- if (lockbits != 0) {
- JS_ASSERT(lockbits == GCF_LOCK);
- lhe = (JSGCLockHashEntry *)
- JS_DHashTableOperate(rt->gcLocksHash, thing,
- JS_DHASH_LOOKUP);
- JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr));
- if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr) &&
- --lhe->count == 0) {
- (void) JS_DHashTableOperate(rt->gcLocksHash, thing,
- JS_DHASH_REMOVE);
- *flagp = (uint8)(flags & ~GCF_LOCKMASK);
- }
- }
- } else {
- *flagp = (uint8)(flags - GCF_LOCK);
- }
- } else {
- METER(rt->gcStats.unstuck++);
- }
-
- rt->gcPoke = JS_TRUE;
- METER(rt->gcStats.unlock++);
- JS_UNLOCK_GC(rt);
- return JS_TRUE;
-}
-
-#ifdef GC_MARK_DEBUG
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "jsprf.h"
-
-JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
-JS_EXPORT_DATA(void *) js_LiveThingToFind;
-
-#ifdef HAVE_XPCONNECT
-#include "dump_xpc.h"
-#endif
-
-static const char *
-gc_object_class_name(void* thing)
-{
- uint8 *flagp = js_GetGCThingFlags(thing);
- const char *className = "";
- static char depbuf[32];
-
- switch (*flagp & GCF_TYPEMASK) {
- case GCX_OBJECT: {
- JSObject *obj = (JSObject *)thing;
- JSClass *clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);
- className = clasp->name;
-#ifdef HAVE_XPCONNECT
- if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
- jsval privateValue = obj->slots[JSSLOT_PRIVATE];
-
- JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);
- if (!JSVAL_IS_VOID(privateValue)) {
- void *privateThing = JSVAL_TO_PRIVATE(privateValue);
- const char *xpcClassName = GetXPCObjectClassName(privateThing);
-
- if (xpcClassName)
- className = xpcClassName;
- }
- }
-#endif
- break;
- }
-
- case GCX_STRING:
- case GCX_MUTABLE_STRING: {
- JSString *str = (JSString *)thing;
- if (JSSTRING_IS_DEPENDENT(str)) {
- JS_snprintf(depbuf, sizeof depbuf, "start:%u, length:%u",
- JSSTRDEP_START(str), JSSTRDEP_LENGTH(str));
- className = depbuf;
- } else {
- className = "string";
- }
- break;
- }
-
- case GCX_DOUBLE:
- className = "double";
- break;
- }
-
- return className;
-}
-
-static void
-gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp)
-{
- GCMarkNode *next = NULL;
- char *path = NULL;
-
- while (prev) {
- next = prev;
- prev = prev->prev;
- }
- while (next) {
- path = JS_sprintf_append(path, "%s(%s).",
- next->name,
- gc_object_class_name(next->thing));
- next = next->next;
- }
- if (!path)
- return;
-
- fprintf(fp, "%08lx ", (long)thing);
- switch (flags & GCF_TYPEMASK) {
- case GCX_OBJECT:
- {
- JSObject *obj = (JSObject *)thing;
- jsval privateValue = obj->slots[JSSLOT_PRIVATE];
- void *privateThing = JSVAL_IS_VOID(privateValue)
- ? NULL
- : JSVAL_TO_PRIVATE(privateValue);
- const char *className = gc_object_class_name(thing);
- fprintf(fp, "object %8p %s", privateThing, className);
- break;
- }
- case GCX_DOUBLE:
- fprintf(fp, "double %g", *(jsdouble *)thing);
- break;
- default:
- fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing));
- break;
- }
- fprintf(fp, " via %s\n", path);
- free(path);
-}
-
-#endif /* !GC_MARK_DEBUG */
-
-static void
-gc_mark_atom_key_thing(void *thing, void *arg)
-{
- JSContext *cx = (JSContext *) arg;
-
- GC_MARK(cx, thing, "atom", NULL);
-}
-
-void
-js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg)
-{
- jsval key;
-
- if (atom->flags & ATOM_MARK)
- return;
- atom->flags |= ATOM_MARK;
- key = ATOM_KEY(atom);
- if (JSVAL_IS_GCTHING(key)) {
-#ifdef GC_MARK_DEBUG
- char name[32];
-
- if (JSVAL_IS_STRING(key)) {
- JS_snprintf(name, sizeof name, "'%s'",
- JS_GetStringBytes(JSVAL_TO_STRING(key)));
- } else {
- JS_snprintf(name, sizeof name, "<%x>", key);
- }
-#endif
- GC_MARK(cx, JSVAL_TO_GCTHING(key), name, arg);
- }
-}
-
-void
-js_MarkGCThing(JSContext *cx, void *thing, void *arg)
-{
- uint8 flags, *flagp;
- JSRuntime *rt;
- JSObject *obj;
- uint32 nslots;
- jsval v, *vp, *end;
- JSString *str;
-#ifdef GC_MARK_DEBUG
- JSScope *scope;
- JSScopeProperty *sprop;
-#endif
-
- if (!thing)
- return;
-
- flagp = js_GetGCThingFlags(thing);
- flags = *flagp;
- JS_ASSERT(flags != GCF_FINAL);
-#ifdef GC_MARK_DEBUG
- if (js_LiveThingToFind == thing)
- gc_dump_thing(thing, flags, arg, stderr);
-#endif
-
- if (flags & GCF_MARK)
- return;
-
- *flagp |= GCF_MARK;
- rt = cx->runtime;
- METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth)
- rt->gcStats.maxdepth = rt->gcStats.depth);
-
-#ifdef GC_MARK_DEBUG
- if (js_DumpGCHeap)
- gc_dump_thing(thing, flags, arg, js_DumpGCHeap);
-#endif
-
- switch (flags & GCF_TYPEMASK) {
- case GCX_OBJECT:
- obj = (JSObject *) thing;
- vp = obj->slots;
- if (!vp) {
- /* If obj->slots is null, obj must be a newborn. */
- JS_ASSERT(!obj->map);
- goto out;
- }
- nslots = (obj->map->ops->mark)
- ? obj->map->ops->mark(cx, obj, arg)
- : JS_MIN(obj->map->freeslot, obj->map->nslots);
-#ifdef GC_MARK_DEBUG
- scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL;
-#endif
- for (end = vp + nslots; vp < end; vp++) {
- v = *vp;
- if (JSVAL_IS_GCTHING(v)) {
-#ifdef GC_MARK_DEBUG
- char name[32];
-
- if (scope) {
- uint32 slot;
- jsval nval;
-
- slot = vp - obj->slots;
- for (sprop = SCOPE_LAST_PROP(scope); ;
- sprop = sprop->parent) {
- if (!sprop) {
- switch (slot) {
- case JSSLOT_PROTO:
- strcpy(name, "__proto__");
- break;
- case JSSLOT_PARENT:
- strcpy(name, "__parent__");
- break;
- case JSSLOT_PRIVATE:
- strcpy(name, "__private__");
- break;
- default:
- JS_snprintf(name, sizeof name,
- "**UNKNOWN SLOT %ld**",
- (long)slot);
- break;
- }
- break;
- }
- if (sprop->slot == slot) {
- nval = ID_TO_VALUE(sprop->id);
- if (JSVAL_IS_INT(nval)) {
- JS_snprintf(name, sizeof name, "%ld",
- (long)JSVAL_TO_INT(nval));
- } else if (JSVAL_IS_STRING(nval)) {
- JS_snprintf(name, sizeof name, "%s",
- JS_GetStringBytes(JSVAL_TO_STRING(nval)));
- } else {
- strcpy(name, "**FINALIZED ATOM KEY**");
- }
- break;
- }
- }
- } else {
- strcpy(name, "**UNKNOWN OBJECT MAP ENTRY**");
- }
-#endif
- GC_MARK(cx, JSVAL_TO_GCTHING(v), name, arg);
- }
- }
- break;
-
-#ifdef DEBUG
- case GCX_STRING:
- str = (JSString *)thing;
- JS_ASSERT(!JSSTRING_IS_DEPENDENT(str));
- break;
-#endif
-
- case GCX_MUTABLE_STRING:
- str = (JSString *)thing;
- if (JSSTRING_IS_DEPENDENT(str))
- GC_MARK(cx, JSSTRDEP_BASE(str), "base", arg);
- break;
- }
-
-out:
- METER(rt->gcStats.depth--);
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-gc_root_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
-{
- JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
- jsval *rp = (jsval *)rhe->root;
- jsval v = *rp;
-
- /* Ignore null object and scalar values. */
- if (!JSVAL_IS_NULL(v) && JSVAL_IS_GCTHING(v)) {
- JSContext *cx = (JSContext *)arg;
-#ifdef DEBUG
- JSArena *a;
- jsuword firstpage;
- JSBool root_points_to_gcArenaPool = JS_FALSE;
- void *thing = JSVAL_TO_GCTHING(v);
-
- for (a = cx->runtime->gcArenaPool.first.next; a; a = a->next) {
- firstpage = FIRST_THING_PAGE(a);
- if (JS_UPTRDIFF(thing, firstpage) < a->avail - firstpage) {
- root_points_to_gcArenaPool = JS_TRUE;
- break;
- }
- }
- if (!root_points_to_gcArenaPool && rhe->name) {
- fprintf(stderr,
-"JS API usage error: the address passed to JS_AddNamedRoot currently holds an\n"
-"invalid jsval. This is usually caused by a missing call to JS_RemoveRoot.\n"
-"The root's name is \"%s\".\n",
- rhe->name);
- }
- JS_ASSERT(root_points_to_gcArenaPool);
-#endif
-
- GC_MARK(cx, JSVAL_TO_GCTHING(v), rhe->name ? rhe->name : "root", NULL);
- }
- return JS_DHASH_NEXT;
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-gc_lock_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
-{
- JSGCLockHashEntry *lhe = (JSGCLockHashEntry *)hdr;
- void *thing = (void *)lhe->thing;
- JSContext *cx = (JSContext *)arg;
-
- GC_MARK(cx, thing, "locked object", NULL);
- return JS_DHASH_NEXT;
-}
-
-void
-js_ForceGC(JSContext *cx, uintN gcflags)
-{
- uintN i;
-
- for (i = 0; i < GCX_NTYPES; i++)
- cx->newborn[i] = NULL;
- cx->lastAtom = NULL;
- cx->runtime->gcPoke = JS_TRUE;
- js_GC(cx, gcflags);
- JS_ArenaFinish();
-}
-
-#define GC_MARK_JSVALS(cx, len, vec, name) \
- JS_BEGIN_MACRO \
- jsval _v, *_vp, *_end; \
- \
- for (_vp = vec, _end = _vp + len; _vp < _end; _vp++) { \
- _v = *_vp; \
- if (JSVAL_IS_GCTHING(_v)) \
- GC_MARK(cx, JSVAL_TO_GCTHING(_v), name, NULL); \
- } \
- JS_END_MACRO
-
-void
-js_GC(JSContext *cx, uintN gcflags)
-{
- JSRuntime *rt;
- JSContext *iter, *acx;
- JSStackFrame *fp, *chain;
- uintN i, depth, nslots, type;
- JSStackHeader *sh;
- JSArena *a, **ap;
- uint8 flags, *flagp, *split;
- JSGCThing *thing, *limit, **flp, **oflp;
- GCFinalizeOp finalizer;
- JSBool all_clear;
-#ifdef JS_THREADSAFE
- jsword currentThread;
- uint32 requestDebit;
-#endif
-
- rt = cx->runtime;
-#ifdef JS_THREADSAFE
- /* Avoid deadlock. */
- JS_ASSERT(!JS_IS_RUNTIME_LOCKED(rt));
-#endif
-
- /*
- * Don't collect garbage if the runtime isn't up, and cx is not the last
- * context in the runtime. The last context must force a GC, and nothing
- * should suppress that final collection or there may be shutdown leaks,
- * or runtime bloat until the next context is created.
- */
- if (rt->state != JSRTS_UP && !(gcflags & GC_LAST_CONTEXT))
- return;
-
- /*
- * Let the API user decide to defer a GC if it wants to (unless this
- * is the last context). Invoke the callback regardless.
- */
- if (rt->gcCallback) {
- if (!rt->gcCallback(cx, JSGC_BEGIN) && !(gcflags & GC_LAST_CONTEXT))
- return;
- }
-
- /* Lock out other GC allocator and collector invocations. */
- if (!(gcflags & GC_ALREADY_LOCKED))
- JS_LOCK_GC(rt);
-
- /* Do nothing if no assignment has executed since the last GC. */
- if (!rt->gcPoke) {
- METER(rt->gcStats.nopoke++);
- if (!(gcflags & GC_ALREADY_LOCKED))
- JS_UNLOCK_GC(rt);
- return;
- }
- METER(rt->gcStats.poke++);
-
-#ifdef JS_THREADSAFE
- /* Bump gcLevel and return rather than nest on this thread. */
- currentThread = js_CurrentThreadId();
- if (rt->gcThread == currentThread) {
- JS_ASSERT(rt->gcLevel > 0);
- rt->gcLevel++;
- METER(if (rt->gcLevel > rt->gcStats.maxlevel)
- rt->gcStats.maxlevel = rt->gcLevel);
- if (!(gcflags & GC_ALREADY_LOCKED))
- JS_UNLOCK_GC(rt);
- return;
- }
-
- /*
- * If we're in one or more requests (possibly on more than one context)
- * running on the current thread, indicate, temporarily, that all these
- * requests are inactive. NB: if cx->thread is 0, then cx is not using
- * the request model, and does not contribute to rt->requestCount.
- */
- requestDebit = 0;
- if (cx->thread) {
- /*
- * Check all contexts for any with the same thread-id. XXX should we
- * keep a sub-list of contexts having the same id?
- */
- iter = NULL;
- while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
- if (acx->thread == cx->thread && acx->requestDepth)
- requestDebit++;
- }
- } else {
- /*
- * We assert, but check anyway, in case someone is misusing the API.
- * Avoiding the loop over all of rt's contexts is a win in the event
- * that the GC runs only on request-less contexts with 0 thread-ids,
- * in a special thread such as might be used by the UI/DOM/Layout
- * "mozilla" or "main" thread in Mozilla-the-browser.
- */
- JS_ASSERT(cx->requestDepth == 0);
- if (cx->requestDepth)
- requestDebit = 1;
- }
- if (requestDebit) {
- JS_ASSERT(requestDebit <= rt->requestCount);
- rt->requestCount -= requestDebit;
- if (rt->requestCount == 0)
- JS_NOTIFY_REQUEST_DONE(rt);
- }
-
- /* If another thread is already in GC, don't attempt GC; wait instead. */
- if (rt->gcLevel > 0) {
- /* Bump gcLevel to restart the current GC, so it finds new garbage. */
- rt->gcLevel++;
- METER(if (rt->gcLevel > rt->gcStats.maxlevel)
- rt->gcStats.maxlevel = rt->gcLevel);
-
- /* Wait for the other thread to finish, then resume our request. */
- while (rt->gcLevel > 0)
- JS_AWAIT_GC_DONE(rt);
- if (requestDebit)
- rt->requestCount += requestDebit;
- if (!(gcflags & GC_ALREADY_LOCKED))
- JS_UNLOCK_GC(rt);
- return;
- }
-
- /* No other thread is in GC, so indicate that we're now in GC. */
- rt->gcLevel = 1;
- rt->gcThread = currentThread;
-
- /* Wait for all other requests to finish. */
- while (rt->requestCount > 0)
- JS_AWAIT_REQUEST_DONE(rt);
-
-#else /* !JS_THREADSAFE */
-
- /* Bump gcLevel and return rather than nest; the outer gc will restart. */
- rt->gcLevel++;
- METER(if (rt->gcLevel > rt->gcStats.maxlevel)
- rt->gcStats.maxlevel = rt->gcLevel);
- if (rt->gcLevel > 1)
- return;
-
-#endif /* !JS_THREADSAFE */
-
- /*
- * Set rt->gcRunning here within the GC lock, and after waiting for any
- * active requests to end, so that new requests that try to JS_AddRoot,
- * JS_RemoveRoot, or JS_RemoveRootRT block in JS_BeginRequest waiting for
- * rt->gcLevel to drop to zero, while request-less calls to the *Root*
- * APIs block in js_AddRoot or js_RemoveRoot (see above in this file),
- * waiting for GC to finish.
- */
- rt->gcRunning = JS_TRUE;
- JS_UNLOCK_GC(rt);
-
- /* If a suspended compile is running on another context, keep atoms. */
- if (rt->gcKeepAtoms)
- gcflags |= GC_KEEP_ATOMS;
-
- /* Reset malloc counter. */
- rt->gcMallocBytes = 0;
-
- /* Drop atoms held by the property cache, and clear property weak links. */
- js_DisablePropertyCache(cx);
- js_FlushPropertyCache(cx);
-#ifdef DEBUG_brendan
- { extern void js_DumpScopeMeters(JSRuntime *rt);
- js_DumpScopeMeters(rt);
- }
-#endif
-
-restart:
- rt->gcNumber++;
-
- /*
- * Mark phase.
- */
- JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_marker, cx);
- if (rt->gcLocksHash)
- JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_marker, cx);
- js_MarkAtomState(&rt->atomState, gcflags, gc_mark_atom_key_thing, cx);
- js_MarkWatchPoints(rt);
- iter = NULL;
- while ((acx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL) {
- /*
- * Iterate frame chain and dormant chains. Temporarily tack current
- * frame onto the head of the dormant list to ease iteration.
- *
- * (NB: see comment on this whole "dormant" thing in js_Execute.)
- */
- chain = acx->fp;
- if (chain) {
- JS_ASSERT(!chain->dormantNext);
- chain->dormantNext = acx->dormantFrameChain;
- } else {
- chain = acx->dormantFrameChain;
- }
-
- for (fp = chain; fp; fp = chain = chain->dormantNext) {
- do {
- if (fp->callobj)
- GC_MARK(cx, fp->callobj, "call object", NULL);
- if (fp->argsobj)
- GC_MARK(cx, fp->argsobj, "arguments object", NULL);
- if (fp->varobj)
- GC_MARK(cx, fp->varobj, "variables object", NULL);
- if (fp->script) {
- js_MarkScript(cx, fp->script, NULL);
- if (fp->spbase) {
- /*
- * Don't mark what has not been pushed yet, or what
- * has been popped already.
- */
- depth = fp->script->depth;
- nslots = (JS_UPTRDIFF(fp->sp, fp->spbase)
- < depth * sizeof(jsval))
- ? (uintN)(fp->sp - fp->spbase)
- : depth;
- GC_MARK_JSVALS(cx, nslots, fp->spbase, "operand");
- }
- }
- GC_MARK(cx, fp->thisp, "this", NULL);
- if (fp->argv) {
- nslots = fp->argc;
- if (fp->fun && fp->fun->nargs > nslots)
- nslots = fp->fun->nargs;
- GC_MARK_JSVALS(cx, nslots, fp->argv, "arg");
- }
- if (JSVAL_IS_GCTHING(fp->rval))
- GC_MARK(cx, JSVAL_TO_GCTHING(fp->rval), "rval", NULL);
- if (fp->vars)
- GC_MARK_JSVALS(cx, fp->nvars, fp->vars, "var");
- GC_MARK(cx, fp->scopeChain, "scope chain", NULL);
- if (fp->sharpArray)
- GC_MARK(cx, fp->sharpArray, "sharp array", NULL);
-
- if (fp->objAtomMap) {
- JSAtom **vector, *atom;
-
- nslots = fp->objAtomMap->length;
- vector = fp->objAtomMap->vector;
- for (i = 0; i < nslots; i++) {
- atom = vector[i];
- if (atom)
- GC_MARK_ATOM(cx, atom, NULL);
- }
- }
- } while ((fp = fp->down) != NULL);
- }
-
- /* Cleanup temporary "dormant" linkage. */
- if (acx->fp)
- acx->fp->dormantNext = NULL;
-
- /* Mark other roots-by-definition in acx. */
- GC_MARK(cx, acx->globalObject, "global object", NULL);
- GC_MARK(cx, acx->newborn[GCX_OBJECT], "newborn object", NULL);
- GC_MARK(cx, acx->newborn[GCX_STRING], "newborn string", NULL);
- GC_MARK(cx, acx->newborn[GCX_DOUBLE], "newborn double", NULL);
- GC_MARK(cx, acx->newborn[GCX_MUTABLE_STRING], "newborn mutable string",
- NULL);
- for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++)
- GC_MARK(cx, acx->newborn[i], "newborn external string", NULL);
- if (acx->lastAtom)
- GC_MARK_ATOM(cx, acx->lastAtom, NULL);
-#if JS_HAS_EXCEPTIONS
- if (acx->throwing && JSVAL_IS_GCTHING(acx->exception))
- GC_MARK(cx, JSVAL_TO_GCTHING(acx->exception), "exception", NULL);
-#endif
-#if JS_HAS_LVALUE_RETURN
- if (acx->rval2set && JSVAL_IS_GCTHING(acx->rval2))
- GC_MARK(cx, JSVAL_TO_GCTHING(acx->rval2), "rval2", NULL);
-#endif
-
- for (sh = acx->stackHeaders; sh; sh = sh->down) {
- METER(rt->gcStats.stackseg++);
- METER(rt->gcStats.segslots += sh->nslots);
- GC_MARK_JSVALS(cx, sh->nslots, JS_STACK_SEGMENT(sh), "stack");
- }
- }
-
- if (rt->gcCallback)
- (void) rt->gcCallback(cx, JSGC_MARK_END);
-
- /*
- * Sweep phase.
- * Finalize as we sweep, outside of rt->gcLock, but with rt->gcRunning set
- * so that any attempt to allocate a GC-thing from a finalizer will fail,
- * rather than nest badly and leave the unmarked newborn to be swept.
- */
- js_SweepAtomState(&rt->atomState);
- js_SweepScopeProperties(rt);
- js_SweepScriptFilenames(rt);
- for (a = rt->gcArenaPool.first.next; a; a = a->next) {
- flagp = (uint8 *) a->base;
- split = (uint8 *) FIRST_THING_PAGE(a);
- limit = (JSGCThing *) a->avail;
- for (thing = (JSGCThing *) split; thing < limit; thing++) {
- if (((jsuword)thing & GC_PAGE_MASK) == 0) {
- flagp++;
- thing++;
- }
- flags = *flagp;
- if (flags & GCF_MARK) {
- *flagp &= ~GCF_MARK;
- } else if (!(flags & (GCF_LOCKMASK | GCF_FINAL))) {
- /* Call the finalizer with GCF_FINAL ORed into flags. */
- type = flags & GCF_TYPEMASK;
- finalizer = gc_finalizers[type];
- if (finalizer) {
- *flagp = (uint8)(flags | GCF_FINAL);
- if (type >= GCX_EXTERNAL_STRING)
- js_PurgeDeflatedStringCache((JSString *)thing);
- finalizer(cx, thing);
- }
-
- /* Set flags to GCF_FINAL, signifying that thing is free. */
- *flagp = GCF_FINAL;
-
- JS_ASSERT(rt->gcBytes >= sizeof(JSGCThing) + sizeof(uint8));
- rt->gcBytes -= sizeof(JSGCThing) + sizeof(uint8);
- }
- if (++flagp == split)
- flagp += GC_THINGS_SIZE;
- }
- }
-
- /*
- * Free phase.
- * Free any unused arenas and rebuild the JSGCThing freelist.
- */
- ap = &rt->gcArenaPool.first.next;
- a = *ap;
- if (!a)
- goto out;
- all_clear = JS_TRUE;
- flp = oflp = &rt->gcFreeList;
- *flp = NULL;
- METER(rt->gcStats.freelen = 0);
-
- do {
- flagp = (uint8 *) a->base;
- split = (uint8 *) FIRST_THING_PAGE(a);
- limit = (JSGCThing *) a->avail;
- for (thing = (JSGCThing *) split; thing < limit; thing++) {
- if (((jsuword)thing & GC_PAGE_MASK) == 0) {
- flagp++;
- thing++;
- }
- if (*flagp != GCF_FINAL) {
- all_clear = JS_FALSE;
- } else {
- thing->flagp = flagp;
- *flp = thing;
- flp = &thing->next;
- METER(rt->gcStats.freelen++);
- }
- if (++flagp == split)
- flagp += GC_THINGS_SIZE;
- }
-
- if (all_clear) {
- JS_ARENA_DESTROY(&rt->gcArenaPool, a, ap);
- flp = oflp;
- METER(rt->gcStats.afree++);
- } else {
- ap = &a->next;
- all_clear = JS_TRUE;
- oflp = flp;
- }
- } while ((a = *ap) != NULL);
-
- /* Terminate the new freelist. */
- *flp = NULL;
-
- if (rt->gcCallback)
- (void) rt->gcCallback(cx, JSGC_FINALIZE_END);
-#ifdef DEBUG_brendan
- { extern void DumpSrcNoteSizeHist();
- DumpSrcNoteSizeHist();
- }
-#endif
-
-out:
- JS_LOCK_GC(rt);
- if (rt->gcLevel > 1) {
- rt->gcLevel = 1;
- JS_UNLOCK_GC(rt);
- goto restart;
- }
- js_EnablePropertyCache(cx);
- rt->gcLevel = 0;
- rt->gcLastBytes = rt->gcBytes;
- rt->gcPoke = rt->gcRunning = JS_FALSE;
-
-#ifdef JS_THREADSAFE
- /* If we were invoked during a request, pay back the temporary debit. */
- if (requestDebit)
- rt->requestCount += requestDebit;
- rt->gcThread = 0;
- JS_NOTIFY_GC_DONE(rt);
- if (!(gcflags & GC_ALREADY_LOCKED))
- JS_UNLOCK_GC(rt);
-#endif
-
- if (rt->gcCallback) {
- if (gcflags & GC_ALREADY_LOCKED)
- JS_UNLOCK_GC(rt);
- (void) rt->gcCallback(cx, JSGC_END);
- if (gcflags & GC_ALREADY_LOCKED)
- JS_LOCK_GC(rt);
- }
-}
diff --git a/src/extension/script/js/jsgc.h b/src/extension/script/js/jsgc.h
deleted file mode 100644
index f501aca23..000000000
--- a/src/extension/script/js/jsgc.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsgc_h___
-#define jsgc_h___
-/*
- * JS Garbage Collector.
- */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-#include "jsdhash.h"
-
-JS_BEGIN_EXTERN_C
-
-/* GC thing type indexes. */
-#define GCX_OBJECT 0 /* JSObject */
-#define GCX_STRING 1 /* JSString */
-#define GCX_DOUBLE 2 /* jsdouble */
-#define GCX_MUTABLE_STRING 3 /* JSString that's mutable --
- single-threaded only! */
-#define GCX_EXTERNAL_STRING 4 /* JSString w/ external chars */
-#define GCX_NTYPES_LOG2 3 /* type index bits */
-#define GCX_NTYPES JS_BIT(GCX_NTYPES_LOG2)
-
-/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */
-#define GCF_TYPEMASK JS_BITMASK(GCX_NTYPES_LOG2)
-#define GCF_MARK JS_BIT(GCX_NTYPES_LOG2)
-#define GCF_FINAL JS_BIT(GCX_NTYPES_LOG2 + 1)
-#define GCF_LOCKSHIFT (GCX_NTYPES_LOG2 + 2) /* lock bit shift and mask */
-#define GCF_LOCKMASK (JS_BITMASK(8 - GCF_LOCKSHIFT) << GCF_LOCKSHIFT)
-#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */
-
-/* Pseudo-flag that modifies GCX_STRING to make GCX_MUTABLE_STRING. */
-#define GCF_MUTABLE 2
-
-#if (GCX_STRING | GCF_MUTABLE) != GCX_MUTABLE_STRING
-# error "mutable string type index botch!"
-#endif
-
-extern uint8 *
-js_GetGCThingFlags(void *thing);
-
-/* These are compatible with JSDHashEntryStub. */
-struct JSGCRootHashEntry {
- JSDHashEntryHdr hdr;
- void *root;
- const char *name;
-};
-
-struct JSGCLockHashEntry {
- JSDHashEntryHdr hdr;
- const JSGCThing *thing;
- uint32 count;
-};
-
-#if 1
-/*
- * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
- * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg
- * ignored", etc.
- */
-#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
-#else
-#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
-#endif
-
-extern intN
-js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
- JSStringFinalizeOp newop);
-
-extern JSBool
-js_InitGC(JSRuntime *rt, uint32 maxbytes);
-
-extern void
-js_FinishGC(JSRuntime *rt);
-
-extern JSBool
-js_AddRoot(JSContext *cx, void *rp, const char *name);
-
-extern JSBool
-js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
-
-extern JSBool
-js_RemoveRoot(JSRuntime *rt, void *rp);
-
-extern void *
-js_AllocGCThing(JSContext *cx, uintN flags);
-
-extern JSBool
-js_LockGCThing(JSContext *cx, void *thing);
-
-extern JSBool
-js_LockGCThingRT(JSRuntime *rt, void *thing);
-
-extern JSBool
-js_UnlockGCThingRT(JSRuntime *rt, void *thing);
-
-extern JSBool
-js_IsAboutToBeFinalized(JSContext *cx, void *thing);
-
-extern void
-js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg);
-
-/* We avoid a large number of unnecessary calls by doing the flag check first */
-#define GC_MARK_ATOM(cx, atom, arg) \
- JS_BEGIN_MACRO \
- if (!((atom)->flags & ATOM_MARK)) \
- js_MarkAtom(cx, atom, arg); \
- JS_END_MACRO
-
-extern void
-js_MarkGCThing(JSContext *cx, void *thing, void *arg);
-
-#ifdef GC_MARK_DEBUG
-
-typedef struct GCMarkNode GCMarkNode;
-
-struct GCMarkNode {
- void *thing;
- const char *name;
- GCMarkNode *next;
- GCMarkNode *prev;
-};
-
-#define GC_MARK(_cx, _thing, _name, _prev) \
- JS_BEGIN_MACRO \
- GCMarkNode _node; \
- _node.thing = _thing; \
- _node.name = _name; \
- _node.next = NULL; \
- _node.prev = _prev; \
- if (_prev) ((GCMarkNode *)(_prev))->next = &_node; \
- js_MarkGCThing(_cx, _thing, &_node); \
- JS_END_MACRO
-
-#else /* !GC_MARK_DEBUG */
-
-#define GC_MARK(cx, thing, name, prev) js_MarkGCThing(cx, thing, NULL)
-
-#endif /* !GC_MARK_DEBUG */
-
-/*
- * Flags to modify how a GC marks and sweeps:
- * GC_KEEP_ATOMS Don't sweep unmarked atoms, they may be in use by the
- * compiler, or by an API function that calls js_Atomize,
- * when the GC is called from js_AllocGCThing, due to a
- * malloc failure or runtime GC-thing limit.
- * GC_LAST_CONTEXT Called from js_DestroyContext for last JSContext in a
- * JSRuntime, when it is imperative that rt->gcPoke gets
- * cleared early in js_GC, if it is set.
- * GC_ALREADY_LOCKED rt->gcLock is already held on entry to js_GC, and kept
- * on return to its caller.
- */
-#define GC_KEEP_ATOMS 0x1
-#define GC_LAST_CONTEXT 0x2
-#define GC_ALREADY_LOCKED 0x4
-
-extern void
-js_ForceGC(JSContext *cx, uintN gcflags);
-
-extern void
-js_GC(JSContext *cx, uintN gcflags);
-
-#ifdef JS_GCMETER
-
-typedef struct JSGCStats {
- uint32 alloc; /* number of allocation attempts */
- uint32 freelen; /* gcFreeList length */
- uint32 recycle; /* number of things recycled through gcFreeList */
- uint32 retry; /* allocation attempt retries after running the GC */
- uint32 fail; /* allocation failures */
- uint32 finalfail; /* finalizer calls allocator failures */
- uint32 lock; /* valid lock calls */
- uint32 unlock; /* valid unlock calls */
- uint32 stuck; /* stuck reference counts seen by lock calls */
- uint32 unstuck; /* unlock calls that saw a stuck lock count */
- uint32 depth; /* mark recursion depth */
- uint32 maxdepth; /* maximum mark recursion depth */
- uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */
- uint32 poke; /* number of potentially useful GC calls */
- uint32 nopoke; /* useless GC calls where js_PokeGC was not set */
- uint32 afree; /* thing arenas freed so far */
- uint32 stackseg; /* total extraordinary stack segments scanned */
- uint32 segslots; /* total stack segment jsval slots scanned */
-} JSGCStats;
-
-extern void
-js_DumpGCStats(JSRuntime *rt, FILE *fp);
-
-#endif /* JS_GCMETER */
-
-JS_END_EXTERN_C
-
-#endif /* jsgc_h___ */
diff --git a/src/extension/script/js/jshash.c b/src/extension/script/js/jshash.c
deleted file mode 100644
index 3382daadb..000000000
--- a/src/extension/script/js/jshash.c
+++ /dev/null
@@ -1,479 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * PR hash table package.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsbit.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jshash.h" /* Added by JSIFY */
-
-/* Compute the number of buckets in ht */
-#define NBUCKETS(ht) JS_BIT(JS_HASH_BITS - (ht)->shift)
-
-/* The smallest table has 16 buckets */
-#define MINBUCKETSLOG2 4
-#define MINBUCKETS JS_BIT(MINBUCKETSLOG2)
-
-/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
-#define OVERLOADED(n) ((n) - ((n) >> 3))
-
-/* Compute the number of entries below which we shrink the table by half */
-#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
-
-/*
-** Stubs for default hash allocator ops.
-*/
-static void *
-DefaultAllocTable(void *pool, size_t size)
-{
- return malloc(size);
-}
-
-static void
-DefaultFreeTable(void *pool, void *item)
-{
- free(item);
-}
-
-static JSHashEntry *
-DefaultAllocEntry(void *pool, const void *key)
-{
- return (JSHashEntry*) malloc(sizeof(JSHashEntry));
-}
-
-static void
-DefaultFreeEntry(void *pool, JSHashEntry *he, uintN flag)
-{
- if (flag == HT_FREE_ENTRY)
- free(he);
-}
-
-static JSHashAllocOps defaultHashAllocOps = {
- DefaultAllocTable, DefaultFreeTable,
- DefaultAllocEntry, DefaultFreeEntry
-};
-
-JS_PUBLIC_API(JSHashTable *)
-JS_NewHashTable(uint32 n, JSHashFunction keyHash,
- JSHashComparator keyCompare, JSHashComparator valueCompare,
- JSHashAllocOps *allocOps, void *allocPriv)
-{
- JSHashTable *ht;
- size_t nb;
-
- if (n <= MINBUCKETS) {
- n = MINBUCKETSLOG2;
- } else {
- n = JS_CeilingLog2(n);
- if ((int32)n < 0)
- return NULL;
- }
-
- if (!allocOps) allocOps = &defaultHashAllocOps;
-
- ht = (JSHashTable*) (*allocOps->allocTable)(allocPriv, sizeof *ht);
- if (!ht)
- return NULL;
- memset(ht, 0, sizeof *ht);
- ht->shift = JS_HASH_BITS - n;
- n = JS_BIT(n);
-#if defined _MSC_VER && _MSC_VER <= 800
- if (n > 16000) {
- (*allocOps->freeTable)(allocPriv, ht);
- return NULL;
- }
-#endif /* WIN16 */
- nb = n * sizeof(JSHashEntry *);
- ht->buckets = (JSHashEntry**) (*allocOps->allocTable)(allocPriv, nb);
- if (!ht->buckets) {
- (*allocOps->freeTable)(allocPriv, ht);
- return NULL;
- }
- memset(ht->buckets, 0, nb);
-
- ht->keyHash = keyHash;
- ht->keyCompare = keyCompare;
- ht->valueCompare = valueCompare;
- ht->allocOps = allocOps;
- ht->allocPriv = allocPriv;
- return ht;
-}
-
-JS_PUBLIC_API(void)
-JS_HashTableDestroy(JSHashTable *ht)
-{
- uint32 i, n;
- JSHashEntry *he, **hep;
- JSHashAllocOps *allocOps = ht->allocOps;
- void *allocPriv = ht->allocPriv;
-
- n = NBUCKETS(ht);
- for (i = 0; i < n; i++) {
- hep = &ht->buckets[i];
- while ((he = *hep) != NULL) {
- *hep = he->next;
- (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
- }
- }
-#ifdef DEBUG
- memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
-#endif
- (*allocOps->freeTable)(allocPriv, ht->buckets);
-#ifdef DEBUG
- memset(ht, 0xDB, sizeof *ht);
-#endif
- (*allocOps->freeTable)(allocPriv, ht);
-}
-
-/*
-** Multiplicative hash, from Knuth 6.4.
-*/
-JS_PUBLIC_API(JSHashEntry **)
-JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key)
-{
- JSHashEntry *he, **hep, **hep0;
- JSHashNumber h;
-
-#ifdef HASHMETER
- ht->nlookups++;
-#endif
- h = keyHash * JS_GOLDEN_RATIO;
- h >>= ht->shift;
- hep = hep0 = &ht->buckets[h];
- while ((he = *hep) != NULL) {
- if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
- /* Move to front of chain if not already there */
- if (hep != hep0) {
- *hep = he->next;
- he->next = *hep0;
- *hep0 = he;
- }
- return hep0;
- }
- hep = &he->next;
-#ifdef HASHMETER
- ht->nsteps++;
-#endif
- }
- return hep;
-}
-
-JS_PUBLIC_API(JSHashEntry *)
-JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep,
- JSHashNumber keyHash, const void *key, void *value)
-{
- uint32 i, n;
- JSHashEntry *he, *next, **oldbuckets;
- size_t nb;
-
- /* Grow the table if it is overloaded */
- n = NBUCKETS(ht);
- if (ht->nentries >= OVERLOADED(n)) {
- oldbuckets = ht->buckets;
-#if defined _MSC_VER && _MSC_VER <= 800
- if (2 * n > 16000)
- return NULL;
-#endif /* WIN16 */
- nb = 2 * n * sizeof(JSHashEntry *);
- ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb);
- if (!ht->buckets) {
- ht->buckets = oldbuckets;
- return NULL;
- }
- memset(ht->buckets, 0, nb);
-#ifdef HASHMETER
- ht->ngrows++;
-#endif
- ht->shift--;
-
- for (i = 0; i < n; i++) {
- for (he = oldbuckets[i]; he; he = next) {
- next = he->next;
- hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
- JS_ASSERT(*hep == NULL);
- he->next = NULL;
- *hep = he;
- }
- }
-#ifdef DEBUG
- memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
-#endif
- (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
- hep = JS_HashTableRawLookup(ht, keyHash, key);
- }
-
- /* Make a new key value entry */
- he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
- if (!he)
- return NULL;
- he->keyHash = keyHash;
- he->key = key;
- he->value = value;
- he->next = *hep;
- *hep = he;
- ht->nentries++;
- return he;
-}
-
-JS_PUBLIC_API(JSHashEntry *)
-JS_HashTableAdd(JSHashTable *ht, const void *key, void *value)
-{
- JSHashNumber keyHash;
- JSHashEntry *he, **hep;
-
- keyHash = (*ht->keyHash)(key);
- hep = JS_HashTableRawLookup(ht, keyHash, key);
- if ((he = *hep) != NULL) {
- /* Hit; see if values match */
- if ((*ht->valueCompare)(he->value, value)) {
- /* key,value pair is already present in table */
- return he;
- }
- if (he->value)
- (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
- he->value = value;
- return he;
- }
- return JS_HashTableRawAdd(ht, hep, keyHash, key, value);
-}
-
-JS_PUBLIC_API(void)
-JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he)
-{
- uint32 i, n;
- JSHashEntry *next, **oldbuckets;
- size_t nb;
-
- *hep = he->next;
- (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
-
- /* Shrink table if it's underloaded */
- n = NBUCKETS(ht);
- if (--ht->nentries < UNDERLOADED(n)) {
- oldbuckets = ht->buckets;
- nb = n * sizeof(JSHashEntry*) / 2;
- ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb);
- if (!ht->buckets) {
- ht->buckets = oldbuckets;
- return;
- }
- memset(ht->buckets, 0, nb);
-#ifdef HASHMETER
- ht->nshrinks++;
-#endif
- ht->shift++;
-
- for (i = 0; i < n; i++) {
- for (he = oldbuckets[i]; he; he = next) {
- next = he->next;
- hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
- JS_ASSERT(*hep == NULL);
- he->next = NULL;
- *hep = he;
- }
- }
-#ifdef DEBUG
- memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
-#endif
- (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
- }
-}
-
-JS_PUBLIC_API(JSBool)
-JS_HashTableRemove(JSHashTable *ht, const void *key)
-{
- JSHashNumber keyHash;
- JSHashEntry *he, **hep;
-
- keyHash = (*ht->keyHash)(key);
- hep = JS_HashTableRawLookup(ht, keyHash, key);
- if ((he = *hep) == NULL)
- return JS_FALSE;
-
- /* Hit; remove element */
- JS_HashTableRawRemove(ht, hep, he);
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(void *)
-JS_HashTableLookup(JSHashTable *ht, const void *key)
-{
- JSHashNumber keyHash;
- JSHashEntry *he, **hep;
-
- keyHash = (*ht->keyHash)(key);
- hep = JS_HashTableRawLookup(ht, keyHash, key);
- if ((he = *hep) != NULL) {
- return he->value;
- }
- return NULL;
-}
-
-/*
-** Iterate over the entries in the hash table calling func for each
-** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP).
-** Return a count of the number of elements scanned.
-*/
-JS_PUBLIC_API(int)
-JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg)
-{
- JSHashEntry *he, **hep;
- uint32 i, nbuckets;
- int rv, n = 0;
- JSHashEntry *todo = NULL;
-
- nbuckets = NBUCKETS(ht);
- for (i = 0; i < nbuckets; i++) {
- hep = &ht->buckets[i];
- while ((he = *hep) != NULL) {
- rv = (*f)(he, n, arg);
- n++;
- if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
- *hep = he->next;
- if (rv & HT_ENUMERATE_REMOVE) {
- he->next = todo;
- todo = he;
- }
- } else {
- hep = &he->next;
- }
- if (rv & HT_ENUMERATE_STOP) {
- goto out;
- }
- }
- }
-
-out:
- hep = &todo;
- while ((he = *hep) != NULL) {
- JS_HashTableRawRemove(ht, hep, he);
- }
- return n;
-}
-
-#ifdef HASHMETER
-#include <math.h>
-#include <stdio.h>
-
-JS_PUBLIC_API(void)
-JS_HashTableDumpMeter(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
-{
- double sqsum, mean, variance, sigma;
- uint32 nchains, nbuckets, nentries;
- uint32 i, n, maxChain, maxChainLen;
- JSHashEntry *he;
-
- sqsum = 0;
- nchains = 0;
- maxChainLen = 0;
- nbuckets = NBUCKETS(ht);
- for (i = 0; i < nbuckets; i++) {
- he = ht->buckets[i];
- if (!he)
- continue;
- nchains++;
- for (n = 0; he; he = he->next)
- n++;
- sqsum += n * n;
- if (n > maxChainLen) {
- maxChainLen = n;
- maxChain = i;
- }
- }
- nentries = ht->nentries;
- mean = (double)nentries / nchains;
- variance = nchains * sqsum - nentries * nentries;
- if (variance < 0 || nchains == 1)
- variance = 0;
- else
- variance /= nchains * (nchains - 1);
- sigma = sqrt(variance);
-
- fprintf(fp, "\nHash table statistics:\n");
- fprintf(fp, " number of lookups: %u\n", ht->nlookups);
- fprintf(fp, " number of entries: %u\n", ht->nentries);
- fprintf(fp, " number of grows: %u\n", ht->ngrows);
- fprintf(fp, " number of shrinks: %u\n", ht->nshrinks);
- fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps
- / ht->nlookups);
- fprintf(fp, "mean hash chain length: %g\n", mean);
- fprintf(fp, " standard deviation: %g\n", sigma);
- fprintf(fp, " max hash chain length: %u\n", maxChainLen);
- fprintf(fp, " max hash chain: [%u]\n", maxChain);
-
- for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
- if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
- break;
-}
-#endif /* HASHMETER */
-
-JS_PUBLIC_API(int)
-JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
-{
- int count;
-
- count = JS_HashTableEnumerateEntries(ht, dump, fp);
-#ifdef HASHMETER
- JS_HashTableDumpMeter(ht, dump, fp);
-#endif
- return count;
-}
-
-JS_PUBLIC_API(JSHashNumber)
-JS_HashString(const void *key)
-{
- JSHashNumber h;
- const unsigned char *s;
-
- h = 0;
- for (s = (const unsigned char *)key; *s; s++)
- h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s;
- return h;
-}
-
-JS_PUBLIC_API(int)
-JS_CompareValues(const void *v1, const void *v2)
-{
- return v1 == v2;
-}
diff --git a/src/extension/script/js/jshash.h b/src/extension/script/js/jshash.h
deleted file mode 100644
index 85e3cf811..000000000
--- a/src/extension/script/js/jshash.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jshash_h___
-#define jshash_h___
-/*
- * API to portable hash table code.
- */
-#include <stddef.h>
-#include <stdio.h>
-#include "jstypes.h"
-#include "jscompat.h"
-
-JS_BEGIN_EXTERN_C
-
-typedef uint32 JSHashNumber;
-typedef struct JSHashEntry JSHashEntry;
-typedef struct JSHashTable JSHashTable;
-
-#define JS_HASH_BITS 32
-#define JS_GOLDEN_RATIO 0x9E3779B9U
-
-typedef JSHashNumber (* JS_DLL_CALLBACK JSHashFunction)(const void *key);
-typedef intN (* JS_DLL_CALLBACK JSHashComparator)(const void *v1, const void *v2);
-typedef intN (* JS_DLL_CALLBACK JSHashEnumerator)(JSHashEntry *he, intN i, void *arg);
-
-/* Flag bits in JSHashEnumerator's return value */
-#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
-#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
-#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
-#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
-
-typedef struct JSHashAllocOps {
- void * (*allocTable)(void *pool, size_t size);
- void (*freeTable)(void *pool, void *item);
- JSHashEntry * (*allocEntry)(void *pool, const void *key);
- void (*freeEntry)(void *pool, JSHashEntry *he, uintN flag);
-} JSHashAllocOps;
-
-#define HT_FREE_VALUE 0 /* just free the entry's value */
-#define HT_FREE_ENTRY 1 /* free value and entire entry */
-
-struct JSHashEntry {
- JSHashEntry *next; /* hash chain linkage */
- JSHashNumber keyHash; /* key hash function result */
- const void *key; /* ptr to opaque key */
- void *value; /* ptr to opaque value */
-};
-
-struct JSHashTable {
- JSHashEntry **buckets; /* vector of hash buckets */
- uint32 nentries; /* number of entries in table */
- uint32 shift; /* multiplicative hash shift */
- JSHashFunction keyHash; /* key hash function */
- JSHashComparator keyCompare; /* key comparison function */
- JSHashComparator valueCompare; /* value comparison function */
- JSHashAllocOps *allocOps; /* allocation operations */
- void *allocPriv; /* allocation private data */
-#ifdef HASHMETER
- uint32 nlookups; /* total number of lookups */
- uint32 nsteps; /* number of hash chains traversed */
- uint32 ngrows; /* number of table expansions */
- uint32 nshrinks; /* number of table contractions */
-#endif
-};
-
-/*
- * Create a new hash table.
- * If allocOps is null, use default allocator ops built on top of malloc().
- */
-extern JS_PUBLIC_API(JSHashTable *)
-JS_NewHashTable(uint32 n, JSHashFunction keyHash,
- JSHashComparator keyCompare, JSHashComparator valueCompare,
- JSHashAllocOps *allocOps, void *allocPriv);
-
-extern JS_PUBLIC_API(void)
-JS_HashTableDestroy(JSHashTable *ht);
-
-/* Low level access methods */
-extern JS_PUBLIC_API(JSHashEntry **)
-JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key);
-
-extern JS_PUBLIC_API(JSHashEntry *)
-JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep, JSHashNumber keyHash,
- const void *key, void *value);
-
-extern JS_PUBLIC_API(void)
-JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he);
-
-/* Higher level access methods */
-extern JS_PUBLIC_API(JSHashEntry *)
-JS_HashTableAdd(JSHashTable *ht, const void *key, void *value);
-
-extern JS_PUBLIC_API(JSBool)
-JS_HashTableRemove(JSHashTable *ht, const void *key);
-
-extern JS_PUBLIC_API(intN)
-JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg);
-
-extern JS_PUBLIC_API(void *)
-JS_HashTableLookup(JSHashTable *ht, const void *key);
-
-extern JS_PUBLIC_API(intN)
-JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp);
-
-/* General-purpose C string hash function. */
-extern JS_PUBLIC_API(JSHashNumber)
-JS_HashString(const void *key);
-
-/* Stub function just returns v1 == v2 */
-extern JS_PUBLIC_API(intN)
-JS_CompareValues(const void *v1, const void *v2);
-
-JS_END_EXTERN_C
-
-#endif /* jshash_h___ */
diff --git a/src/extension/script/js/jsinterp.c b/src/extension/script/js/jsinterp.c
deleted file mode 100644
index 60f39b3ce..000000000
--- a/src/extension/script/js/jsinterp.c
+++ /dev/null
@@ -1,4284 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* build on macs with low memory */
-#if defined(XP_MAC) && defined(MOZ_MAC_LOWMEM)
-#pragma optimization_level 1
-#endif
-
-/*
- * JavaScript bytecode interpreter.
- */
-#include "jsstddef.h"
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jsbool.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-#if JS_HAS_JIT
-#include "jsjit.h"
-#endif
-
-#ifdef DEBUG
-#define ASSERT_CACHE_IS_EMPTY(cache) \
- JS_BEGIN_MACRO \
- JSPropertyCacheEntry *end_, *pce_, entry_; \
- JSPropertyCache *cache_ = (cache); \
- JS_ASSERT(cache_->empty); \
- end_ = &cache_->table[PROPERTY_CACHE_SIZE]; \
- for (pce_ = &cache_->table[0]; pce_ < end_; pce_++) { \
- PCE_LOAD(cache_, pce_, entry_); \
- JS_ASSERT(!PCE_OBJECT(entry_)); \
- JS_ASSERT(!PCE_PROPERTY(entry_)); \
- } \
- JS_END_MACRO
-#else
-#define ASSERT_CACHE_IS_EMPTY(cache) ((void)0)
-#endif
-
-void
-js_FlushPropertyCache(JSContext *cx)
-{
- JSPropertyCache *cache;
-
- cache = &cx->runtime->propertyCache;
- if (cache->empty) {
- ASSERT_CACHE_IS_EMPTY(cache);
- return;
- }
- memset(cache->table, 0, sizeof cache->table);
- cache->empty = JS_TRUE;
-#ifdef JS_PROPERTY_CACHE_METERING
- cache->flushes++;
-#endif
-}
-
-void
-js_DisablePropertyCache(JSContext *cx)
-{
- JS_ASSERT(!cx->runtime->propertyCache.disabled);
- cx->runtime->propertyCache.disabled = JS_TRUE;
-}
-
-void
-js_EnablePropertyCache(JSContext *cx)
-{
- JS_ASSERT(cx->runtime->propertyCache.disabled);
- ASSERT_CACHE_IS_EMPTY(&cx->runtime->propertyCache);
- cx->runtime->propertyCache.disabled = JS_FALSE;
-}
-
-/*
- * Class for for/in loop property iterator objects.
- */
-#define JSSLOT_ITER_STATE JSSLOT_PRIVATE
-
-static void
-prop_iterator_finalize(JSContext *cx, JSObject *obj)
-{
- jsval iter_state;
- jsval iteratee;
-
- /* Protect against stillborn iterators. */
- iter_state = obj->slots[JSSLOT_ITER_STATE];
- iteratee = obj->slots[JSSLOT_PARENT];
- if (!JSVAL_IS_NULL(iter_state) && !JSVAL_IS_PRIMITIVE(iteratee)) {
- OBJ_ENUMERATE(cx, JSVAL_TO_OBJECT(iteratee), JSENUMERATE_DESTROY,
- &iter_state, NULL);
- }
- js_RemoveRoot(cx->runtime, &obj->slots[JSSLOT_PARENT]);
-
- /* XXX force the GC to restart so we can collect iteratee, if possible,
- during the current collector activation */
- cx->runtime->gcLevel++;
-}
-
-static JSClass prop_iterator_class = {
- "PropertyIterator",
- 0,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, prop_iterator_finalize,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-/*
- * Stack macros and functions. These all use a local variable, jsval *sp, to
- * point to the next free stack slot. SAVE_SP must be called before any call
- * to a function that may invoke the interpreter. RESTORE_SP must be called
- * only after return from js_Invoke, because only js_Invoke changes fp->sp.
- */
-#define PUSH(v) (*sp++ = (v))
-#define POP() (*--sp)
-#ifdef DEBUG
-#define SAVE_SP(fp) \
- (JS_ASSERT((fp)->script || !(fp)->spbase || (sp) == (fp)->spbase), \
- (fp)->sp = sp)
-#else
-#define SAVE_SP(fp) ((fp)->sp = sp)
-#endif
-#define RESTORE_SP(fp) (sp = (fp)->sp)
-
-/*
- * Push the generating bytecode's pc onto the parallel pc stack that runs
- * depth slots below the operands.
- *
- * NB: PUSH_OPND uses sp, depth, and pc from its lexical environment. See
- * js_Interpret for these local variables' declarations and uses.
- */
-#define PUSH_OPND(v) (sp[-depth] = (jsval)pc, PUSH(v))
-#define STORE_OPND(n,v) (sp[(n)-depth] = (jsval)pc, sp[n] = (v))
-#define POP_OPND() POP()
-#define FETCH_OPND(n) (sp[n])
-
-/*
- * Push the jsdouble d using sp, depth, and pc from the lexical environment.
- * Try to convert d to a jsint that fits in a jsval, otherwise GC-alloc space
- * for it and push a reference.
- */
-#define STORE_NUMBER(cx, n, d) \
- JS_BEGIN_MACRO \
- jsint i_; \
- jsval v_; \
- \
- if (JSDOUBLE_IS_INT(d, i_) && INT_FITS_IN_JSVAL(i_)) { \
- v_ = INT_TO_JSVAL(i_); \
- } else { \
- ok = js_NewDoubleValue(cx, d, &v_); \
- if (!ok) \
- goto out; \
- } \
- STORE_OPND(n, v_); \
- JS_END_MACRO
-
-#define FETCH_NUMBER(cx, n, d) \
- JS_BEGIN_MACRO \
- jsval v_; \
- \
- v_ = FETCH_OPND(n); \
- VALUE_TO_NUMBER(cx, v_, d); \
- JS_END_MACRO
-
-#define FETCH_INT(cx, n, i) \
- JS_BEGIN_MACRO \
- jsval v_ = FETCH_OPND(n); \
- if (JSVAL_IS_INT(v_)) { \
- i = JSVAL_TO_INT(v_); \
- } else { \
- SAVE_SP(fp); \
- ok = js_ValueToECMAInt32(cx, v_, &i); \
- if (!ok) \
- goto out; \
- } \
- JS_END_MACRO
-
-#define FETCH_UINT(cx, n, ui) \
- JS_BEGIN_MACRO \
- jsval v_ = FETCH_OPND(n); \
- jsint i_; \
- if (JSVAL_IS_INT(v_) && (i_ = JSVAL_TO_INT(v_)) >= 0) { \
- ui = (uint32) i_; \
- } else { \
- SAVE_SP(fp); \
- ok = js_ValueToECMAUint32(cx, v_, &ui); \
- if (!ok) \
- goto out; \
- } \
- JS_END_MACRO
-
-/*
- * Optimized conversion macros that test for the desired type in v before
- * homing sp and calling a conversion function.
- */
-#define VALUE_TO_NUMBER(cx, v, d) \
- JS_BEGIN_MACRO \
- if (JSVAL_IS_INT(v)) { \
- d = (jsdouble)JSVAL_TO_INT(v); \
- } else if (JSVAL_IS_DOUBLE(v)) { \
- d = *JSVAL_TO_DOUBLE(v); \
- } else { \
- SAVE_SP(fp); \
- ok = js_ValueToNumber(cx, v, &d); \
- if (!ok) \
- goto out; \
- } \
- JS_END_MACRO
-
-#define POP_BOOLEAN(cx, v, b) \
- JS_BEGIN_MACRO \
- v = FETCH_OPND(-1); \
- if (v == JSVAL_NULL) { \
- b = JS_FALSE; \
- } else if (JSVAL_IS_BOOLEAN(v)) { \
- b = JSVAL_TO_BOOLEAN(v); \
- } else { \
- SAVE_SP(fp); \
- ok = js_ValueToBoolean(cx, v, &b); \
- if (!ok) \
- goto out; \
- } \
- sp--; \
- JS_END_MACRO
-
-#define VALUE_TO_OBJECT(cx, v, obj) \
- JS_BEGIN_MACRO \
- if (JSVAL_IS_OBJECT(v) && v != JSVAL_NULL) { \
- obj = JSVAL_TO_OBJECT(v); \
- } else { \
- SAVE_SP(fp); \
- obj = js_ValueToNonNullObject(cx, v); \
- if (!obj) { \
- ok = JS_FALSE; \
- goto out; \
- } \
- } \
- JS_END_MACRO
-
-#if JS_BUG_VOID_TOSTRING
-#define CHECK_VOID_TOSTRING(cx, v) \
- if (JSVAL_IS_VOID(v)) { \
- JSString *str_; \
- str_ = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); \
- v = STRING_TO_JSVAL(str_); \
- }
-#else
-#define CHECK_VOID_TOSTRING(cx, v) ((void)0)
-#endif
-
-#if JS_BUG_EAGER_TOSTRING
-#define CHECK_EAGER_TOSTRING(hint) (hint = JSTYPE_STRING)
-#else
-#define CHECK_EAGER_TOSTRING(hint) ((void)0)
-#endif
-
-#define VALUE_TO_PRIMITIVE(cx, v, hint, vp) \
- JS_BEGIN_MACRO \
- if (JSVAL_IS_PRIMITIVE(v)) { \
- CHECK_VOID_TOSTRING(cx, v); \
- *vp = v; \
- } else { \
- SAVE_SP(fp); \
- CHECK_EAGER_TOSTRING(hint); \
- ok = OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), hint, vp); \
- if (!ok) \
- goto out; \
- } \
- JS_END_MACRO
-
-JS_FRIEND_API(jsval *)
-js_AllocRawStack(JSContext *cx, uintN nslots, void **markp)
-{
- jsval *sp;
-
- if (markp)
- *markp = JS_ARENA_MARK(&cx->stackPool);
- JS_ARENA_ALLOCATE_CAST(sp, jsval *, &cx->stackPool, nslots * sizeof(jsval));
- if (!sp) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_STACK_OVERFLOW,
- (cx->fp && cx->fp->fun)
- ? JS_GetFunctionName(cx->fp->fun)
- : "script");
- }
- return sp;
-}
-
-JS_FRIEND_API(void)
-js_FreeRawStack(JSContext *cx, void *mark)
-{
- JS_ARENA_RELEASE(&cx->stackPool, mark);
-}
-
-JS_FRIEND_API(jsval *)
-js_AllocStack(JSContext *cx, uintN nslots, void **markp)
-{
- jsval *sp, *vp, *end;
- JSArena *a;
- JSStackHeader *sh;
- JSStackFrame *fp;
-
- /* Callers don't check for zero nslots: we do to avoid empty segments. */
- if (nslots == 0) {
- *markp = NULL;
- return JS_ARENA_MARK(&cx->stackPool);
- }
-
- /* Allocate 2 extra slots for the stack segment header we'll likely need. */
- sp = js_AllocRawStack(cx, 2 + nslots, markp);
- if (!sp)
- return NULL;
-
- /* Try to avoid another header if we can piggyback on the last segment. */
- a = cx->stackPool.current;
- sh = cx->stackHeaders;
- if (sh && JS_STACK_SEGMENT(sh) + sh->nslots == sp) {
- /* Extend the last stack segment, give back the 2 header slots. */
- sh->nslots += nslots;
- a->avail -= 2 * sizeof(jsval);
- } else {
- /*
- * Need a new stack segment, so we must initialize unused slots in the
- * current frame. See js_GC, just before marking the "operand" jsvals,
- * where we scan from fp->spbase to fp->sp or through fp->script->depth
- * (whichever covers fewer slots).
- */
- fp = cx->fp;
- if (fp && fp->script && fp->spbase) {
-#ifdef DEBUG
- jsuword depthdiff = fp->script->depth * sizeof(jsval);
- JS_ASSERT(JS_UPTRDIFF(fp->sp, fp->spbase) <= depthdiff);
- JS_ASSERT(JS_UPTRDIFF(*markp, fp->spbase) >= depthdiff);
-#endif
- end = fp->spbase + fp->script->depth;
- for (vp = fp->sp; vp < end; vp++)
- *vp = JSVAL_VOID;
- }
-
- /* Allocate and push a stack segment header from the 2 extra slots. */
- sh = (JSStackHeader *)sp;
- sh->nslots = nslots;
- sh->down = cx->stackHeaders;
- cx->stackHeaders = sh;
- sp += 2;
- }
-
- return sp;
-}
-
-JS_FRIEND_API(void)
-js_FreeStack(JSContext *cx, void *mark)
-{
- JSStackHeader *sh;
- jsuword slotdiff;
-
- /* Check for zero nslots allocation special case. */
- if (!mark)
- return;
-
- /* We can assert because js_FreeStack always balances js_AllocStack. */
- sh = cx->stackHeaders;
- JS_ASSERT(sh);
-
- /* If mark is in the current segment, reduce sh->nslots, else pop sh. */
- slotdiff = JS_UPTRDIFF(mark, JS_STACK_SEGMENT(sh)) / sizeof(jsval);
- if (slotdiff < (jsuword)sh->nslots)
- sh->nslots = slotdiff;
- else
- cx->stackHeaders = sh->down;
-
- /* Release the stackPool space allocated since mark was set. */
- JS_ARENA_RELEASE(&cx->stackPool, mark);
-}
-
-/*
- * To economize on slots space in functions, the compiler records arguments and
- * local variables as shared (JSPROP_SHARED) properties with well-known getters
- * and setters: js_{Get,Set}Argument, js_{Get,Set}LocalVariable. Now, we could
- * record args and vars in lists or hash tables in function-private data, but
- * that means more duplication in code, and more data at runtime in the hash
- * table case due to round-up to powers of two, just to recapitulate the scope
- * machinery in the function object.
- *
- * What's more, for a long time (to the dawn of "Mocha" in 1995), these getters
- * and setters knew how to search active stack frames in a context to find the
- * top activation of the function f, in order to satisfy a get or set of f.a,
- * for argument a, or f.x, for local variable x. You could use f.a instead of
- * just a in function f(a) { return f.a }, for example, to return the actual
- * parameter.
- *
- * ECMA requires that we give up on this ancient extension, because it is not
- * compatible with the standard as used by real-world scripts. While Chapter
- * 16 does allow for additional properties to be defined on native objects by
- * a conforming implementation, these magic getters and setters cause f.a's
- * meaning to vary unexpectedly. Real-world scripts set f.A = 42 to define
- * "class static" (after Java) constants, for example, but if A also names an
- * arg or var in f, the constant is not available while f is active, and any
- * non-constant class-static can't be set while f is active.
- *
- * So, to label arg and var properties in functions without giving them magic
- * abilities to affect active frame stack slots, while keeping the properties
- * shared (slot-less) to save space in the common case (where no assignment
- * sets a function property with the same name as an arg or var), the setters
- * for args and vars must handle two special cases here.
- *
- * XXX functions tend to have few args and vars, so we risk O(n^2) growth here
- * XXX ECMA *really* wants args and vars to be stored in function-private data,
- * not as function object properties.
- */
-static JSBool
-SetFunctionSlot(JSContext *cx, JSObject *obj, JSPropertyOp setter, jsid id,
- jsval v)
-{
- uintN slot;
- JSObject *origobj;
- JSScope *scope;
- JSScopeProperty *sprop;
- JSString *str;
- JSBool ok;
-
- slot = (uintN) JSVAL_TO_INT(id);
- if (OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) {
- /*
- * Given a non-function object obj that has a function object in its
- * prototype chain, where an argument or local variable property named
- * by (setter, slot) is being set, override the shared property in the
- * prototype with an unshared property in obj. This situation arises
- * in real-world JS due to .prototype setting and collisions among a
- * function's "static property" names and arg or var names, believe it
- * or not.
- */
- origobj = obj;
- do {
- obj = OBJ_GET_PROTO(cx, obj);
- if (!obj)
- return JS_TRUE;
- } while (OBJ_GET_CLASS(cx, obj) != &js_FunctionClass);
-
- JS_LOCK_OBJ(cx, obj);
- scope = OBJ_SCOPE(obj);
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (sprop->setter == setter) {
- JS_ASSERT(!JSVAL_IS_INT(sprop->id) &&
- ATOM_IS_STRING((JSAtom *)sprop->id) &&
- (sprop->flags & SPROP_HAS_SHORTID));
-
- if ((uintN) sprop->shortid == slot) {
- str = ATOM_TO_STRING((JSAtom *)sprop->id);
- JS_UNLOCK_SCOPE(cx, scope);
-
- return JS_DefineUCProperty(cx, origobj,
- JSSTRING_CHARS(str),
- JSSTRING_LENGTH(str),
- v, NULL, NULL,
- JSPROP_ENUMERATE);
- }
- }
- }
- JS_UNLOCK_SCOPE(cx, scope);
- return JS_TRUE;
- }
-
- /*
- * Argument and local variable properties of function objects are shared
- * by default (JSPROP_SHARED), therefore slot-less. But if for function
- * f(a) {}, f.a = 42 is evaluated, f.a should be 42 after the assignment,
- * whether or not f is active. So js_SetArgument and js_SetLocalVariable
- * must be prepared to change an arg or var from shared to unshared status,
- * allocating a slot in obj to hold v.
- */
- ok = JS_TRUE;
- JS_LOCK_OBJ(cx, obj);
- scope = OBJ_SCOPE(obj);
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (sprop->setter == setter && (uintN) sprop->shortid == slot) {
- if (sprop->attrs & JSPROP_SHARED) {
- sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop,
- 0, ~JSPROP_SHARED,
- sprop->getter, setter);
- if (!sprop) {
- ok = JS_FALSE;
- } else {
- /* See js_SetProperty, near the bottom. */
- GC_POKE(cx, pval);
- LOCKED_OBJ_SET_SLOT(obj, sprop->slot, v);
- }
- }
- break;
- }
- }
- JS_UNLOCK_SCOPE(cx, scope);
- return ok;
-}
-
-JSBool
-js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return JS_TRUE;
-}
-
-JSBool
-js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return SetFunctionSlot(cx, obj, js_SetArgument, id, *vp);
-}
-
-JSBool
-js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return JS_TRUE;
-}
-
-JSBool
-js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- return SetFunctionSlot(cx, obj, js_SetLocalVariable, id, *vp);
-}
-
-/*
- * Compute the 'this' parameter and store it in frame as frame.thisp.
- * Activation objects ("Call" objects not created with "new Call()", i.e.,
- * "Call" objects that have private data) may not be referred to by 'this',
- * as dictated by ECMA.
- *
- * N.B.: fp->argv must be set, fp->argv[-1] the nominal 'this' paramter as
- * a jsval, and fp->argv[-2] must be the callee object reference, usually a
- * function object. Also, fp->flags must contain JSFRAME_CONSTRUCTING if we
- * are preparing for a constructor call.
- */
-static JSBool
-ComputeThis(JSContext *cx, JSObject *thisp, JSStackFrame *fp)
-{
- JSObject *parent;
-
- if (thisp && OBJ_GET_CLASS(cx, thisp) != &js_CallClass) {
- /* Some objects (e.g., With) delegate 'this' to another object. */
- thisp = OBJ_THIS_OBJECT(cx, thisp);
- if (!thisp)
- return JS_FALSE;
-
- /* Default return value for a constructor is the new object. */
- if (fp->flags & JSFRAME_CONSTRUCTING)
- fp->rval = OBJECT_TO_JSVAL(thisp);
- } else {
- /*
- * ECMA requires "the global object", but in the presence of multiple
- * top-level objects (windows, frames, or certain layers in the client
- * object model), we prefer fun's parent. An example that causes this
- * code to run:
- *
- * // in window w1
- * function f() { return this }
- * function g() { return f }
- *
- * // in window w2
- * var h = w1.g()
- * alert(h() == w1)
- *
- * The alert should display "true".
- */
- JS_ASSERT(!(fp->flags & JSFRAME_CONSTRUCTING));
- if (JSVAL_IS_PRIMITIVE(fp->argv[-2]) ||
- !(parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fp->argv[-2])))) {
- thisp = cx->globalObject;
- } else {
- /* walk up to find the top-level object */
- thisp = parent;
- while ((parent = OBJ_GET_PARENT(cx, thisp)) != NULL)
- thisp = parent;
- }
- }
- fp->thisp = thisp;
- fp->argv[-1] = OBJECT_TO_JSVAL(thisp);
- return JS_TRUE;
-}
-
-/*
- * Find a function reference and its 'this' object implicit first parameter
- * under argc arguments on cx's stack, and call the function. Push missing
- * required arguments, allocate declared local variables, and pop everything
- * when done. Then push the return value.
- */
-JS_FRIEND_API(JSBool)
-js_Invoke(JSContext *cx, uintN argc, uintN flags)
-{
- void *mark;
- JSStackFrame *fp, frame;
- jsval *sp, *newsp, *limit;
- jsval *vp, v;
- JSObject *funobj, *parent, *thisp;
- JSBool ok;
- JSClass *clasp;
- JSObjectOps *ops;
- JSNative native;
- JSFunction *fun;
- JSScript *script;
- uintN minargs, nvars;
- intN nslots, nalloc, surplus;
- JSInterpreterHook hook;
- void *hookData;
-
- /* Mark the top of stack and load frequently-used registers. */
- mark = JS_ARENA_MARK(&cx->stackPool);
- fp = cx->fp;
- sp = fp->sp;
-
- /*
- * Set vp to the callee value's stack slot (it's where rval goes).
- * Once vp is set, control should flow through label out2: to return.
- * Set frame.rval early so native class and object ops can throw and
- * return false, causing a goto out2 with ok set to false. Also set
- * frame.flags to flags so that ComputeThis can test bits in it.
- */
- vp = sp - (2 + argc);
- v = *vp;
- frame.rval = JSVAL_VOID;
- frame.flags = flags;
- thisp = JSVAL_TO_OBJECT(vp[1]);
-
- /*
- * A callee must be an object reference, unless its |this| parameter
- * implements the __noSuchMethod__ method, in which case that method will
- * be called like so:
- *
- * thisp.__noSuchMethod__(id, args)
- *
- * where id is the name of the method that this invocation attempted to
- * call by name, and args is an Array containing this invocation's actual
- * parameters.
- */
- if (JSVAL_IS_PRIMITIVE(v)) {
-#if JS_HAS_NO_SUCH_METHOD
- jsbytecode *pc;
- jsatomid atomIndex;
- JSAtom *atom;
- JSObject *argsobj;
- JSArena *a;
-
- if (!fp->script || (flags & JSINVOKE_INTERNAL))
- goto bad;
-
- /*
- * We must ComputeThis here to censor Call objects; performance hit,
- * but at least it's idempotent.
- *
- * Normally, we call ComputeThis after all frame members have been
- * set, and in particular, after any revision of the callee value at
- * *vp due to clasp->convert (see below). This matters because
- * ComputeThis may access *vp via fp->argv[-2], to follow the parent
- * chain to a global object to use as the |this| parameter.
- *
- * Obviously, here in the JSVAL_IS_PRIMITIVE(v) case, there can't be
- * any such defaulting of |this| to callee (v, *vp) ancestor.
- */
- frame.argv = vp + 2;
- ok = ComputeThis(cx, thisp, &frame);
- if (!ok)
- goto out2;
- thisp = frame.thisp;
-
- ok = OBJ_GET_PROPERTY(cx, thisp,
- (jsid)cx->runtime->atomState.noSuchMethodAtom,
- &v);
- if (!ok)
- goto out2;
- if (JSVAL_IS_PRIMITIVE(v))
- goto bad;
-
- pc = (jsbytecode *) vp[-(intN)fp->script->depth];
- switch ((JSOp) *pc) {
- case JSOP_NAME:
- case JSOP_GETPROP:
- atomIndex = GET_ATOM_INDEX(pc);
- atom = js_GetAtom(cx, &fp->script->atomMap, atomIndex);
- argsobj = js_NewArrayObject(cx, argc, vp + 2);
- if (!argsobj) {
- ok = JS_FALSE;
- goto out2;
- }
-
- sp = vp + 4;
- if (argc < 2) {
- a = cx->stackPool.current;
- if ((jsuword)sp > a->limit) {
- /*
- * Arguments must be contiguous, and must include argv[-1]
- * and argv[-2], so allocate more stack, advance sp, and
- * set newsp[1] to thisp (vp[1]). The other argv elements
- * will be set below, using negative indexing from sp.
- */
- newsp = js_AllocRawStack(cx, 4, NULL);
- if (!newsp) {
- ok = JS_FALSE;
- goto out2;
- }
- newsp[1] = OBJECT_TO_JSVAL(thisp);
- sp = newsp + 4;
- } else if ((jsuword)sp > a->avail) {
- /*
- * Inline, optimized version of JS_ARENA_ALLOCATE to claim
- * the small number of words not already allocated as part
- * of the caller's operand stack.
- */
- JS_ArenaCountAllocation(pool, (jsuword)sp - a->avail);
- a->avail = (jsuword)sp;
- }
- }
-
- sp[-4] = v;
- JS_ASSERT(sp[-3] == OBJECT_TO_JSVAL(thisp));
- sp[-2] = ATOM_KEY(atom);
- sp[-1] = OBJECT_TO_JSVAL(argsobj);
- fp->sp = sp;
- argc = 2;
- break;
-
- default:
- goto bad;
- }
-#else
- goto bad;
-#endif
- }
-
- funobj = JSVAL_TO_OBJECT(v);
- parent = OBJ_GET_PARENT(cx, funobj);
- clasp = OBJ_GET_CLASS(cx, funobj);
- if (clasp != &js_FunctionClass) {
- /* Function is inlined, all other classes use object ops. */
- ops = funobj->map->ops;
-
- /*
- * XXX
- * Try converting to function, for closure and API compatibility.
- * We attempt the conversion under all circumstances for 1.2, but
- * only if there is a call op defined otherwise.
- */
- if (cx->version == JSVERSION_1_2 ||
- ((ops == &js_ObjectOps) ? clasp->call : ops->call)) {
- ok = clasp->convert(cx, funobj, JSTYPE_FUNCTION, &v);
- if (!ok)
- goto out2;
-
- if (JSVAL_IS_FUNCTION(cx, v)) {
- /* Make vp refer to funobj to keep it available as argv[-2]. */
- *vp = v;
- funobj = JSVAL_TO_OBJECT(v);
- parent = OBJ_GET_PARENT(cx, funobj);
- goto have_fun;
- }
- }
- fun = NULL;
- script = NULL;
- minargs = nvars = 0;
-
- /* Try a call or construct native object op. */
- native = (flags & JSINVOKE_CONSTRUCT) ? ops->construct : ops->call;
- if (!native)
- goto bad;
- } else {
-have_fun:
- /* Get private data and set derived locals from it. */
- fun = (JSFunction *) JS_GetPrivate(cx, funobj);
- native = fun->native;
- script = fun->script;
- minargs = fun->nargs + fun->extra;
- nvars = fun->nvars;
-
- /* Handle bound method special case. */
- if (fun->flags & JSFUN_BOUND_METHOD)
- thisp = parent;
- }
-
- /* Initialize the rest of frame, except for sp (set by SAVE_SP later). */
- frame.varobj = NULL;
- frame.callobj = frame.argsobj = NULL;
- frame.script = script;
- frame.fun = fun;
- frame.argc = argc;
- frame.argv = sp - argc;
- frame.nvars = nvars;
- frame.vars = sp;
- frame.down = fp;
- frame.annotation = NULL;
- frame.scopeChain = NULL; /* set below for real, after cx->fp is set */
- frame.pc = NULL;
- frame.spbase = NULL;
- frame.sharpDepth = 0;
- frame.sharpArray = NULL;
- frame.dormantNext = NULL;
- frame.objAtomMap = NULL;
-
- /* Compute the 'this' parameter and store it in frame as frame.thisp. */
- ok = ComputeThis(cx, thisp, &frame);
- if (!ok)
- goto out2;
-
- /* From here on, control must flow through label out: to return. */
- cx->fp = &frame;
-
- /* Init these now in case we goto out before first hook call. */
- hook = cx->runtime->callHook;
- hookData = NULL;
-
- /* Check for missing arguments expected by the function. */
- nslots = (intN)((argc < minargs) ? minargs - argc : 0);
- if (nslots) {
- /* All arguments must be contiguous, so we may have to copy actuals. */
- nalloc = nslots;
- limit = (jsval *) cx->stackPool.current->limit;
- if (sp + nslots > limit) {
- /* Hit end of arena: we have to copy argv[-2..(argc+nslots-1)]. */
- nalloc += 2 + argc;
- } else {
- /* Take advantage of surplus slots in the caller's frame depth. */
- surplus = (jsval *)mark - sp;
- JS_ASSERT(surplus >= 0);
- nalloc -= surplus;
- }
-
- /* Check whether we have enough space in the caller's frame. */
- if (nalloc > 0) {
- /* Need space for actuals plus missing formals minus surplus. */
- newsp = js_AllocRawStack(cx, (uintN)nalloc, NULL);
- if (!newsp) {
- ok = JS_FALSE;
- goto out;
- }
-
- /* If we couldn't allocate contiguous args, copy actuals now. */
- if (newsp != mark) {
- JS_ASSERT(sp + nslots > limit);
- JS_ASSERT(2 + argc + nslots == (uintN)nalloc);
- *newsp++ = vp[0];
- *newsp++ = vp[1];
- if (argc)
- memcpy(newsp, frame.argv, argc * sizeof(jsval));
- frame.argv = newsp;
- sp = frame.vars = newsp + argc;
- }
- }
-
- /* Advance frame.vars to make room for the missing args. */
- frame.vars += nslots;
-
- /* Push void to initialize missing args. */
- while (--nslots >= 0)
- PUSH(JSVAL_VOID);
- }
-
- /* Now allocate stack space for local variables. */
- nslots = (intN)frame.nvars;
- if (nslots) {
- surplus = (intN)((jsval *)cx->stackPool.current->avail - frame.vars);
- if (surplus < nslots) {
- newsp = js_AllocRawStack(cx, (uintN)nslots, NULL);
- if (!newsp) {
- ok = JS_FALSE;
- goto out;
- }
- if (newsp != sp) {
- /* NB: Discontinuity between argv and vars. */
- sp = frame.vars = newsp;
- }
- }
-
- /* Push void to initialize local variables. */
- while (--nslots >= 0)
- PUSH(JSVAL_VOID);
- }
-
- /* Store the current sp in frame before calling fun. */
- SAVE_SP(&frame);
-
- /* call the hook if present */
- if (hook && (native || script))
- hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->callHookData);
-
- /* Call the function, either a native method or an interpreted script. */
- if (native) {
-#if JS_HAS_LVALUE_RETURN
- /* Set by JS_SetCallReturnValue2, used to return reference types. */
- cx->rval2set = JS_FALSE;
-#endif
-
- /* If native, use caller varobj and scopeChain for eval. */
- frame.varobj = fp->varobj;
- frame.scopeChain = fp->scopeChain;
- ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval);
- JS_RUNTIME_METER(cx->runtime, nativeCalls);
- } else if (script) {
- /* Use parent scope so js_GetCallObject can find the right "Call". */
- frame.scopeChain = parent;
- if (fun->flags & JSFUN_HEAVYWEIGHT) {
-#if JS_HAS_CALL_OBJECT
- /* Scope with a call object parented by the callee's parent. */
- if (!js_GetCallObject(cx, &frame, parent)) {
- ok = JS_FALSE;
- goto out;
- }
-#else
- /* Bad old code used the function as a proxy for all calls to it. */
- frame.scopeChain = funobj;
-#endif
- }
- ok = js_Interpret(cx, &v);
- } else {
- /* fun might be onerror trying to report a syntax error in itself. */
- frame.scopeChain = NULL;
- ok = JS_TRUE;
- }
-
-out:
- if (hookData) {
- hook = cx->runtime->callHook;
- if (hook)
- hook(cx, &frame, JS_FALSE, &ok, hookData);
- }
-#if JS_HAS_CALL_OBJECT
- /* If frame has a call object, sync values and clear back-pointer. */
- if (frame.callobj)
- ok &= js_PutCallObject(cx, &frame);
-#endif
-#if JS_HAS_ARGS_OBJECT
- /* If frame has an arguments object, sync values and clear back-pointer. */
- if (frame.argsobj)
- ok &= js_PutArgsObject(cx, &frame);
-#endif
-
- /* Restore cx->fp now that we're done releasing frame objects. */
- cx->fp = fp;
-
-out2:
- /* Pop everything we may have allocated off the stack. */
- JS_ARENA_RELEASE(&cx->stackPool, mark);
-
- /* Store the return value and restore sp just above it. */
- *vp = frame.rval;
- fp->sp = vp + 1;
-
- /*
- * Store the location of the JSOP_CALL or JSOP_EVAL that generated the
- * return value, but only if this is an external (compiled from script
- * source) call that has stack budget for the generating pc.
- */
- if (fp->script && !(flags & JSINVOKE_INTERNAL))
- vp[-(intN)fp->script->depth] = (jsval)fp->pc;
- return ok;
-
-bad:
- js_ReportIsNotFunction(cx, vp, flags & JSINVOKE_CONSTRUCT);
- ok = JS_FALSE;
- goto out2;
-}
-
-JSBool
-js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
- uintN argc, jsval *argv, jsval *rval)
-{
- JSStackFrame *fp, *oldfp, frame;
- jsval *oldsp, *sp;
- void *mark;
- uintN i;
- JSBool ok;
-
- fp = oldfp = cx->fp;
- if (!fp) {
- memset(&frame, 0, sizeof frame);
- cx->fp = fp = &frame;
- }
- oldsp = fp->sp;
- sp = js_AllocStack(cx, 2 + argc, &mark);
- if (!sp) {
- ok = JS_FALSE;
- goto out;
- }
-
- PUSH(fval);
- PUSH(OBJECT_TO_JSVAL(obj));
- for (i = 0; i < argc; i++)
- PUSH(argv[i]);
- fp->sp = sp;
- ok = js_Invoke(cx, argc, flags | JSINVOKE_INTERNAL);
- if (ok) {
- RESTORE_SP(fp);
- *rval = POP_OPND();
- }
-
- js_FreeStack(cx, mark);
-out:
- fp->sp = oldsp;
- if (oldfp != fp)
- cx->fp = oldfp;
-
- return ok;
-}
-
-JSBool
-js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
- JSAccessMode mode, uintN argc, jsval *argv, jsval *rval)
-{
- /*
- * Check general (not object-ops/class-specific) access from the running
- * script to obj.id only if id has a scripted getter or setter that we're
- * about to invoke. If we don't check this case, nothing else will -- no
- * other native code has the chance to check.
- *
- * Contrast this non-native (scripted) case with native getter and setter
- * accesses, where the native itself must do an access check, if security
- * policies requires it. We make a checkAccess or checkObjectAccess call
- * back to the embedding program only in those cases where we're not going
- * to call an embedding-defined native function, getter, setter, or class
- * hook anyway. Where we do call such a native, there's no need for the
- * engine to impose a separate access check callback on all embeddings --
- * many embeddings have no security policy at all.
- */
- JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE);
- if (cx->runtime->checkObjectAccess &&
- JSVAL_IS_FUNCTION(cx, fval) &&
- ((JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)))->script &&
- !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode,
- &fval)) {
- return JS_FALSE;
- }
-
- return js_InternalCall(cx, obj, fval, argc, argv, rval);
-}
-
-JSBool
-js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
- JSStackFrame *down, uintN special, jsval *result)
-{
- JSStackFrame *oldfp, frame;
- JSObject *obj, *tmp;
- JSBool ok;
- JSInterpreterHook hook;
- void *hookData;
-
- hook = cx->runtime->executeHook;
- hookData = NULL;
- oldfp = cx->fp;
- frame.callobj = frame.argsobj = NULL;
- frame.script = script;
- if (down) {
- /* Propagate arg/var state for eval and the debugger API. */
- frame.varobj = down->varobj;
- frame.fun = down->fun;
- frame.thisp = down->thisp;
- frame.argc = down->argc;
- frame.argv = down->argv;
- frame.nvars = down->nvars;
- frame.vars = down->vars;
- frame.annotation = down->annotation;
- frame.sharpArray = down->sharpArray;
- } else {
- obj = chain;
- if (cx->options & JSOPTION_VAROBJFIX) {
- while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
- obj = tmp;
- }
- frame.varobj = obj;
- frame.fun = NULL;
- frame.thisp = chain;
- frame.argc = frame.nvars = 0;
- frame.argv = frame.vars = NULL;
- frame.annotation = NULL;
- frame.sharpArray = NULL;
- }
- frame.rval = JSVAL_VOID;
- frame.down = down;
- frame.scopeChain = chain;
- frame.pc = NULL;
- frame.sp = oldfp ? oldfp->sp : NULL;
- frame.spbase = NULL;
- frame.sharpDepth = 0;
- frame.flags = special;
- frame.dormantNext = NULL;
- frame.objAtomMap = NULL;
-
- /*
- * Here we wrap the call to js_Interpret with code to (conditionally)
- * save and restore the old stack frame chain into a chain of 'dormant'
- * frame chains. Since we are replacing cx->fp, we were running into
- * the problem that if GC was called under this frame, some of the GC
- * things associated with the old frame chain (available here only in
- * the C variable 'oldfp') were not rooted and were being collected.
- *
- * So, now we preserve the links to these 'dormant' frame chains in cx
- * before calling js_Interpret and cleanup afterwards. The GC walks
- * these dormant chains and marks objects in the same way that it marks
- * objects in the primary cx->fp chain.
- */
- if (oldfp && oldfp != down) {
- JS_ASSERT(!oldfp->dormantNext);
- oldfp->dormantNext = cx->dormantFrameChain;
- cx->dormantFrameChain = oldfp;
- }
-
- cx->fp = &frame;
- if (hook)
- hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData);
-
- ok = js_Interpret(cx, result);
-
- if (hookData) {
- hook = cx->runtime->executeHook;
- if (hook)
- hook(cx, &frame, JS_FALSE, &ok, hookData);
- }
- cx->fp = oldfp;
-
- if (oldfp && oldfp != down) {
- JS_ASSERT(cx->dormantFrameChain == oldfp);
- cx->dormantFrameChain = oldfp->dormantNext;
- oldfp->dormantNext = NULL;
- }
-
- return ok;
-}
-
-#if JS_HAS_EXPORT_IMPORT
-/*
- * If id is JSVAL_VOID, import all exported properties from obj.
- */
-static JSBool
-ImportProperty(JSContext *cx, JSObject *obj, jsid id)
-{
- JSBool ok;
- JSIdArray *ida;
- JSProperty *prop;
- JSObject *obj2, *target, *funobj, *closure;
- JSString *str;
- uintN attrs;
- jsint i;
- jsval value;
-
- if (JSVAL_IS_VOID(id)) {
- ida = JS_Enumerate(cx, obj);
- if (!ida)
- return JS_FALSE;
- ok = JS_TRUE;
- if (ida->length == 0)
- goto out;
- } else {
- ida = NULL;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
- ID_TO_VALUE(id), NULL);
- if (str)
- js_ReportIsNotDefined(cx, JS_GetStringBytes(str));
- return JS_FALSE;
- }
- ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (!ok)
- return JS_FALSE;
- if (!(attrs & JSPROP_EXPORTED)) {
- str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
- ID_TO_VALUE(id), NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_NOT_EXPORTED,
- JS_GetStringBytes(str));
- }
- return JS_FALSE;
- }
- }
-
- target = cx->fp->varobj;
- i = 0;
- do {
- if (ida) {
- id = ida->vector[i];
- ok = OBJ_GET_ATTRIBUTES(cx, obj, id, NULL, &attrs);
- if (!ok)
- goto out;
- if (!(attrs & JSPROP_EXPORTED))
- continue;
- }
- ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs);
- if (!ok)
- goto out;
- if (JSVAL_IS_FUNCTION(cx, value)) {
- funobj = JSVAL_TO_OBJECT(value);
- closure = js_CloneFunctionObject(cx, funobj, obj);
- if (!closure) {
- ok = JS_FALSE;
- goto out;
- }
- value = OBJECT_TO_JSVAL(closure);
- }
-
- /*
- * Handle the case of importing a property that refers to a local
- * variable or formal parameter of a function activation. These
- * properties are accessed by opcodes using stack slot numbers
- * generated by the compiler rather than runtime name-lookup. These
- * local references, therefore, bypass the normal scope chain lookup.
- * So, instead of defining a new property in the activation object,
- * modify the existing value in the stack slot.
- */
- if (OBJ_GET_CLASS(cx, target) == &js_CallClass) {
- ok = OBJ_LOOKUP_PROPERTY(cx, target, id, &obj2, &prop);
- if (!ok)
- goto out;
- } else {
- prop = NULL;
- }
- if (prop && target == obj2) {
- ok = OBJ_SET_PROPERTY(cx, target, id, &value);
- } else {
- ok = OBJ_DEFINE_PROPERTY(cx, target, id, value, NULL, NULL,
- attrs & ~JSPROP_EXPORTED,
- NULL);
- }
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (!ok)
- goto out;
- } while (ida && ++i < ida->length);
-
-out:
- if (ida)
- JS_DestroyIdArray(cx, ida);
- return ok;
-}
-#endif /* JS_HAS_EXPORT_IMPORT */
-
-JSBool
-js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,
- JSBool *foundp)
-{
- JSObject *obj2;
- JSProperty *prop;
- JSBool ok;
- uintN oldAttrs, report;
- JSBool isFunction;
- jsval value;
- const char *type, *name;
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
- *foundp = (prop != NULL);
- if (!prop)
- return JS_TRUE;
- ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs);
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (!ok)
- return JS_FALSE;
-
- /* If either property is readonly, we have an error. */
- report = ((oldAttrs | attrs) & JSPROP_READONLY)
- ? JSREPORT_ERROR
- : JSREPORT_WARNING | JSREPORT_STRICT;
-
- if (report != JSREPORT_ERROR) {
- /*
- * Allow redeclaration of variables and functions, but insist that the
- * new value is not a getter if the old value was, ditto for setters --
- * unless prop is impermanent (in which case anyone could delete it and
- * redefine it, willy-nilly).
- */
- if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER)))
- return JS_TRUE;
- if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0)
- return JS_TRUE;
- if (!(oldAttrs & JSPROP_PERMANENT))
- return JS_TRUE;
- report = JSREPORT_ERROR;
- }
-
- isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0;
- if (!isFunction) {
- if (!OBJ_GET_PROPERTY(cx, obj, id, &value))
- return JS_FALSE;
- isFunction = JSVAL_IS_FUNCTION(cx, value);
- }
- type = (oldAttrs & attrs & JSPROP_GETTER)
- ? js_getter_str
- : (oldAttrs & attrs & JSPROP_SETTER)
- ? js_setter_str
- : (oldAttrs & JSPROP_READONLY)
- ? js_const_str
- : isFunction
- ? js_function_str
- : js_var_str;
- name = js_AtomToPrintableString(cx, (JSAtom *)id);
- if (!name)
- return JS_FALSE;
- return JS_ReportErrorFlagsAndNumber(cx, report,
- js_GetErrorMessage, NULL,
- JSMSG_REDECLARED_VAR,
- type, name);
-}
-
-#ifndef MAX_INTERP_LEVEL
-#if defined(XP_OS2)
-#define MAX_INTERP_LEVEL 250
-#elif defined _MSC_VER && _MSC_VER <= 800
-#define MAX_INTERP_LEVEL 30
-#else
-#define MAX_INTERP_LEVEL 1000
-#endif
-#endif
-
-#define MAX_INLINE_CALL_COUNT 1000
-
-JSBool
-js_Interpret(JSContext *cx, jsval *result)
-{
- JSRuntime *rt;
- JSStackFrame *fp;
- JSScript *script;
- uintN inlineCallCount;
- JSObject *obj, *obj2, *proto, *parent;
- JSVersion currentVersion, originalVersion;
- JSBranchCallback onbranch;
- JSBool ok, cond;
- JSTrapHandler interruptHandler;
- jsint depth, len;
- jsval *sp, *newsp;
- void *mark;
- jsbytecode *pc, *pc2, *endpc;
- JSOp op, op2;
- const JSCodeSpec *cs;
- JSAtom *atom;
- uintN argc, slot, attrs;
- jsval *vp, lval, rval, ltmp, rtmp;
- jsid id;
- JSObject *withobj, *origobj, *propobj;
- jsval iter_state;
- JSProperty *prop;
- JSScopeProperty *sprop;
- JSString *str, *str2;
- jsint i, j;
- jsdouble d, d2;
- JSClass *clasp, *funclasp;
- JSFunction *fun;
- JSType type;
-#ifdef DEBUG
- FILE *tracefp;
-#endif
-#if JS_HAS_EXPORT_IMPORT
- JSIdArray *ida;
-#endif
-#if JS_HAS_SWITCH_STATEMENT
- jsint low, high, off, npairs;
- JSBool match;
-#endif
-#if JS_HAS_GETTER_SETTER
- JSPropertyOp getter, setter;
-#endif
- int stackDummy;
-
- *result = JSVAL_VOID;
- rt = cx->runtime;
-
- /* Set registerized frame pointer and derived script pointer. */
- fp = cx->fp;
- script = fp->script;
-
- /* Count of JS function calls that nest in this C js_Interpret frame. */
- inlineCallCount = 0;
-
- /*
- * Optimized Get and SetVersion for proper script language versioning.
- *
- * If any native method or JSClass/JSObjectOps hook calls JS_SetVersion
- * and changes cx->version, the effect will "stick" and we will stop
- * maintaining currentVersion. This is relied upon by testsuites, for
- * the most part -- web browsers select version before compiling and not
- * at run-time.
- */
- currentVersion = script->version;
- originalVersion = cx->version;
- if (currentVersion != originalVersion)
- JS_SetVersion(cx, currentVersion);
-
- /*
- * Prepare to call a user-supplied branch handler, and abort the script
- * if it returns false.
- */
- onbranch = cx->branchCallback;
- ok = JS_TRUE;
-#define CHECK_BRANCH(len) \
- JS_BEGIN_MACRO \
- if (len <= 0 && onbranch) { \
- SAVE_SP(fp); \
- if (!(ok = (*onbranch)(cx, script))) \
- goto out; \
- } \
- JS_END_MACRO
-
- /*
- * Load the debugger's interrupt hook here and after calling out to native
- * functions (but not to getters, setters, or other native hooks), so we do
- * not have to reload it each time through the interpreter loop -- we hope
- * the compiler can keep it in a register.
- * XXX if it spills, we still lose
- */
-#define LOAD_INTERRUPT_HANDLER(rt) (interruptHandler = (rt)->interruptHandler)
-
- LOAD_INTERRUPT_HANDLER(rt);
-
- pc = script->code;
- endpc = pc + script->length;
- depth = (jsint) script->depth;
- len = -1;
-
- /* Check for too much js_Interpret nesting, or too deep a C stack. */
- if (++cx->interpLevel == MAX_INTERP_LEVEL ||
- !JS_CHECK_STACK_SIZE(cx, stackDummy)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
- ok = JS_FALSE;
- goto out;
- }
-
- /*
- * Allocate operand and pc stack slots for the script's worst-case depth.
- */
- newsp = js_AllocRawStack(cx, (uintN)(2 * depth), &mark);
- if (!newsp) {
- ok = JS_FALSE;
- goto out;
- }
- sp = newsp + depth;
- fp->spbase = sp;
- SAVE_SP(fp);
-
- while (pc < endpc) {
- fp->pc = pc;
- op = (JSOp) *pc;
- do_op:
- cs = &js_CodeSpec[op];
- len = cs->length;
-
-#ifdef DEBUG
- tracefp = (FILE *) cx->tracefp;
- if (tracefp) {
- intN nuses, n;
-
- fprintf(tracefp, "%4u: ", js_PCToLineNumber(cx, script, pc));
- js_Disassemble1(cx, script, pc,
- PTRDIFF(pc, script->code, jsbytecode), JS_FALSE,
- tracefp);
- nuses = cs->nuses;
- if (nuses) {
- SAVE_SP(fp);
- for (n = -nuses; n < 0; n++) {
- str = js_DecompileValueGenerator(cx, n, sp[n], NULL);
- if (str != NULL) {
- fprintf(tracefp, "%s %s",
- (n == -nuses) ? " inputs:" : ",",
- JS_GetStringBytes(str));
- }
- }
- fprintf(tracefp, " @ %d\n", sp - fp->spbase);
- }
- }
-#endif
-
- if (interruptHandler) {
- SAVE_SP(fp);
- switch (interruptHandler(cx, script, pc, &rval,
- rt->interruptHandlerData)) {
- case JSTRAP_ERROR:
- ok = JS_FALSE;
- goto out;
- case JSTRAP_CONTINUE:
- break;
- case JSTRAP_RETURN:
- fp->rval = rval;
- goto out;
-#if JS_HAS_EXCEPTIONS
- case JSTRAP_THROW:
- cx->throwing = JS_TRUE;
- cx->exception = rval;
- ok = JS_FALSE;
- goto out;
-#endif /* JS_HAS_EXCEPTIONS */
- default:;
- }
- LOAD_INTERRUPT_HANDLER(rt);
- }
-
- switch (op) {
- case JSOP_NOP:
- break;
-
- case JSOP_GROUP:
- obj = NULL;
- break;
-
- case JSOP_PUSH:
- PUSH_OPND(JSVAL_VOID);
- break;
-
- case JSOP_POP:
- sp--;
- break;
-
- case JSOP_POP2:
- sp -= 2;
- break;
-
- case JSOP_SWAP:
- /*
- * N.B. JSOP_SWAP doesn't swap the corresponding generating pcs
- * for the operands it swaps.
- */
- ltmp = sp[-1];
- sp[-1] = sp[-2];
- sp[-2] = ltmp;
- break;
-
- case JSOP_POPV:
- *result = POP_OPND();
- break;
-
- case JSOP_ENTERWITH:
- rval = FETCH_OPND(-1);
- VALUE_TO_OBJECT(cx, rval, obj);
- withobj = js_NewObject(cx, &js_WithClass, obj, fp->scopeChain);
- if (!withobj)
- goto out;
- fp->scopeChain = withobj;
- STORE_OPND(-1, OBJECT_TO_JSVAL(withobj));
- break;
-
- case JSOP_LEAVEWITH:
- rval = POP_OPND();
- JS_ASSERT(JSVAL_IS_OBJECT(rval));
- withobj = JSVAL_TO_OBJECT(rval);
- JS_ASSERT(OBJ_GET_CLASS(cx, withobj) == &js_WithClass);
-
- rval = OBJ_GET_SLOT(cx, withobj, JSSLOT_PARENT);
- JS_ASSERT(JSVAL_IS_OBJECT(rval));
- fp->scopeChain = JSVAL_TO_OBJECT(rval);
- break;
-
- case JSOP_SETRVAL:
- fp->rval = POP_OPND();
- break;
-
- case JSOP_RETURN:
- CHECK_BRANCH(-1);
- fp->rval = POP_OPND();
- /* FALL THROUGH */
-
- case JSOP_RETRVAL: /* fp->rval already set */
- if (inlineCallCount)
- inline_return:
- {
- JSInlineFrame *ifp = (JSInlineFrame *) fp;
- void *hookData = ifp->hookData;
-
- if (hookData) {
- JSInterpreterHook hook = cx->runtime->callHook;
- if (hook) {
- hook(cx, fp, JS_FALSE, &ok, hookData);
- LOAD_INTERRUPT_HANDLER(rt);
- }
- }
-#if JS_HAS_ARGS_OBJECT
- if (fp->argsobj)
- ok &= js_PutArgsObject(cx, fp);
-#endif
-
- /* Restore context version only if callee hasn't set version. */
- if (cx->version == currentVersion) {
- currentVersion = ifp->callerVersion;
- if (currentVersion != cx->version)
- JS_SetVersion(cx, currentVersion);
- }
-
- /* Store the return value in the caller's operand frame. */
- vp = fp->argv - 2;
- *vp = fp->rval;
-
- /* Restore cx->fp and release the inline frame's space. */
- cx->fp = fp = fp->down;
- JS_ARENA_RELEASE(&cx->stackPool, ifp->mark);
-
- /* Restore sp to point just above the return value. */
- fp->sp = vp + 1;
- RESTORE_SP(fp);
-
- /* Restore the calling script's interpreter registers. */
- script = fp->script;
- depth = (jsint) script->depth;
- pc = fp->pc;
- endpc = script->code + script->length;
-
- /* Store the generating pc for the return value. */
- vp[-depth] = (jsval)pc;
-
- /* Set remaining variables for 'goto advance_pc'. */
- op = (JSOp) *pc;
- cs = &js_CodeSpec[op];
- len = cs->length;
-
- /* Resume execution in the calling frame. */
- inlineCallCount--;
- if (ok)
- goto advance_pc;
- }
- goto out;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JSOP_DEFAULT:
- (void) POP();
- /* FALL THROUGH */
-#endif
- case JSOP_GOTO:
- len = GET_JUMP_OFFSET(pc);
- CHECK_BRANCH(len);
- break;
-
- case JSOP_IFEQ:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_FALSE) {
- len = GET_JUMP_OFFSET(pc);
- CHECK_BRANCH(len);
- }
- break;
-
- case JSOP_IFNE:
- POP_BOOLEAN(cx, rval, cond);
- if (cond != JS_FALSE) {
- len = GET_JUMP_OFFSET(pc);
- CHECK_BRANCH(len);
- }
- break;
-
- case JSOP_OR:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_TRUE) {
- len = GET_JUMP_OFFSET(pc);
- PUSH_OPND(rval);
- }
- break;
-
- case JSOP_AND:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_FALSE) {
- len = GET_JUMP_OFFSET(pc);
- PUSH_OPND(rval);
- }
- break;
-
-
-#if JS_HAS_SWITCH_STATEMENT
- case JSOP_DEFAULTX:
- (void) POP();
- /* FALL THROUGH */
-#endif
- case JSOP_GOTOX:
- len = GET_JUMPX_OFFSET(pc);
- CHECK_BRANCH(len);
- break;
-
- case JSOP_IFEQX:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_FALSE) {
- len = GET_JUMPX_OFFSET(pc);
- CHECK_BRANCH(len);
- }
- break;
-
- case JSOP_IFNEX:
- POP_BOOLEAN(cx, rval, cond);
- if (cond != JS_FALSE) {
- len = GET_JUMPX_OFFSET(pc);
- CHECK_BRANCH(len);
- }
- break;
-
- case JSOP_ORX:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_TRUE) {
- len = GET_JUMPX_OFFSET(pc);
- PUSH_OPND(rval);
- }
- break;
-
- case JSOP_ANDX:
- POP_BOOLEAN(cx, rval, cond);
- if (cond == JS_FALSE) {
- len = GET_JUMPX_OFFSET(pc);
- PUSH_OPND(rval);
- }
- break;
-
- case JSOP_TOOBJECT:
- SAVE_SP(fp);
- ok = js_ValueToObject(cx, FETCH_OPND(-1), &obj);
- if (!ok)
- goto out;
- STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
- break;
-
-#define FETCH_ELEMENT_ID(n, id) \
- JS_BEGIN_MACRO \
- /* If the index is not a jsint, atomize it. */ \
- id = (jsid) FETCH_OPND(n); \
- if (JSVAL_IS_INT(id)) { \
- atom = NULL; \
- } else { \
- SAVE_SP(fp); \
- atom = js_ValueToStringAtom(cx, (jsval)id); \
- if (!atom) { \
- ok = JS_FALSE; \
- goto out; \
- } \
- id = (jsid)atom; \
- } \
- JS_END_MACRO
-
-#define POP_ELEMENT_ID(id) \
- JS_BEGIN_MACRO \
- FETCH_ELEMENT_ID(-1, id); \
- sp--; \
- JS_END_MACRO
-
-#if JS_HAS_IN_OPERATOR
- case JSOP_IN:
- rval = FETCH_OPND(-1);
- if (JSVAL_IS_PRIMITIVE(rval)) {
- str = js_DecompileValueGenerator(cx, -1, rval, NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_IN_NOT_OBJECT,
- JS_GetStringBytes(str));
- }
- ok = JS_FALSE;
- goto out;
- }
- sp--;
- obj = JSVAL_TO_OBJECT(rval);
- FETCH_ELEMENT_ID(-1, id);
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ok)
- goto out;
- STORE_OPND(-1, BOOLEAN_TO_JSVAL(prop != NULL));
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- break;
-#endif /* JS_HAS_IN_OPERATOR */
-
- case JSOP_FORPROP:
- /*
- * Handle JSOP_FORPROP first, so the cost of the goto do_forinloop
- * is not paid for the more common cases.
- */
- lval = FETCH_OPND(-1);
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- i = -2;
- goto do_forinloop;
-
- case JSOP_FORNAME:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
-
- /*
- * ECMA 12.6.3 says to eval the LHS after looking for properties
- * to enumerate, and bail without LHS eval if there are no props.
- * We do Find here to share the most code at label do_forinloop.
- * If looking for enumerable properties could have side effects,
- * then we'd have to move this into the common code and condition
- * it on op == JSOP_FORNAME.
- */
- SAVE_SP(fp);
- ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
- if (!ok)
- goto out;
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- lval = OBJECT_TO_JSVAL(obj);
- /* FALL THROUGH */
-
- case JSOP_FORARG:
- case JSOP_FORVAR:
- /*
- * JSOP_FORARG and JSOP_FORVAR don't require any lval computation
- * here, because they address slots on the stack (in fp->args and
- * fp->vars, respectively).
- */
- /* FALL THROUGH */
-
- case JSOP_FORELEM:
- /*
- * JSOP_FORELEM simply initializes or updates the iteration state
- * and leaves the index expression evaluation and assignment to the
- * enumerator until after the next property has been acquired, via
- * a JSOP_ENUMELEM bytecode.
- */
- i = -1;
-
- do_forinloop:
- /*
- * ECMA-compatible for/in evals the object just once, before loop.
- * Bad old bytecodes (since removed) did it on every iteration.
- */
- obj = JSVAL_TO_OBJECT(sp[i]);
-
- /* If the thing to the right of 'in' has no properties, break. */
- if (!obj) {
- rval = JSVAL_FALSE;
- goto end_forinloop;
- }
-
- /*
- * Save the thing to the right of 'in' as origobj. Later on, we
- * use this variable to suppress enumeration of shadowed prototype
- * properties.
- */
- origobj = obj;
-
- /*
- * Reach under the top of stack to find our property iterator, a
- * JSObject that contains the iteration state. (An object is used
- * rather than a native struct so that the iteration state is
- * cleaned up via GC if the for-in loop terminates abruptly.)
- */
- vp = &sp[i - 1];
- rval = *vp;
-
- /* Is this the first iteration ? */
- if (JSVAL_IS_VOID(rval)) {
- /* Yes, create a new JSObject to hold the iterator state */
- propobj = js_NewObject(cx, &prop_iterator_class, NULL, obj);
- if (!propobj) {
- ok = JS_FALSE;
- goto out;
- }
- propobj->slots[JSSLOT_ITER_STATE] = JSVAL_NULL;
-
- /*
- * Root the parent slot so we can get it even in our finalizer
- * (otherwise, it would live as long as we do, but it might be
- * finalized first).
- */
- ok = js_AddRoot(cx, &propobj->slots[JSSLOT_PARENT],
- "propobj->parent");
- if (!ok)
- goto out;
-
- /*
- * Rewrite the iterator so we know to do the next case.
- * Do this before calling the enumerator, which could
- * displace cx->newborn and cause GC.
- */
- *vp = OBJECT_TO_JSVAL(propobj);
-
- ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0);
-
- /*
- * Stash private iteration state into property iterator object.
- * We do this before checking 'ok' to ensure that propobj is
- * in a valid state even if OBJ_ENUMERATE returned JS_FALSE.
- * NB: This code knows that the first slots are pre-allocated.
- */
-#if JS_INITIAL_NSLOTS < 5
-#error JS_INITIAL_NSLOTS must be greater than or equal to 5.
-#endif
- propobj->slots[JSSLOT_ITER_STATE] = iter_state;
- if (!ok)
- goto out;
- } else {
- /* This is not the first iteration. Recover iterator state. */
- propobj = JSVAL_TO_OBJECT(rval);
- obj = JSVAL_TO_OBJECT(propobj->slots[JSSLOT_PARENT]);
- iter_state = propobj->slots[JSSLOT_ITER_STATE];
- }
-
- enum_next_property:
- /* Get the next jsid to be enumerated and store it in rval. */
- OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &rval);
- propobj->slots[JSSLOT_ITER_STATE] = iter_state;
-
- /* No more jsids to iterate in obj? */
- if (iter_state == JSVAL_NULL) {
- /* Enumerate the properties on obj's prototype chain. */
- obj = OBJ_GET_PROTO(cx, obj);
- if (!obj) {
- /* End of property list -- terminate loop. */
- rval = JSVAL_FALSE;
- goto end_forinloop;
- }
-
- ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0);
-
- /*
- * Stash private iteration state into property iterator object.
- * We do this before checking 'ok' to ensure that propobj is
- * in a valid state even if OBJ_ENUMERATE returned JS_FALSE.
- * NB: This code knows that the first slots are pre-allocated.
- */
- propobj->slots[JSSLOT_ITER_STATE] = iter_state;
- if (!ok)
- goto out;
-
- /*
- * Update the iterator JSObject's parent link to refer to the
- * current object. This is used in the iterator JSObject's
- * finalizer.
- */
- propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);
- goto enum_next_property;
- }
-
- /* Skip properties not owned by obj, and leave next id in rval. */
- ok = OBJ_LOOKUP_PROPERTY(cx, origobj, rval, &obj2, &prop);
- if (!ok)
- goto out;
- if (prop) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
-
- /* Yes, don't enumerate again. Go to the next property. */
- if (obj2 != obj)
- goto enum_next_property;
- }
-
- /* Make sure rval is a string for uniformity and compatibility. */
- if (!JSVAL_IS_INT(rval)) {
- rval = ATOM_KEY((JSAtom *)rval);
- } else if (cx->version != JSVERSION_1_2) {
- str = js_NumberToString(cx, (jsdouble) JSVAL_TO_INT(rval));
- if (!str) {
- ok = JS_FALSE;
- goto out;
- }
-
- rval = STRING_TO_JSVAL(str);
- }
-
- switch (op) {
- case JSOP_FORARG:
- slot = GET_ARGNO(pc);
- JS_ASSERT(slot < fp->fun->nargs);
- fp->argv[slot] = rval;
- break;
-
- case JSOP_FORVAR:
- slot = GET_VARNO(pc);
- JS_ASSERT(slot < fp->fun->nvars);
- fp->vars[slot] = rval;
- break;
-
- case JSOP_FORELEM:
- /* FORELEM is not a SET operation, it's more like BINDNAME. */
- PUSH_OPND(rval);
- break;
-
- default:
- /* Convert lval to a non-null object containing id. */
- VALUE_TO_OBJECT(cx, lval, obj);
-
- /* Set the variable obj[id] to refer to rval. */
- fp->flags |= JSFRAME_ASSIGNING;
- ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
- fp->flags &= ~JSFRAME_ASSIGNING;
- if (!ok)
- goto out;
- break;
- }
-
- /* Push true to keep looping through properties. */
- rval = JSVAL_TRUE;
-
- end_forinloop:
- sp += i + 1;
- PUSH_OPND(rval);
- break;
-
- case JSOP_DUP:
- JS_ASSERT(sp > fp->spbase);
- rval = sp[-1];
- PUSH_OPND(rval);
- break;
-
- case JSOP_DUP2:
- JS_ASSERT(sp - 1 > fp->spbase);
- lval = FETCH_OPND(-2);
- rval = FETCH_OPND(-1);
- PUSH_OPND(lval);
- PUSH_OPND(rval);
- break;
-
-#define PROPERTY_OP(n, call) \
- JS_BEGIN_MACRO \
- /* Pop the left part and resolve it to a non-null object. */ \
- lval = FETCH_OPND(n); \
- VALUE_TO_OBJECT(cx, lval, obj); \
- \
- /* Get or set the property, set ok false if error, true if success. */\
- SAVE_SP(fp); \
- call; \
- if (!ok) \
- goto out; \
- JS_END_MACRO
-
-#define ELEMENT_OP(n, call) \
- JS_BEGIN_MACRO \
- FETCH_ELEMENT_ID(n, id); \
- PROPERTY_OP(n-1, call); \
- JS_END_MACRO
-
-/*
- * Direct callers, i.e. those who do not wrap CACHED_GET and CACHED_SET calls
- * in PROPERTY_OP or ELEMENT_OP macro calls must SAVE_SP(fp); beforehand, just
- * in case a getter or setter function is invoked.
- */
-#define CACHED_GET(call) \
- JS_BEGIN_MACRO \
- if (!OBJ_IS_NATIVE(obj)) { \
- ok = call; \
- } else { \
- JS_LOCK_OBJ(cx, obj); \
- PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop); \
- if (sprop) { \
- JSScope *scope_ = OBJ_SCOPE(obj); \
- slot = (uintN)sprop->slot; \
- rval = (slot != SPROP_INVALID_SLOT) \
- ? LOCKED_OBJ_GET_SLOT(obj, slot) \
- : JSVAL_VOID; \
- JS_UNLOCK_SCOPE(cx, scope_); \
- ok = SPROP_GET(cx, sprop, obj, obj, &rval); \
- JS_LOCK_SCOPE(cx, scope_); \
- if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) \
- LOCKED_OBJ_SET_SLOT(obj, slot, rval); \
- JS_UNLOCK_SCOPE(cx, scope_); \
- } else { \
- JS_UNLOCK_OBJ(cx, obj); \
- ok = call; \
- /* No fill here: js_GetProperty fills the cache. */ \
- } \
- } \
- JS_END_MACRO
-
-#define CACHED_SET(call) \
- JS_BEGIN_MACRO \
- if (!OBJ_IS_NATIVE(obj)) { \
- ok = call; \
- } else { \
- JSScope *scope_; \
- JS_LOCK_OBJ(cx, obj); \
- PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop); \
- if (sprop && \
- !(sprop->attrs & JSPROP_READONLY) && \
- (scope_ = OBJ_SCOPE(obj), !SCOPE_IS_SEALED(scope_))) { \
- JS_UNLOCK_SCOPE(cx, scope_); \
- ok = SPROP_SET(cx, sprop, obj, obj, &rval); \
- JS_LOCK_SCOPE(cx, scope_); \
- if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) { \
- LOCKED_OBJ_SET_SLOT(obj, sprop->slot, rval); \
- GC_POKE(cx, JSVAL_NULL); /* XXX second arg ignored */ \
- } \
- JS_UNLOCK_SCOPE(cx, scope_); \
- } else { \
- JS_UNLOCK_OBJ(cx, obj); \
- ok = call; \
- /* No fill here: js_SetProperty writes through the cache. */ \
- } \
- } \
- JS_END_MACRO
-
- case JSOP_SETCONST:
- obj = fp->varobj;
- atom = GET_ATOM(cx, script, pc);
- rval = FETCH_OPND(-1);
- ok = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, rval, NULL, NULL,
- JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_READONLY,
- NULL);
- if (!ok)
- goto out;
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_BINDNAME:
- atom = GET_ATOM(cx, script, pc);
- SAVE_SP(fp);
- obj = js_FindIdentifierBase(cx, (jsid)atom);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- PUSH_OPND(OBJECT_TO_JSVAL(obj));
- break;
-
- case JSOP_SETNAME:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- rval = FETCH_OPND(-1);
- lval = FETCH_OPND(-2);
- JS_ASSERT(!JSVAL_IS_PRIMITIVE(lval));
- obj = JSVAL_TO_OBJECT(lval);
- SAVE_SP(fp);
- CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
- if (!ok)
- goto out;
- sp--;
- STORE_OPND(-1, rval);
- break;
-
-#define INTEGER_OP(OP, EXTRA_CODE) \
- JS_BEGIN_MACRO \
- FETCH_INT(cx, -1, j); \
- FETCH_INT(cx, -2, i); \
- if (!ok) \
- goto out; \
- EXTRA_CODE \
- d = i OP j; \
- sp--; \
- STORE_NUMBER(cx, -1, d); \
- JS_END_MACRO
-
-#define BITWISE_OP(OP) INTEGER_OP(OP, (void) 0;)
-#define SIGNED_SHIFT_OP(OP) INTEGER_OP(OP, j &= 31;)
-
- case JSOP_BITOR:
- BITWISE_OP(|);
- break;
-
- case JSOP_BITXOR:
- BITWISE_OP(^);
- break;
-
- case JSOP_BITAND:
- BITWISE_OP(&);
- break;
-
-#if defined(XP_WIN)
-#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) \
- ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL)) \
- ? (IFNAN) \
- : (LVAL) OP (RVAL))
-#else
-#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
-#endif
-
-#define RELATIONAL_OP(OP) \
- JS_BEGIN_MACRO \
- rval = FETCH_OPND(-1); \
- lval = FETCH_OPND(-2); \
- /* Optimize for two int-tagged operands (typical loop control). */ \
- if ((lval & rval) & JSVAL_INT) { \
- ltmp = lval ^ JSVAL_VOID; \
- rtmp = rval ^ JSVAL_VOID; \
- if (ltmp && rtmp) { \
- cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval); \
- } else { \
- d = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN; \
- d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN; \
- cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE); \
- } \
- } else { \
- VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval); \
- VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval); \
- if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) { \
- str = JSVAL_TO_STRING(lval); \
- str2 = JSVAL_TO_STRING(rval); \
- cond = js_CompareStrings(str, str2) OP 0; \
- } else { \
- VALUE_TO_NUMBER(cx, lval, d); \
- VALUE_TO_NUMBER(cx, rval, d2); \
- cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE); \
- } \
- } \
- sp--; \
- STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \
- JS_END_MACRO
-
-#define EQUALITY_OP(OP, IFNAN) \
- JS_BEGIN_MACRO \
- rval = FETCH_OPND(-1); \
- lval = FETCH_OPND(-2); \
- ltmp = JSVAL_TAG(lval); \
- rtmp = JSVAL_TAG(rval); \
- if (ltmp == rtmp) { \
- if (ltmp == JSVAL_STRING) { \
- str = JSVAL_TO_STRING(lval); \
- str2 = JSVAL_TO_STRING(rval); \
- cond = js_CompareStrings(str, str2) OP 0; \
- } else if (ltmp == JSVAL_DOUBLE) { \
- d = *JSVAL_TO_DOUBLE(lval); \
- d2 = *JSVAL_TO_DOUBLE(rval); \
- cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \
- } else { \
- /* Handle all undefined (=>NaN) and int combinations. */ \
- cond = lval OP rval; \
- } \
- } else { \
- if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) { \
- cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1; \
- } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) { \
- cond = 1 OP 0; \
- } else { \
- if (ltmp == JSVAL_OBJECT) { \
- VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval); \
- ltmp = JSVAL_TAG(lval); \
- } else if (rtmp == JSVAL_OBJECT) { \
- VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval); \
- rtmp = JSVAL_TAG(rval); \
- } \
- if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) { \
- str = JSVAL_TO_STRING(lval); \
- str2 = JSVAL_TO_STRING(rval); \
- cond = js_CompareStrings(str, str2) OP 0; \
- } else { \
- VALUE_TO_NUMBER(cx, lval, d); \
- VALUE_TO_NUMBER(cx, rval, d2); \
- cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \
- } \
- } \
- } \
- sp--; \
- STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \
- JS_END_MACRO
-
- case JSOP_EQ:
- EQUALITY_OP(==, JS_FALSE);
- break;
-
- case JSOP_NE:
- EQUALITY_OP(!=, JS_TRUE);
- break;
-
-#if !JS_BUG_FALLIBLE_EQOPS
-#define NEW_EQUALITY_OP(OP, IFNAN) \
- JS_BEGIN_MACRO \
- rval = FETCH_OPND(-1); \
- lval = FETCH_OPND(-2); \
- ltmp = JSVAL_TAG(lval); \
- rtmp = JSVAL_TAG(rval); \
- if (ltmp == rtmp) { \
- if (ltmp == JSVAL_STRING) { \
- str = JSVAL_TO_STRING(lval); \
- str2 = JSVAL_TO_STRING(rval); \
- cond = js_CompareStrings(str, str2) OP 0; \
- } else if (ltmp == JSVAL_DOUBLE) { \
- d = *JSVAL_TO_DOUBLE(lval); \
- d2 = *JSVAL_TO_DOUBLE(rval); \
- cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \
- } else { \
- cond = lval OP rval; \
- } \
- } else { \
- if (ltmp == JSVAL_DOUBLE && JSVAL_IS_INT(rval)) { \
- d = *JSVAL_TO_DOUBLE(lval); \
- d2 = JSVAL_TO_INT(rval); \
- cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \
- } else if (JSVAL_IS_INT(lval) && rtmp == JSVAL_DOUBLE) { \
- d = JSVAL_TO_INT(lval); \
- d2 = *JSVAL_TO_DOUBLE(rval); \
- cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \
- } else { \
- cond = lval OP rval; \
- } \
- } \
- sp--; \
- STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \
- JS_END_MACRO
-
- case JSOP_NEW_EQ:
- NEW_EQUALITY_OP(==, JS_FALSE);
- break;
-
- case JSOP_NEW_NE:
- NEW_EQUALITY_OP(!=, JS_TRUE);
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JSOP_CASE:
- NEW_EQUALITY_OP(==, JS_FALSE);
- (void) POP();
- if (cond) {
- len = GET_JUMP_OFFSET(pc);
- CHECK_BRANCH(len);
- } else {
- PUSH(lval);
- }
- break;
-
- case JSOP_CASEX:
- NEW_EQUALITY_OP(==, JS_FALSE);
- (void) POP();
- if (cond) {
- len = GET_JUMPX_OFFSET(pc);
- CHECK_BRANCH(len);
- } else {
- PUSH(lval);
- }
- break;
-#endif
-
-#endif /* !JS_BUG_FALLIBLE_EQOPS */
-
- case JSOP_LT:
- RELATIONAL_OP(<);
- break;
-
- case JSOP_LE:
- RELATIONAL_OP(<=);
- break;
-
- case JSOP_GT:
- RELATIONAL_OP(>);
- break;
-
- case JSOP_GE:
- RELATIONAL_OP(>=);
- break;
-
-#undef EQUALITY_OP
-#undef RELATIONAL_OP
-
- case JSOP_LSH:
- SIGNED_SHIFT_OP(<<);
- break;
-
- case JSOP_RSH:
- SIGNED_SHIFT_OP(>>);
- break;
-
- case JSOP_URSH:
- {
- uint32 u;
-
- FETCH_INT(cx, -1, j);
- FETCH_UINT(cx, -2, u);
- j &= 31;
- d = u >> j;
- sp--;
- STORE_NUMBER(cx, -1, d);
- break;
- }
-
-#undef INTEGER_OP
-#undef BITWISE_OP
-#undef SIGNED_SHIFT_OP
-
- case JSOP_ADD:
- rval = FETCH_OPND(-1);
- lval = FETCH_OPND(-2);
- VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &ltmp);
- VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rtmp);
- if ((cond = JSVAL_IS_STRING(ltmp)) || JSVAL_IS_STRING(rtmp)) {
- if (cond) {
- str = JSVAL_TO_STRING(ltmp);
- SAVE_SP(fp);
- ok = (str2 = js_ValueToString(cx, rtmp)) != NULL;
- } else {
- str2 = JSVAL_TO_STRING(rtmp);
- SAVE_SP(fp);
- ok = (str = js_ValueToString(cx, ltmp)) != NULL;
- }
- if (!ok)
- goto out;
- str = js_ConcatStrings(cx, str, str2);
- if (!str) {
- ok = JS_FALSE;
- goto out;
- }
- sp--;
- STORE_OPND(-1, STRING_TO_JSVAL(str));
- } else {
- VALUE_TO_NUMBER(cx, lval, d);
- VALUE_TO_NUMBER(cx, rval, d2);
- d += d2;
- sp--;
- STORE_NUMBER(cx, -1, d);
- }
- break;
-
-#define BINARY_OP(OP) \
- JS_BEGIN_MACRO \
- FETCH_NUMBER(cx, -1, d2); \
- FETCH_NUMBER(cx, -2, d); \
- d = d OP d2; \
- sp--; \
- STORE_NUMBER(cx, -1, d); \
- JS_END_MACRO
-
- case JSOP_SUB:
- BINARY_OP(-);
- break;
-
- case JSOP_MUL:
- BINARY_OP(*);
- break;
-
- case JSOP_DIV:
- FETCH_NUMBER(cx, -1, d2);
- FETCH_NUMBER(cx, -2, d);
- sp--;
- if (d2 == 0) {
-#if defined(XP_WIN)
- /* XXX MSVC miscompiles such that (NaN == 0) */
- if (JSDOUBLE_IS_NaN(d2))
- rval = DOUBLE_TO_JSVAL(rt->jsNaN);
- else
-#endif
- if (d == 0 || JSDOUBLE_IS_NaN(d))
- rval = DOUBLE_TO_JSVAL(rt->jsNaN);
- else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
- rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
- else
- rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
- STORE_OPND(-1, rval);
- } else {
- d /= d2;
- STORE_NUMBER(cx, -1, d);
- }
- break;
-
- case JSOP_MOD:
- FETCH_NUMBER(cx, -1, d2);
- FETCH_NUMBER(cx, -2, d);
- sp--;
- if (d2 == 0) {
- STORE_OPND(-1, DOUBLE_TO_JSVAL(rt->jsNaN));
- } else {
-#if defined(XP_WIN)
- /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
- if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
-#endif
- d = fmod(d, d2);
- STORE_NUMBER(cx, -1, d);
- }
- break;
-
- case JSOP_NOT:
- POP_BOOLEAN(cx, rval, cond);
- PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));
- break;
-
- case JSOP_BITNOT:
- FETCH_INT(cx, -1, i);
- d = (jsdouble) ~i;
- STORE_NUMBER(cx, -1, d);
- break;
-
- case JSOP_NEG:
- FETCH_NUMBER(cx, -1, d);
-#ifdef HPUX
- /*
- * Negation of a zero doesn't produce a negative
- * zero on HPUX. Perform the operation by bit
- * twiddling.
- */
- JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;
-#else
- d = -d;
-#endif
- STORE_NUMBER(cx, -1, d);
- break;
-
- case JSOP_POS:
- FETCH_NUMBER(cx, -1, d);
- STORE_NUMBER(cx, -1, d);
- break;
-
- case JSOP_NEW:
- /* Get immediate argc and find the constructor function. */
- argc = GET_ARGC(pc);
-
-#if JS_HAS_INITIALIZERS
- do_new:
-#endif
- vp = sp - (2 + argc);
- JS_ASSERT(vp >= fp->spbase);
-
- fun = NULL;
- obj2 = NULL;
- lval = *vp;
- if (!JSVAL_IS_OBJECT(lval) ||
- (obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||
- /* XXX clean up to avoid special cases above ObjectOps layer */
- OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass ||
- !obj2->map->ops->construct)
- {
- SAVE_SP(fp);
- fun = js_ValueToFunction(cx, vp, JSV2F_CONSTRUCT);
- if (!fun) {
- ok = JS_FALSE;
- goto out;
- }
- }
-
- clasp = &js_ObjectClass;
- if (!obj2) {
- proto = parent = NULL;
- fun = NULL;
- } else {
- /* Get the constructor prototype object for this function. */
- ok = OBJ_GET_PROPERTY(cx, obj2,
- (jsid)rt->atomState.classPrototypeAtom,
- &rval);
- if (!ok)
- goto out;
- proto = JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : NULL;
- parent = OBJ_GET_PARENT(cx, obj2);
-
- if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) {
- funclasp = ((JSFunction *)JS_GetPrivate(cx, obj2))->clasp;
- if (funclasp)
- clasp = funclasp;
- }
- }
- obj = js_NewObject(cx, clasp, proto, parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
-
- /* Now we have an object with a constructor method; call it. */
- vp[1] = OBJECT_TO_JSVAL(obj);
- SAVE_SP(fp);
- ok = js_Invoke(cx, argc, JSINVOKE_CONSTRUCT);
- RESTORE_SP(fp);
- LOAD_INTERRUPT_HANDLER(rt);
- if (!ok) {
- cx->newborn[GCX_OBJECT] = NULL;
- goto out;
- }
-
- /* Check the return value and update obj from it. */
- rval = *vp;
- if (JSVAL_IS_PRIMITIVE(rval)) {
- if (fun || !JSVERSION_IS_ECMA(cx->version)) {
- *vp = OBJECT_TO_JSVAL(obj);
- break;
- }
- /* native [[Construct]] returning primitive is error */
- str = js_ValueToString(cx, rval);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_NEW_RESULT,
- JS_GetStringBytes(str));
- }
- ok = JS_FALSE;
- goto out;
- }
- obj = JSVAL_TO_OBJECT(rval);
- JS_RUNTIME_METER(rt, constructs);
- break;
-
- case JSOP_DELNAME:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
-
- SAVE_SP(fp);
- ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
- if (!ok)
- goto out;
-
- /* ECMA says to return true if name is undefined or inherited. */
- rval = JSVAL_TRUE;
- if (prop) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- }
- PUSH_OPND(rval);
- break;
-
- case JSOP_DELPROP:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- PROPERTY_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_DELELEM:
- ELEMENT_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));
- sp--;
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_TYPEOF:
- rval = POP_OPND();
- type = JS_TypeOfValue(cx, rval);
- atom = rt->atomState.typeAtoms[type];
- str = ATOM_TO_STRING(atom);
- PUSH_OPND(STRING_TO_JSVAL(str));
- break;
-
- case JSOP_VOID:
- (void) POP_OPND();
- PUSH_OPND(JSVAL_VOID);
- break;
-
- case JSOP_INCNAME:
- case JSOP_DECNAME:
- case JSOP_NAMEINC:
- case JSOP_NAMEDEC:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
-
- SAVE_SP(fp);
- ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
- if (!ok)
- goto out;
- if (!prop)
- goto atom_not_defined;
-
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- lval = OBJECT_TO_JSVAL(obj);
- goto do_incop;
-
- case JSOP_INCPROP:
- case JSOP_DECPROP:
- case JSOP_PROPINC:
- case JSOP_PROPDEC:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- lval = POP_OPND();
- goto do_incop;
-
- case JSOP_INCELEM:
- case JSOP_DECELEM:
- case JSOP_ELEMINC:
- case JSOP_ELEMDEC:
- POP_ELEMENT_ID(id);
- lval = POP_OPND();
-
- do_incop:
- VALUE_TO_OBJECT(cx, lval, obj);
-
- /* The operand must contain a number. */
- SAVE_SP(fp);
- CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval));
- if (!ok)
- goto out;
-
- /* The expression result goes in rtmp, the updated value in rval. */
- if (JSVAL_IS_INT(rval) &&
- rval != INT_TO_JSVAL(JSVAL_INT_MIN) &&
- rval != INT_TO_JSVAL(JSVAL_INT_MAX)) {
- if (cs->format & JOF_POST) {
- rtmp = rval;
- (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);
- } else {
- (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);
- rtmp = rval;
- }
- } else {
-
-/*
- * Initially, rval contains the value to increment or decrement, which is not
- * yet converted. As above, the expression result goes in rtmp, the updated
- * value goes in rval.
- */
-#define NONINT_INCREMENT_OP() \
- JS_BEGIN_MACRO \
- VALUE_TO_NUMBER(cx, rval, d); \
- if (cs->format & JOF_POST) { \
- rtmp = rval; \
- if (!JSVAL_IS_NUMBER(rtmp)) { \
- ok = js_NewNumberValue(cx, d, &rtmp); \
- if (!ok) \
- goto out; \
- } \
- (cs->format & JOF_INC) ? d++ : d--; \
- ok = js_NewNumberValue(cx, d, &rval); \
- } else { \
- (cs->format & JOF_INC) ? ++d : --d; \
- ok = js_NewNumberValue(cx, d, &rval); \
- rtmp = rval; \
- } \
- if (!ok) \
- goto out; \
- JS_END_MACRO
-
- NONINT_INCREMENT_OP();
- }
-
- CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
- if (!ok)
- goto out;
- PUSH_OPND(rtmp);
- break;
-
-/*
- * NB: This macro can't use JS_BEGIN_MACRO/JS_END_MACRO around its body because
- * it must break from the switch case that calls it, not from the do...while(0)
- * loop created by the JS_BEGIN/END_MACRO brackets.
- */
-#define FAST_INCREMENT_OP(SLOT,COUNT,BASE,PRE,OP,MINMAX) \
- slot = (uintN)SLOT; \
- JS_ASSERT(slot < fp->fun->COUNT); \
- vp = fp->BASE + slot; \
- rval = *vp; \
- if (JSVAL_IS_INT(rval) && \
- rval != INT_TO_JSVAL(JSVAL_INT_##MINMAX)) { \
- PRE = rval; \
- rval OP 2; \
- *vp = rval; \
- PUSH_OPND(PRE); \
- break; \
- } \
- goto do_nonint_fast_incop;
-
- case JSOP_INCARG:
- FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, +=, MAX);
- case JSOP_DECARG:
- FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, -=, MIN);
- case JSOP_ARGINC:
- FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, +=, MAX);
- case JSOP_ARGDEC:
- FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, -=, MIN);
-
- case JSOP_INCVAR:
- FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, +=, MAX);
- case JSOP_DECVAR:
- FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, -=, MIN);
- case JSOP_VARINC:
- FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, +=, MAX);
- case JSOP_VARDEC:
- FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, -=, MIN);
-
-#undef FAST_INCREMENT_OP
-
- do_nonint_fast_incop:
- NONINT_INCREMENT_OP();
- *vp = rval;
- PUSH_OPND(rtmp);
- break;
-
- case JSOP_GETPROP:
- /* Get an immediate atom naming the property. */
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- PROPERTY_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_SETPROP:
- /* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */
- rval = FETCH_OPND(-1);
-
- /* Get an immediate atom naming the property. */
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- PROPERTY_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));
- sp--;
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_GETELEM:
- ELEMENT_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));
- sp--;
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_SETELEM:
- rval = FETCH_OPND(-1);
- ELEMENT_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));
- sp -= 2;
- STORE_OPND(-1, rval);
- break;
-
- case JSOP_ENUMELEM:
- /* Funky: the value to set is under the [obj, id] pair. */
- FETCH_ELEMENT_ID(-1, id);
- lval = FETCH_OPND(-2);
- VALUE_TO_OBJECT(cx, lval, obj);
- rval = FETCH_OPND(-3);
- SAVE_SP(fp);
- ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- sp -= 3;
- break;
-
-/*
- * LAZY_ARGS_THISP allows the JSOP_ARGSUB bytecode to defer creation of the
- * arguments object until it is truly needed. JSOP_ARGSUB optimizes away
- * arguments objects when the only uses of the 'arguments' parameter are to
- * fetch individual actual parameters. But if such a use were then invoked,
- * e.g., arguments[i](), the 'this' parameter would and must bind to the
- * caller's arguments object. So JSOP_ARGSUB sets obj to LAZY_ARGS_THISP.
- */
-#define LAZY_ARGS_THISP ((JSObject *) 1)
-
- case JSOP_PUSHOBJ:
- if (obj == LAZY_ARGS_THISP && !(obj = js_GetArgsObject(cx, fp))) {
- ok = JS_FALSE;
- goto out;
- }
- PUSH_OPND(OBJECT_TO_JSVAL(obj));
- break;
-
- case JSOP_CALL:
- case JSOP_EVAL:
- argc = GET_ARGC(pc);
- vp = sp - (argc + 2);
- lval = *vp;
- SAVE_SP(fp);
-
- if (JSVAL_IS_FUNCTION(cx, lval) &&
- (obj = JSVAL_TO_OBJECT(lval),
- fun = (JSFunction *) JS_GetPrivate(cx, obj),
- !fun->native &&
- !(fun->flags & (JSFUN_HEAVYWEIGHT | JSFUN_BOUND_METHOD)) &&
- argc >= (uintN)(fun->nargs + fun->extra)))
- /* inline_call: */
- {
- uintN nframeslots, nvars;
- void *newmark;
- JSInlineFrame *newifp;
- JSInterpreterHook hook;
-
- /* Restrict recursion of lightweight functions. */
- if (inlineCallCount == MAX_INLINE_CALL_COUNT) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_OVER_RECURSED);
- ok = JS_FALSE;
- goto out;
- }
-
-#if JS_HAS_JIT
- /* ZZZbe should do this only if interpreted often enough. */
- ok = jsjit_Compile(cx, fun);
- if (!ok)
- goto out;
-#endif
-
- /* Compute the number of stack slots needed for fun. */
- nframeslots = (sizeof(JSInlineFrame) + sizeof(jsval) - 1)
- / sizeof(jsval);
- nvars = fun->nvars;
- script = fun->script;
- depth = (jsint) script->depth;
-
- /* Allocate the frame and space for vars and operands. */
- newsp = js_AllocRawStack(cx, nframeslots + nvars + 2 * depth,
- &newmark);
- if (!newsp) {
- ok = JS_FALSE;
- goto bad_inline_call;
- }
- newifp = (JSInlineFrame *) newsp;
- newsp += nframeslots;
-
- /* Initialize the stack frame. */
- memset(newifp, 0, sizeof(JSInlineFrame));
- newifp->frame.script = script;
- newifp->frame.fun = fun;
- newifp->frame.argc = argc;
- newifp->frame.argv = vp + 2;
- newifp->frame.rval = JSVAL_VOID;
- newifp->frame.nvars = nvars;
- newifp->frame.vars = newsp;
- newifp->frame.down = fp;
- newifp->frame.scopeChain = OBJ_GET_PARENT(cx, obj);
- newifp->mark = newmark;
-
- /* Compute the 'this' parameter now that argv is set. */
- ok = ComputeThis(cx, JSVAL_TO_OBJECT(vp[1]), &newifp->frame);
- if (!ok) {
- js_FreeRawStack(cx, newmark);
- goto bad_inline_call;
- }
-
- /* Push void to initialize local variables. */
- sp = newsp;
- while (nvars--)
- PUSH(JSVAL_VOID);
- sp += depth;
- newifp->frame.spbase = sp;
- SAVE_SP(&newifp->frame);
-
- /* Call the debugger hook if present. */
- hook = cx->runtime->callHook;
- if (hook) {
- newifp->hookData = hook(cx, &newifp->frame, JS_TRUE, 0,
- cx->runtime->callHookData);
- LOAD_INTERRUPT_HANDLER(rt);
- }
-
- /* Switch to new version if currentVersion wasn't overridden. */
- newifp->callerVersion = cx->version;
- if (cx->version == currentVersion) {
- currentVersion = script->version;
- if (currentVersion != cx->version)
- JS_SetVersion(cx, currentVersion);
- }
-
- /* Push the frame and set interpreter registers. */
- cx->fp = fp = &newifp->frame;
- pc = script->code;
- endpc = pc + script->length;
- inlineCallCount++;
- JS_RUNTIME_METER(rt, inlineCalls);
- continue;
-
- bad_inline_call:
- script = fp->script;
- depth = (jsint) script->depth;
- goto out;
- }
-
- ok = js_Invoke(cx, argc, 0);
- RESTORE_SP(fp);
- LOAD_INTERRUPT_HANDLER(rt);
- if (!ok)
- goto out;
- JS_RUNTIME_METER(rt, nonInlineCalls);
-#if JS_HAS_LVALUE_RETURN
- if (cx->rval2set) {
- /*
- * Sneaky: use the stack depth we didn't claim in our budget,
- * but that we know is there on account of [fun, this] already
- * having been pushed, at a minimum (if no args). Those two
- * slots have been popped and [rval] has been pushed, which
- * leaves one more slot for rval2 before we might overflow.
- *
- * NB: rval2 must be the property identifier, and rval the
- * object from which to get the property. The pair form an
- * ECMA "reference type", which can be used on the right- or
- * left-hand side of assignment ops. Only native methods can
- * return reference types. See JSOP_SETCALL just below for
- * the left-hand-side case.
- */
- PUSH_OPND(cx->rval2);
- cx->rval2set = JS_FALSE;
- ELEMENT_OP(-1, ok = OBJ_GET_PROPERTY(cx, obj, id, &rval));
- sp--;
- STORE_OPND(-1, rval);
- }
-#endif
- obj = NULL;
- break;
-
-#if JS_HAS_LVALUE_RETURN
- case JSOP_SETCALL:
- argc = GET_ARGC(pc);
- SAVE_SP(fp);
- ok = js_Invoke(cx, argc, 0);
- RESTORE_SP(fp);
- LOAD_INTERRUPT_HANDLER(rt);
- if (!ok)
- goto out;
- if (!cx->rval2set) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_LEFTSIDE_OF_ASS);
- ok = JS_FALSE;
- goto out;
- }
- PUSH_OPND(cx->rval2);
- cx->rval2set = JS_FALSE;
- obj = NULL;
- break;
-#endif
-
- case JSOP_NAME:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
-
- SAVE_SP(fp);
- ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
- if (!ok)
- goto out;
- if (!prop) {
- /* Kludge to allow (typeof foo == "undefined") tests. */
- for (pc2 = pc + len; pc2 < endpc; pc2++) {
- op2 = (JSOp)*pc2;
- if (op2 == JSOP_TYPEOF) {
- PUSH_OPND(JSVAL_VOID);
- goto advance_pc;
- }
- if (op2 != JSOP_GROUP)
- break;
- }
- goto atom_not_defined;
- }
-
- /* Take the slow path if prop was not found in a native object. */
- if (!OBJ_IS_NATIVE(obj) || !OBJ_IS_NATIVE(obj2)) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- PUSH_OPND(rval);
- break;
- }
-
- /* Get and push the obj[id] property's value. */
- sprop = (JSScopeProperty *)prop;
- slot = (uintN)sprop->slot;
- rval = (slot != SPROP_INVALID_SLOT)
- ? LOCKED_OBJ_GET_SLOT(obj2, slot)
- : JSVAL_VOID;
- JS_UNLOCK_OBJ(cx, obj2);
- ok = SPROP_GET(cx, sprop, obj, obj2, &rval);
- JS_LOCK_OBJ(cx, obj2);
- if (!ok) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- goto out;
- }
- if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)))
- LOCKED_OBJ_SET_SLOT(obj2, slot, rval);
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- PUSH_OPND(rval);
- break;
-
- case JSOP_UINT16:
- i = (jsint) GET_ATOM_INDEX(pc);
- rval = INT_TO_JSVAL(i);
- PUSH_OPND(rval);
- obj = NULL;
- break;
-
- case JSOP_NUMBER:
- case JSOP_STRING:
- atom = GET_ATOM(cx, script, pc);
- PUSH_OPND(ATOM_KEY(atom));
- obj = NULL;
- break;
-
- case JSOP_OBJECT:
- {
-#if 0
- jsatomid atomIndex;
- JSAtomMap *atomMap;
-
- /*
- * Get a suitable object from an atom mapped by the bytecode at pc.
- *
- * We must handle the case where a regexp object literal is used in
- * a different global at execution time from the global with which
- * it was scanned at compile time, in order to rewrap the JSRegExp
- * struct with a new object having the right prototype and parent.
- *
- * Unlike JSOP_DEFFUN and other prolog bytecodes, we don't want to
- * pay a script prolog execution price for all regexp literals in a
- * script (many may not be used by a particular execution of that
- * script, depending on control flow), so we do all fp->objAtomMap
- * initialization lazily, here under JSOP_OBJECT.
- *
- * XXX This code is specific to regular expression objects. If we
- * need JSOP_OBJECT for other kinds of object literals, we should
- * push cloning down under JSObjectOps. Also, fp->objAtomMap is
- * used only for object atoms, so it's sparse (wasting some stack
- * space) and as its name implies, you can't get non-object atoms
- * from it.
- */
- atomIndex = GET_ATOM_INDEX(pc);
- atomMap = fp->objAtomMap;
- atom = atomMap ? atomMap->vector[atomIndex] : NULL;
- if (!atom) {
- /* Let atom and obj denote the regexp (object) mapped by pc. */
- atom = js_GetAtom(cx, &script->atomMap, atomIndex);
- JS_ASSERT(ATOM_IS_OBJECT(atom));
- obj = ATOM_TO_OBJECT(atom);
- JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
-
- /* Compute the current global object in obj2. */
- obj2 = fp->scopeChain;
- while ((parent = OBJ_GET_PARENT(cx, obj2)) != NULL)
- obj2 = parent;
-
- /*
- * If obj's parent is not obj2, we must clone obj so that it
- * has the right parent, and therefore, the right prototype.
- *
- * Yes, this means we assume that the correct RegExp.prototype
- * to which regexp instances (including literals) delegate can
- * be distinguished solely by the instance's parent, which was
- * set to the parent of the RegExp constructor function object
- * when the instance was created. In other words,
- *
- * (/x/.__parent__ == RegExp.__parent__) implies
- * (/x/.__proto__ == RegExp.prototype)
- *
- * (unless you assign a different object to RegExp.prototype
- * at runtime, in which case, ECMA doesn't specify operation,
- * and you get what you deserve).
- *
- * This same coupling between instance parent and constructor
- * parent turns up elsewhere (see jsobj.c's FindConstructor,
- * js_ConstructObject, and js_NewObject). It's fundamental.
- */
- if (OBJ_GET_PARENT(cx, obj) != obj2) {
- obj = js_CloneRegExpObject(cx, obj, obj2);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
-
- atom = js_AtomizeObject(cx, obj, 0);
- if (!atom) {
- ok = JS_FALSE;
- goto out;
- }
- }
-
- /*
- * If fp->objAtomMap is null, initialize it now so we can map
- * atom (whether atom is newly created for a cloned object, or
- * the original atom mapped by script) for faster performance
- * next time through JSOP_OBJECT.
- */
- if (!atomMap) {
- jsatomid mapLength = script->atomMap.length;
- size_t vectorBytes = mapLength * sizeof(JSAtom *);
-
- /* Allocate an override atom map from cx->stackPool. */
- JS_ARENA_ALLOCATE_CAST(atomMap, JSAtomMap *,
- &cx->stackPool,
- sizeof(JSAtomMap) + vectorBytes);
- if (!atomMap) {
- JS_ReportOutOfMemory(cx);
- ok = JS_FALSE;
- goto out;
- }
-
- atomMap->length = mapLength;
- atomMap->vector = (JSAtom **)(atomMap + 1);
- memset(atomMap->vector, 0, vectorBytes);
- fp->objAtomMap = atomMap;
- }
- atomMap->vector[atomIndex] = atom;
- }
-#else
- atom = GET_ATOM(cx, script, pc);
- JS_ASSERT(ATOM_IS_OBJECT(atom));
-#endif
- rval = ATOM_KEY(atom);
- PUSH_OPND(rval);
- obj = NULL;
- break;
- }
-
- case JSOP_ZERO:
- PUSH_OPND(JSVAL_ZERO);
- obj = NULL;
- break;
-
- case JSOP_ONE:
- PUSH_OPND(JSVAL_ONE);
- obj = NULL;
- break;
-
- case JSOP_NULL:
- PUSH_OPND(JSVAL_NULL);
- obj = NULL;
- break;
-
- case JSOP_THIS:
- PUSH_OPND(OBJECT_TO_JSVAL(fp->thisp));
- obj = NULL;
- break;
-
- case JSOP_FALSE:
- PUSH_OPND(JSVAL_FALSE);
- obj = NULL;
- break;
-
- case JSOP_TRUE:
- PUSH_OPND(JSVAL_TRUE);
- obj = NULL;
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JSOP_TABLESWITCH:
- pc2 = pc;
- len = GET_JUMP_OFFSET(pc2);
-
- /*
- * ECMAv2 forbids conversion of discriminant, so we will skip to
- * the default case if the discriminant isn't already an int jsval.
- * (This opcode is emitted only for dense jsint-domain switches.)
- */
- if (cx->version == JSVERSION_DEFAULT ||
- cx->version >= JSVERSION_1_4) {
- rval = POP_OPND();
- if (!JSVAL_IS_INT(rval))
- break;
- i = JSVAL_TO_INT(rval);
- } else {
- FETCH_INT(cx, -1, i);
- sp--;
- }
-
- pc2 += JUMP_OFFSET_LEN;
- low = GET_JUMP_OFFSET(pc2);
- pc2 += JUMP_OFFSET_LEN;
- high = GET_JUMP_OFFSET(pc2);
-
- i -= low;
- if ((jsuint)i < (jsuint)(high - low + 1)) {
- pc2 += JUMP_OFFSET_LEN + JUMP_OFFSET_LEN * i;
- off = (jsint) GET_JUMP_OFFSET(pc2);
- if (off)
- len = off;
- }
- break;
-
- case JSOP_LOOKUPSWITCH:
- lval = POP_OPND();
- pc2 = pc;
- len = GET_JUMP_OFFSET(pc2);
-
- if (!JSVAL_IS_NUMBER(lval) &&
- !JSVAL_IS_STRING(lval) &&
- !JSVAL_IS_BOOLEAN(lval)) {
- goto advance_pc;
- }
-
- pc2 += JUMP_OFFSET_LEN;
- npairs = (jsint) GET_ATOM_INDEX(pc2);
- pc2 += ATOM_INDEX_LEN;
-
-#define SEARCH_PAIRS(MATCH_CODE) \
- while (npairs) { \
- atom = GET_ATOM(cx, script, pc2); \
- rval = ATOM_KEY(atom); \
- MATCH_CODE \
- if (match) { \
- pc2 += ATOM_INDEX_LEN; \
- len = GET_JUMP_OFFSET(pc2); \
- goto advance_pc; \
- } \
- pc2 += ATOM_INDEX_LEN + JUMP_OFFSET_LEN; \
- npairs--; \
- }
- if (JSVAL_IS_STRING(lval)) {
- str = JSVAL_TO_STRING(lval);
- SEARCH_PAIRS(
- match = (JSVAL_IS_STRING(rval) &&
- ((str2 = JSVAL_TO_STRING(rval)) == str ||
- !js_CompareStrings(str2, str)));
- )
- } else if (JSVAL_IS_DOUBLE(lval)) {
- d = *JSVAL_TO_DOUBLE(lval);
- SEARCH_PAIRS(
- match = (JSVAL_IS_DOUBLE(rval) &&
- *JSVAL_TO_DOUBLE(rval) == d);
- )
- } else {
- SEARCH_PAIRS(
- match = (lval == rval);
- )
- }
-#undef SEARCH_PAIRS
- break;
-
- case JSOP_TABLESWITCHX:
- pc2 = pc;
- len = GET_JUMPX_OFFSET(pc2);
-
- /*
- * ECMAv2 forbids conversion of discriminant, so we will skip to
- * the default case if the discriminant isn't already an int jsval.
- * (This opcode is emitted only for dense jsint-domain switches.)
- */
- if (cx->version == JSVERSION_DEFAULT ||
- cx->version >= JSVERSION_1_4) {
- rval = POP_OPND();
- if (!JSVAL_IS_INT(rval))
- break;
- i = JSVAL_TO_INT(rval);
- } else {
- FETCH_INT(cx, -1, i);
- sp--;
- }
-
- pc2 += JUMPX_OFFSET_LEN;
- low = GET_JUMP_OFFSET(pc2);
- pc2 += JUMP_OFFSET_LEN;
- high = GET_JUMP_OFFSET(pc2);
-
- i -= low;
- if ((jsuint)i < (jsuint)(high - low + 1)) {
- pc2 += JUMP_OFFSET_LEN + JUMPX_OFFSET_LEN * i;
- off = (jsint) GET_JUMPX_OFFSET(pc2);
- if (off)
- len = off;
- }
- break;
-
- case JSOP_LOOKUPSWITCHX:
- lval = POP_OPND();
- pc2 = pc;
- len = GET_JUMPX_OFFSET(pc2);
-
- if (!JSVAL_IS_NUMBER(lval) &&
- !JSVAL_IS_STRING(lval) &&
- !JSVAL_IS_BOOLEAN(lval)) {
- goto advance_pc;
- }
-
- pc2 += JUMPX_OFFSET_LEN;
- npairs = (jsint) GET_ATOM_INDEX(pc2);
- pc2 += ATOM_INDEX_LEN;
-
-#define SEARCH_EXTENDED_PAIRS(MATCH_CODE) \
- while (npairs) { \
- atom = GET_ATOM(cx, script, pc2); \
- rval = ATOM_KEY(atom); \
- MATCH_CODE \
- if (match) { \
- pc2 += ATOM_INDEX_LEN; \
- len = GET_JUMPX_OFFSET(pc2); \
- goto advance_pc; \
- } \
- pc2 += ATOM_INDEX_LEN + JUMPX_OFFSET_LEN; \
- npairs--; \
- }
- if (JSVAL_IS_STRING(lval)) {
- str = JSVAL_TO_STRING(lval);
- SEARCH_EXTENDED_PAIRS(
- match = (JSVAL_IS_STRING(rval) &&
- ((str2 = JSVAL_TO_STRING(rval)) == str ||
- !js_CompareStrings(str2, str)));
- )
- } else if (JSVAL_IS_DOUBLE(lval)) {
- d = *JSVAL_TO_DOUBLE(lval);
- SEARCH_EXTENDED_PAIRS(
- match = (JSVAL_IS_DOUBLE(rval) &&
- *JSVAL_TO_DOUBLE(rval) == d);
- )
- } else {
- SEARCH_EXTENDED_PAIRS(
- match = (lval == rval);
- )
- }
-#undef SEARCH_EXTENDED_PAIRS
- break;
-
- case JSOP_CONDSWITCH:
- break;
-
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
-#if JS_HAS_EXPORT_IMPORT
- case JSOP_EXPORTALL:
- obj = fp->varobj;
- ida = JS_Enumerate(cx, obj);
- if (!ida) {
- ok = JS_FALSE;
- } else {
- for (i = 0, j = ida->length; i < j; i++) {
- id = ida->vector[i];
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ok)
- break;
- if (!prop)
- continue;
- ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
- if (ok) {
- attrs |= JSPROP_EXPORTED;
- ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (!ok)
- break;
- }
- JS_DestroyIdArray(cx, ida);
- }
- break;
-
- case JSOP_EXPORTNAME:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- obj = fp->varobj;
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ok)
- goto out;
- if (!prop) {
- ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
- JSPROP_EXPORTED, NULL);
- } else {
- ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
- if (ok) {
- attrs |= JSPROP_EXPORTED;
- ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- }
- if (!ok)
- goto out;
- break;
-
- case JSOP_IMPORTALL:
- id = (jsid)JSVAL_VOID;
- PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));
- sp--;
- break;
-
- case JSOP_IMPORTPROP:
- /* Get an immediate atom naming the property. */
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));
- sp--;
- break;
-
- case JSOP_IMPORTELEM:
- ELEMENT_OP(-1, ok = ImportProperty(cx, obj, id));
- sp -= 2;
- break;
-#endif /* JS_HAS_EXPORT_IMPORT */
-
- case JSOP_TRAP:
- switch (JS_HandleTrap(cx, script, pc, &rval)) {
- case JSTRAP_ERROR:
- ok = JS_FALSE;
- goto out;
- case JSTRAP_CONTINUE:
- JS_ASSERT(JSVAL_IS_INT(rval));
- op = (JSOp) JSVAL_TO_INT(rval);
- JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT);
- LOAD_INTERRUPT_HANDLER(rt);
- goto do_op;
- case JSTRAP_RETURN:
- fp->rval = rval;
- goto out;
-#if JS_HAS_EXCEPTIONS
- case JSTRAP_THROW:
- cx->throwing = JS_TRUE;
- cx->exception = rval;
- ok = JS_FALSE;
- goto out;
-#endif /* JS_HAS_EXCEPTIONS */
- default:;
- }
- LOAD_INTERRUPT_HANDLER(rt);
- break;
-
- case JSOP_ARGUMENTS:
- SAVE_SP(fp);
- ok = js_GetArgsValue(cx, fp, &rval);
- if (!ok)
- goto out;
- PUSH_OPND(rval);
- break;
-
- case JSOP_ARGSUB:
- id = (jsid) INT_TO_JSVAL(GET_ARGNO(pc));
- SAVE_SP(fp);
- ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);
- if (!ok)
- goto out;
- if (!obj) {
- /*
- * If arguments was not overridden by eval('arguments = ...'),
- * set obj to the magic cookie respected by JSOP_PUSHOBJ, just
- * in case this bytecode is part of an 'arguments[i](j, k)' or
- * similar such invocation sequence, where the function that
- * is invoked expects its 'this' parameter to be the caller's
- * arguments object.
- */
- obj = LAZY_ARGS_THISP;
- }
- PUSH_OPND(rval);
- break;
-
-#undef LAZY_ARGS_THISP
-
- case JSOP_ARGCNT:
- id = (jsid) rt->atomState.lengthAtom;
- SAVE_SP(fp);
- ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);
- if (!ok)
- goto out;
- PUSH_OPND(rval);
- break;
-
- case JSOP_GETARG:
- slot = GET_ARGNO(pc);
- JS_ASSERT(slot < fp->fun->nargs);
- PUSH_OPND(fp->argv[slot]);
- obj = NULL;
- break;
-
- case JSOP_SETARG:
- slot = GET_ARGNO(pc);
- JS_ASSERT(slot < fp->fun->nargs);
- vp = &fp->argv[slot];
- GC_POKE(cx, *vp);
- *vp = FETCH_OPND(-1);
- obj = NULL;
- break;
-
- case JSOP_GETVAR:
- slot = GET_VARNO(pc);
- JS_ASSERT(slot < fp->fun->nvars);
- PUSH_OPND(fp->vars[slot]);
- obj = NULL;
- break;
-
- case JSOP_SETVAR:
- slot = GET_VARNO(pc);
- JS_ASSERT(slot < fp->fun->nvars);
- vp = &fp->vars[slot];
- GC_POKE(cx, *vp);
- *vp = FETCH_OPND(-1);
- obj = NULL;
- break;
-
- case JSOP_DEFCONST:
- case JSOP_DEFVAR:
- {
- JSBool defined;
-
- atom = GET_ATOM(cx, script, pc);
- obj = fp->varobj;
- attrs = JSPROP_ENUMERATE;
- if (!(fp->flags & JSFRAME_EVAL))
- attrs |= JSPROP_PERMANENT;
- if (op == JSOP_DEFCONST)
- attrs |= JSPROP_READONLY;
-
- /* Lookup id in order to check for redeclaration problems. */
- id = (jsid)atom;
- ok = js_CheckRedeclaration(cx, obj, id, attrs, &defined);
- if (!ok)
- goto out;
-
- /* Bind a variable only if it's not yet defined. */
- if (!defined) {
- ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
- attrs, NULL);
- if (!ok)
- goto out;
- }
- break;
- }
-
- case JSOP_DEFFUN:
- {
- uintN flags;
-
- atom = GET_ATOM(cx, script, pc);
- obj = ATOM_TO_OBJECT(atom);
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- id = (jsid) fun->atom;
-
- /*
- * We must be at top-level (either outermost block that forms a
- * function's body, or a global) scope, not inside an expression
- * (JSOP_{ANON,NAMED}FUNOBJ) or compound statement (JSOP_CLOSURE)
- * in the same compilation unit (ECMA Program).
- *
- * However, we could be in a Program being eval'd from inside a
- * with statement, so we need to distinguish variables object from
- * scope chain head. Hence the two assignments to parent below.
- * First we make sure the function object we're defining has the
- * right scope chain. Then we define its name in fp->varobj.
- *
- * If static link is not current scope, clone fun's object to link
- * to the current scope via parent. This clause exists to enable
- * sharing of compiled functions among multiple equivalent scopes,
- * splitting the cost of compilation evenly among the scopes and
- * amortizing it over a number of executions. Examples include XUL
- * scripts and event handlers shared among Mozilla chrome windows,
- * and server-side JS user-defined functions shared among requests.
- *
- * NB: The Script object exposes compile and exec in the language,
- * such that this clause introduces an incompatible change from old
- * JS versions that supported Script. Such a JS version supported
- * executing a script that defined and called functions scoped by
- * the compile-time static link, not by the exec-time scope chain.
- *
- * We sacrifice compatibility, breaking such scripts, in order to
- * promote compile-cost sharing and amortizing, and because Script
- * is not and will not be standardized.
- */
- parent = fp->scopeChain;
- if (OBJ_GET_PARENT(cx, obj) != parent) {
- obj = js_CloneFunctionObject(cx, obj, parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- }
-
- /*
- * ECMA requires functions defined when entering Global code to be
- * permanent, and functions defined when entering Eval code to be
- * impermanent.
- */
- attrs = JSPROP_ENUMERATE;
- if (!(fp->flags & JSFRAME_EVAL))
- attrs |= JSPROP_PERMANENT;
-
- /*
- * Load function flags that are also property attributes. Getters
- * and setters do not need a slot, their value is stored elsewhere
- * in the property itself, not in obj->slots.
- */
- flags = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
- if (flags)
- attrs |= flags | JSPROP_SHARED;
-
- /*
- * Check for a const property of the same name -- or any kind
- * of property if executing with the strict option. We check
- * here at runtime as well as at compile-time, to handle eval
- * as well as multiple HTML script tags.
- */
- parent = fp->varobj;
- ok = js_CheckRedeclaration(cx, parent, id, attrs, &cond);
- if (!ok)
- goto out;
-
- ok = OBJ_DEFINE_PROPERTY(cx, parent, id,
- flags ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),
- (flags & JSFUN_GETTER)
- ? (JSPropertyOp) obj
- : NULL,
- (flags & JSFUN_SETTER)
- ? (JSPropertyOp) obj
- : NULL,
- attrs,
- NULL);
- if (!ok)
- goto out;
- break;
- }
-
-#if JS_HAS_LEXICAL_CLOSURE
- case JSOP_DEFLOCALFUN:
- /*
- * Define a local function (i.e., one nested at the top level of
- * another function), parented by the current scope chain, and
- * stored in a local variable slot that the compiler allocated.
- * This is an optimization over JSOP_DEFFUN that avoids requiring
- * a call object for the outer function's activation.
- */
- pc2 = pc;
- slot = GET_VARNO(pc2);
- pc2 += VARNO_LEN;
- atom = GET_ATOM(cx, script, pc2);
- obj = ATOM_TO_OBJECT(atom);
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
-
- parent = fp->scopeChain;
- if (OBJ_GET_PARENT(cx, obj) != parent) {
- obj = js_CloneFunctionObject(cx, obj, parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- }
- fp->vars[slot] = OBJECT_TO_JSVAL(obj);
- break;
-
- case JSOP_ANONFUNOBJ:
- /* Push the specified function object literal. */
- atom = GET_ATOM(cx, script, pc);
- obj = ATOM_TO_OBJECT(atom);
-
- /* If re-parenting, push a clone of the function object. */
- parent = fp->scopeChain;
- if (OBJ_GET_PARENT(cx, obj) != parent) {
- obj = js_CloneFunctionObject(cx, obj, parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- }
- PUSH_OPND(OBJECT_TO_JSVAL(obj));
- break;
-
- case JSOP_NAMEDFUNOBJ:
- /* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */
- atom = GET_ATOM(cx, script, pc);
- rval = ATOM_KEY(atom);
- JS_ASSERT(JSVAL_IS_FUNCTION(cx, rval));
-
- /*
- * 1. Create a new object as if by the expression new Object().
- * 2. Add Result(1) to the front of the scope chain.
- *
- * Step 2 is achieved by making the new object's parent be the
- * current scope chain, and then making the new object the parent
- * of the Function object clone.
- */
- SAVE_SP(fp);
- parent = js_ConstructObject(cx, &js_ObjectClass, NULL,
- fp->scopeChain, 0, NULL);
- if (!parent) {
- ok = JS_FALSE;
- goto out;
- }
-
- /*
- * 3. Create a new Function object as specified in section 13.2
- * with [parameters and body specified by the function expression
- * that was parsed by the compiler into a Function object, and
- * saved in the script's atom map].
- */
- obj = js_CloneFunctionObject(cx, JSVAL_TO_OBJECT(rval), parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
-
- /*
- * 4. Create a property in the object Result(1). The property's
- * name is [fun->atom, the identifier parsed by the compiler],
- * value is Result(3), and attributes are { DontDelete, ReadOnly }.
- */
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
- if (attrs)
- attrs |= JSPROP_SHARED;
- ok = OBJ_DEFINE_PROPERTY(cx, parent, (jsid)fun->atom,
- attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),
- (attrs & JSFUN_GETTER)
- ? (JSPropertyOp) obj
- : NULL,
- (attrs & JSFUN_SETTER)
- ? (JSPropertyOp) obj
- : NULL,
- attrs |
- JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_READONLY,
- NULL);
- if (!ok) {
- cx->newborn[GCX_OBJECT] = NULL;
- goto out;
- }
-
- /*
- * 5. Remove Result(1) from the front of the scope chain [no-op].
- * 6. Return Result(3).
- */
- PUSH_OPND(OBJECT_TO_JSVAL(obj));
- break;
-
- case JSOP_CLOSURE:
- /*
- * ECMA ed. 3 extension: a named function expression in a compound
- * statement (not at the top statement level of global code, or at
- * the top level of a function body).
- *
- * Get immediate operand atom, which is a function object literal.
- * From it, get the function to close.
- */
- atom = GET_ATOM(cx, script, pc);
- JS_ASSERT(JSVAL_IS_FUNCTION(cx, ATOM_KEY(atom)));
- obj = ATOM_TO_OBJECT(atom);
-
- /*
- * Clone the function object with the current scope chain as the
- * clone's parent. The original function object is the prototype
- * of the clone. Do this only if re-parenting; the compiler may
- * have seen the right parent already and created a sufficiently
- * well-scoped function object.
- */
- parent = fp->scopeChain;
- if (OBJ_GET_PARENT(cx, obj) != parent) {
- obj = js_CloneFunctionObject(cx, obj, parent);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- }
-
- /*
- * Make a property in fp->varobj with id fun->atom and value obj,
- * unless fun is a getter or setter (in which case, obj is cast to
- * a JSPropertyOp and passed accordingly).
- */
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
- if (attrs)
- attrs |= JSPROP_SHARED;
- ok = OBJ_DEFINE_PROPERTY(cx, fp->varobj, (jsid)fun->atom,
- attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),
- (attrs & JSFUN_GETTER)
- ? (JSPropertyOp) obj
- : NULL,
- (attrs & JSFUN_SETTER)
- ? (JSPropertyOp) obj
- : NULL,
- attrs | JSPROP_ENUMERATE,
- NULL);
- if (!ok) {
- cx->newborn[GCX_OBJECT] = NULL;
- goto out;
- }
- break;
-#endif /* JS_HAS_LEXICAL_CLOSURE */
-
-#if JS_HAS_GETTER_SETTER
- case JSOP_GETTER:
- case JSOP_SETTER:
- JS_ASSERT(len == 1);
- op2 = (JSOp) *++pc;
- cs = &js_CodeSpec[op2];
- len = cs->length;
- switch (op2) {
- case JSOP_SETNAME:
- case JSOP_SETPROP:
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- i = -1;
- rval = FETCH_OPND(i);
- goto gs_pop_lval;
-
- case JSOP_SETELEM:
- rval = FETCH_OPND(-1);
- i = -2;
- FETCH_ELEMENT_ID(i, id);
- gs_pop_lval:
- lval = FETCH_OPND(i-1);
- VALUE_TO_OBJECT(cx, lval, obj);
- break;
-
-#if JS_HAS_INITIALIZERS
- case JSOP_INITPROP:
- JS_ASSERT(sp - fp->spbase >= 2);
- i = -1;
- rval = FETCH_OPND(i);
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- goto gs_get_lval;
-
- case JSOP_INITELEM:
- JS_ASSERT(sp - fp->spbase >= 3);
- rval = FETCH_OPND(-1);
- i = -2;
- FETCH_ELEMENT_ID(i, id);
- gs_get_lval:
- lval = FETCH_OPND(i-1);
- JS_ASSERT(JSVAL_IS_OBJECT(lval));
- obj = JSVAL_TO_OBJECT(lval);
- break;
-#endif /* JS_HAS_INITIALIZERS */
-
- default:
- JS_ASSERT(0);
- }
-
- if (JS_TypeOfValue(cx, rval) != JSTYPE_FUNCTION) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_GETTER_OR_SETTER,
- (op == JSOP_GETTER)
- ? js_getter_str
- : js_setter_str);
- ok = JS_FALSE;
- goto out;
- }
-
- /*
- * Getters and setters are just like watchpoints from an access
- * control point of view.
- */
- ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &rtmp, &attrs);
- if (!ok)
- goto out;
-
- if (op == JSOP_GETTER) {
- getter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);
- setter = NULL;
- attrs = JSPROP_GETTER;
- } else {
- getter = NULL;
- setter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);
- attrs = JSPROP_SETTER;
- }
- attrs |= JSPROP_ENUMERATE | JSPROP_SHARED;
-
- /* Check for a readonly or permanent property of the same name. */
- ok = js_CheckRedeclaration(cx, obj, id, attrs, &cond);
- if (!ok)
- goto out;
-
- ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, getter, setter,
- attrs, NULL);
- if (!ok)
- goto out;
-
- sp += i;
- if (cs->ndefs)
- STORE_OPND(-1, rval);
- break;
-#endif /* JS_HAS_GETTER_SETTER */
-
-#if JS_HAS_INITIALIZERS
- case JSOP_NEWINIT:
- argc = 0;
- fp->sharpDepth++;
- goto do_new;
-
- case JSOP_ENDINIT:
- if (--fp->sharpDepth == 0)
- fp->sharpArray = NULL;
-
- /* Re-set the newborn root to the top of this object tree. */
- JS_ASSERT(sp - fp->spbase >= 1);
- lval = FETCH_OPND(-1);
- JS_ASSERT(JSVAL_IS_OBJECT(lval));
- cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(lval);
- break;
-
- case JSOP_INITPROP:
- /* Pop the property's value into rval. */
- JS_ASSERT(sp - fp->spbase >= 2);
- rval = FETCH_OPND(-1);
-
- /* Get the immediate property name into id. */
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
- i = -1;
- goto do_init;
-
- case JSOP_INITELEM:
- /* Pop the element's value into rval. */
- JS_ASSERT(sp - fp->spbase >= 3);
- rval = FETCH_OPND(-1);
-
- /* Pop and conditionally atomize the element id. */
- FETCH_ELEMENT_ID(-2, id);
- i = -2;
-
- do_init:
- /* Find the object being initialized at top of stack. */
- lval = FETCH_OPND(i-1);
- JS_ASSERT(JSVAL_IS_OBJECT(lval));
- obj = JSVAL_TO_OBJECT(lval);
-
- /* Set the property named by obj[id] to rval. */
- ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- sp += i;
- break;
-
-#if JS_HAS_SHARP_VARS
- case JSOP_DEFSHARP:
- obj = fp->sharpArray;
- if (!obj) {
- obj = js_NewArrayObject(cx, 0, NULL);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- fp->sharpArray = obj;
- }
- i = (jsint) GET_ATOM_INDEX(pc);
- id = (jsid) INT_TO_JSVAL(i);
- rval = FETCH_OPND(-1);
- if (JSVAL_IS_PRIMITIVE(rval)) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_SHARP_DEF, numBuf);
- ok = JS_FALSE;
- goto out;
- }
- ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- break;
-
- case JSOP_USESHARP:
- i = (jsint) GET_ATOM_INDEX(pc);
- id = (jsid) INT_TO_JSVAL(i);
- obj = fp->sharpArray;
- if (!obj) {
- rval = JSVAL_VOID;
- } else {
- ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);
- if (!ok)
- goto out;
- }
- if (!JSVAL_IS_OBJECT(rval)) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_SHARP_USE, numBuf);
- ok = JS_FALSE;
- goto out;
- }
- PUSH_OPND(rval);
- break;
-#endif /* JS_HAS_SHARP_VARS */
-#endif /* JS_HAS_INITIALIZERS */
-
-#if JS_HAS_EXCEPTIONS
- /* No-ops for ease of decompilation and jit'ing. */
- case JSOP_TRY:
- case JSOP_FINALLY:
- break;
-
- /* Reset the stack to the given depth. */
- case JSOP_SETSP:
- i = (jsint) GET_ATOM_INDEX(pc);
- JS_ASSERT(i >= 0);
- sp = fp->spbase + i;
- break;
-
- case JSOP_GOSUB:
- i = PTRDIFF(pc, script->main, jsbytecode) + len;
- len = GET_JUMP_OFFSET(pc);
- PUSH(INT_TO_JSVAL(i));
- break;
-
- case JSOP_GOSUBX:
- i = PTRDIFF(pc, script->main, jsbytecode) + len;
- len = GET_JUMPX_OFFSET(pc);
- PUSH(INT_TO_JSVAL(i));
- break;
-
- case JSOP_RETSUB:
- rval = POP();
- JS_ASSERT(JSVAL_IS_INT(rval));
- i = JSVAL_TO_INT(rval);
- pc = script->main + i;
- len = 0;
- break;
-
- case JSOP_EXCEPTION:
- PUSH(cx->exception);
- break;
-
- case JSOP_THROW:
- cx->throwing = JS_TRUE;
- cx->exception = POP_OPND();
- ok = JS_FALSE;
- /* let the code at out try to catch the exception. */
- goto out;
-
- case JSOP_INITCATCHVAR:
- /* Pop the property's value into rval. */
- JS_ASSERT(sp - fp->spbase >= 2);
- rval = POP_OPND();
-
- /* Get the immediate catch variable name into id. */
- atom = GET_ATOM(cx, script, pc);
- id = (jsid)atom;
-
- /* Find the object being initialized at top of stack. */
- lval = FETCH_OPND(-1);
- JS_ASSERT(JSVAL_IS_OBJECT(lval));
- obj = JSVAL_TO_OBJECT(lval);
-
- /* Define obj[id] to contain rval and to be permanent. */
- ok = OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL,
- JSPROP_PERMANENT, NULL);
- if (!ok)
- goto out;
- break;
-#endif /* JS_HAS_EXCEPTIONS */
-
-#if JS_HAS_INSTANCEOF
- case JSOP_INSTANCEOF:
- rval = FETCH_OPND(-1);
- if (JSVAL_IS_PRIMITIVE(rval)) {
- SAVE_SP(fp);
- str = js_DecompileValueGenerator(cx, -1, rval, NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_INSTANCEOF_RHS,
- JS_GetStringBytes(str));
- }
- ok = JS_FALSE;
- goto out;
- }
- obj = JSVAL_TO_OBJECT(rval);
- lval = FETCH_OPND(-2);
- cond = JS_FALSE;
- if (obj->map->ops->hasInstance) {
- SAVE_SP(fp);
- ok = obj->map->ops->hasInstance(cx, obj, lval, &cond);
- if (!ok)
- goto out;
- }
- sp--;
- STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));
- break;
-#endif /* JS_HAS_INSTANCEOF */
-
-#if JS_HAS_DEBUGGER_KEYWORD
- case JSOP_DEBUGGER:
- {
- JSTrapHandler handler = rt->debuggerHandler;
- if (handler) {
- SAVE_SP(fp);
- switch (handler(cx, script, pc, &rval,
- rt->debuggerHandlerData)) {
- case JSTRAP_ERROR:
- ok = JS_FALSE;
- goto out;
- case JSTRAP_CONTINUE:
- break;
- case JSTRAP_RETURN:
- fp->rval = rval;
- goto out;
-#if JS_HAS_EXCEPTIONS
- case JSTRAP_THROW:
- cx->throwing = JS_TRUE;
- cx->exception = rval;
- ok = JS_FALSE;
- goto out;
-#endif /* JS_HAS_EXCEPTIONS */
- default:;
- }
- LOAD_INTERRUPT_HANDLER(rt);
- }
- break;
- }
-#endif /* JS_HAS_DEBUGGER_KEYWORD */
-
- default: {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%d", op);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_BYTECODE, numBuf);
- ok = JS_FALSE;
- goto out;
- }
- }
-
- advance_pc:
- pc += len;
-
-#ifdef DEBUG
- if (tracefp) {
- intN ndefs, n;
- jsval *siter;
-
- ndefs = cs->ndefs;
- if (ndefs) {
- SAVE_SP(fp);
- for (n = -ndefs; n < 0; n++) {
- str = js_DecompileValueGenerator(cx, n, sp[n], NULL);
- if (str) {
- fprintf(tracefp, "%s %s",
- (n == -ndefs) ? " output:" : ",",
- JS_GetStringBytes(str));
- }
- }
- fprintf(tracefp, " @ %d\n", sp - fp->spbase);
- }
- fprintf(tracefp, " stack: ");
- for (siter = fp->spbase; siter < sp; siter++) {
- str = js_ValueToSource(cx, *siter);
- fprintf(tracefp, "%s ",
- str ? JS_GetStringBytes(str) : "<null>");
- }
- fputc('\n', tracefp);
- }
-#endif
- }
-out:
-
-#if JS_HAS_EXCEPTIONS
- /*
- * Has an exception been raised?
- */
- if (!ok && cx->throwing) {
- /*
- * Call debugger throw hook if set (XXX thread safety?).
- */
- JSTrapHandler handler = rt->throwHook;
- if (handler) {
- SAVE_SP(fp);
- switch (handler(cx, script, pc, &rval, rt->throwHookData)) {
- case JSTRAP_ERROR:
- cx->throwing = JS_FALSE;
- goto no_catch;
- case JSTRAP_RETURN:
- ok = JS_TRUE;
- cx->throwing = JS_FALSE;
- fp->rval = rval;
- goto no_catch;
- case JSTRAP_THROW:
- cx->exception = rval;
- case JSTRAP_CONTINUE:
- default:;
- }
- LOAD_INTERRUPT_HANDLER(rt);
- }
-
- /*
- * Look for a try block within this frame that can catch the exception.
- */
- SCRIPT_FIND_CATCH_START(script, pc, pc);
- if (pc) {
- len = 0;
- cx->throwing = JS_FALSE; /* caught */
- ok = JS_TRUE;
- goto advance_pc;
- }
- }
-no_catch:
-#endif
-
- /*
- * Check whether control fell off the end of a lightweight function, or an
- * exception thrown under such a function was not caught by it. If so, go
- * to the inline code under JSOP_RETURN.
- */
- if (inlineCallCount)
- goto inline_return;
-
- /*
- * Reset sp before freeing stack slots, because our caller may GC soon.
- * Clear spbase to indicate that we've popped the 2 * depth operand slots.
- * Restore the previous frame's execution state.
- */
- fp->sp = fp->spbase;
- fp->spbase = NULL;
- js_FreeRawStack(cx, mark);
- if (cx->version == currentVersion && currentVersion != originalVersion)
- JS_SetVersion(cx, originalVersion);
- cx->interpLevel--;
- return ok;
-
-atom_not_defined:
- {
- const char *printable = js_AtomToPrintableString(cx, atom);
- if (printable)
- js_ReportIsNotDefined(cx, printable);
- ok = JS_FALSE;
- goto out;
- }
-}
diff --git a/src/extension/script/js/jsinterp.h b/src/extension/script/js/jsinterp.h
deleted file mode 100644
index 3e0634e4d..000000000
--- a/src/extension/script/js/jsinterp.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsinterp_h___
-#define jsinterp_h___
-/*
- * JS interpreter interface.
- */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * JS stack frame, allocated on the C stack.
- */
-struct JSStackFrame {
- JSObject *callobj; /* lazily created Call object */
- JSObject *argsobj; /* lazily created arguments object */
- JSObject *varobj; /* variables object, where vars go */
- 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 */
- jsval *spbase; /* operand stack base */
- uintN sharpDepth; /* array/object initializer depth */
- JSObject *sharpArray; /* scope for #n= initializer vars */
- uint32 flags; /* frame flags -- see below */
- JSStackFrame *dormantNext; /* next dormant frame chain */
- JSAtomMap *objAtomMap; /* object atom map, non-null only if we
- hit a regexp object literal */
-};
-
-typedef struct JSInlineFrame {
- JSStackFrame frame; /* base struct */
- void *mark; /* mark before inline frame */
- void *hookData; /* debugger call hook data */
- JSVersion callerVersion; /* dynamic version of calling script */
-} JSInlineFrame;
-
-/* JS stack frame flags. */
-#define JSFRAME_CONSTRUCTING 0x01 /* frame is for a constructor invocation */
-#define JSFRAME_INTERNAL 0x02 /* internal call, not invoked by a script */
-#define JSFRAME_SKIP_CALLER 0x04 /* skip one link when evaluating f.caller
- for this invocation of f */
-#define JSFRAME_ASSIGNING 0x08 /* a complex (not simplex JOF_ASSIGNING) op
- is currently assigning to a property */
-#define JSFRAME_DEBUGGER 0x10 /* frame for JS_EvaluateInStackFrame */
-#define JSFRAME_EVAL 0x20 /* frame for obj_eval */
-#define JSFRAME_SPECIAL 0x30 /* special evaluation frame flags */
-
-#define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */
-#define JSFRAME_OVERRIDE_BITS 8
-
-/*
- * Property cache for quickened get/set property opcodes.
- */
-#define PROPERTY_CACHE_LOG2 10
-#define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2)
-#define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2)
-
-#define PROPERTY_CACHE_HASH(obj, id) \
- ((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK)
-
-#ifdef JS_THREADSAFE
-
-#if HAVE_ATOMIC_DWORD_ACCESS
-
-#define PCE_LOAD(cache, pce, entry) JS_ATOMIC_DWORD_LOAD(pce, entry)
-#define PCE_STORE(cache, pce, entry) JS_ATOMIC_DWORD_STORE(pce, entry)
-
-#else /* !HAVE_ATOMIC_DWORD_ACCESS */
-
-#define JS_PROPERTY_CACHE_METERING 1
-
-#define PCE_LOAD(cache, pce, entry) \
- JS_BEGIN_MACRO \
- uint32 prefills_; \
- uint32 fills_ = (cache)->fills; \
- do { \
- /* Load until cache->fills is stable (see FILL macro below). */ \
- prefills_ = fills_; \
- (entry) = *(pce); \
- } while ((fills_ = (cache)->fills) != prefills_); \
- JS_END_MACRO
-
-#define PCE_STORE(cache, pce, entry) \
- JS_BEGIN_MACRO \
- do { \
- /* Store until no racing collider stores half or all of pce. */ \
- *(pce) = (entry); \
- } while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) || \
- PCE_PROPERTY(*pce) != PCE_PROPERTY(entry)); \
- JS_END_MACRO
-
-#endif /* !HAVE_ATOMIC_DWORD_ACCESS */
-
-#else /* !JS_THREADSAFE */
-
-#define PCE_LOAD(cache, pce, entry) ((entry) = *(pce))
-#define PCE_STORE(cache, pce, entry) (*(pce) = (entry))
-
-#endif /* !JS_THREADSAFE */
-
-typedef union JSPropertyCacheEntry {
- struct {
- JSObject *object; /* weak link to object */
- JSScopeProperty *property; /* weak link to property */
- } 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;
- JSBool disabled;
-#ifdef JS_PROPERTY_CACHE_METERING
- uint32 fills;
- uint32 recycles;
- uint32 tests;
- uint32 misses;
- uint32 flushes;
-# define PCMETER(x) x
-#else
-# define PCMETER(x) /* nothing */
-#endif
-} JSPropertyCache;
-
-#define PROPERTY_CACHE_FILL(cache, obj, id, sprop) \
- JS_BEGIN_MACRO \
- JSPropertyCache *cache_ = (cache); \
- if (!cache_->disabled) { \
- uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \
- JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \
- JSPropertyCacheEntry entry_; \
- JSScopeProperty *pce_sprop_; \
- PCE_LOAD(cache_, pce_, entry_); \
- pce_sprop_ = PCE_PROPERTY(entry_); \
- PCMETER(if (pce_sprop_ && pce_sprop_ != sprop) \
- cache_->recycles++); \
- PCE_OBJECT(entry_) = obj; \
- PCE_PROPERTY(entry_) = sprop; \
- cache_->empty = JS_FALSE; \
- PCMETER(cache_->fills++); \
- PCE_STORE(cache_, pce_, entry_); \
- } \
- JS_END_MACRO
-
-#define PROPERTY_CACHE_TEST(cache, obj, id, sprop) \
- JS_BEGIN_MACRO \
- uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \
- JSPropertyCache *cache_ = (cache); \
- JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \
- JSPropertyCacheEntry entry_; \
- JSScopeProperty *pce_sprop_; \
- PCE_LOAD(cache_, pce_, entry_); \
- pce_sprop_ = PCE_PROPERTY(entry_); \
- PCMETER(cache_->tests++); \
- if (pce_sprop_ && \
- PCE_OBJECT(entry_) == obj && \
- pce_sprop_->id == id) { \
- sprop = pce_sprop_; \
- } else { \
- PCMETER(cache_->misses++); \
- sprop = NULL; \
- } \
- JS_END_MACRO
-
-extern void
-js_FlushPropertyCache(JSContext *cx);
-
-extern void
-js_DisablePropertyCache(JSContext *cx);
-
-extern void
-js_EnablePropertyCache(JSContext *cx);
-
-extern JS_FRIEND_API(jsval *)
-js_AllocStack(JSContext *cx, uintN nslots, void **markp);
-
-extern JS_FRIEND_API(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);
-
-/*
- * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp
- * is non-null).
- */
-extern JS_FRIEND_API(JSBool)
-js_Invoke(JSContext *cx, uintN argc, uintN flags);
-
-/*
- * Consolidated js_Invoke flags simply rename the low JSFRAME_* flags.
- */
-#define JSINVOKE_CONSTRUCT JSFRAME_CONSTRUCTING
-#define JSINVOKE_INTERNAL JSFRAME_INTERNAL
-#define JSINVOKE_SKIP_CALLER JSFRAME_SKIP_CALLER
-
-/*
- * "Internal" calls may come from C or C++ code using a JSContext on which no
- * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame.
- */
-#define js_InternalCall(cx,obj,fval,argc,argv,rval) \
- js_InternalInvoke(cx, obj, fval, 0, argc, argv, rval)
-
-#define js_InternalConstruct(cx,obj,fval,argc,argv,rval) \
- js_InternalInvoke(cx, obj, fval, JSINVOKE_CONSTRUCT, argc, argv, rval)
-
-extern JSBool
-js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
- uintN argc, jsval *argv, jsval *rval);
-
-extern JSBool
-js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
- JSAccessMode mode, uintN argc, jsval *argv, jsval *rval);
-
-extern JSBool
-js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
- JSStackFrame *down, uintN flags, jsval *result);
-
-extern JSBool
-js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,
- JSBool *foundp);
-
-extern JSBool
-js_Interpret(JSContext *cx, jsval *result);
-
-JS_END_EXTERN_C
-
-#endif /* jsinterp_h___ */
diff --git a/src/extension/script/js/jslibmath.h b/src/extension/script/js/jslibmath.h
deleted file mode 100644
index 7cbcf767a..000000000
--- a/src/extension/script/js/jslibmath.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * IBM Corp.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * By default all math calls go to fdlibm. The defines for each platform
- * remap the math calls to native routines.
- */
-
-#ifndef _LIBMATH_H
-#define _LIBMATH_H
-
-#include <math.h>
-#include "jsconfig.h"
-
-/*
- * Define which platforms on which to use fdlibm. Not used
- * by default since there can be problems with endian-ness and such.
- */
-
-#if defined(_WIN32) && !defined(__MWERKS__)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(SUNOS4)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(IRIX)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(SOLARIS)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(HPUX)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(linux)
-#define JS_USE_FDLIBM_MATH 1
-
-#elif defined(OSF1)
-/* Want to use some fdlibm functions but fdlibm broken on OSF1/alpha. */
-#define JS_USE_FDLIBM_MATH 0
-
-#elif defined(AIX)
-#define JS_USE_FDLIBM_MATH 1
-
-#else
-#define JS_USE_FDLIBM_MATH 0
-#endif
-
-#if !JS_USE_FDLIBM_MATH
-
-/*
- * Use system provided math routines.
- */
-
-#define fd_acos acos
-#define fd_asin asin
-#define fd_atan atan
-#define fd_atan2 atan2
-#define fd_ceil ceil
-#define fd_copysign copysign
-#define fd_cos cos
-#define fd_exp exp
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-#define fd_log log
-#define fd_pow pow
-#define fd_sin sin
-#define fd_sqrt sqrt
-#define fd_tan tan
-
-#else
-
-/*
- * Use math routines in fdlibm.
- */
-
-#undef __P
-#ifdef __STDC__
-#define __P(p) p
-#else
-#define __P(p) ()
-#endif
-
-#if defined _WIN32 || defined SUNOS4
-
-#define fd_acos acos
-#define fd_asin asin
-#define fd_atan atan
-#define fd_cos cos
-#define fd_sin sin
-#define fd_tan tan
-#define fd_exp exp
-#define fd_log log
-#define fd_sqrt sqrt
-#define fd_ceil ceil
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-
-extern double fd_atan2 __P((double, double));
-extern double fd_copysign __P((double, double));
-extern double fd_pow __P((double, double));
-
-#elif defined IRIX
-
-#define fd_acos acos
-#define fd_asin asin
-#define fd_atan atan
-#define fd_exp exp
-#define fd_log log
-#define fd_log10 log10
-#define fd_sqrt sqrt
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-
-extern double fd_cos __P((double));
-extern double fd_sin __P((double));
-extern double fd_tan __P((double));
-extern double fd_atan2 __P((double, double));
-extern double fd_pow __P((double, double));
-extern double fd_ceil __P((double));
-extern double fd_copysign __P((double, double));
-
-#elif defined SOLARIS
-
-#define fd_atan atan
-#define fd_cos cos
-#define fd_sin sin
-#define fd_tan tan
-#define fd_exp exp
-#define fd_sqrt sqrt
-#define fd_ceil ceil
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-
-extern double fd_acos __P((double));
-extern double fd_asin __P((double));
-extern double fd_log __P((double));
-extern double fd_atan2 __P((double, double));
-extern double fd_pow __P((double, double));
-extern double fd_copysign __P((double, double));
-
-#elif defined HPUX
-
-#define fd_cos cos
-#define fd_sin sin
-#define fd_exp exp
-#define fd_sqrt sqrt
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-
-extern double fd_ceil __P((double));
-extern double fd_acos __P((double));
-extern double fd_log __P((double));
-extern double fd_atan2 __P((double, double));
-extern double fd_tan __P((double));
-extern double fd_pow __P((double, double));
-extern double fd_asin __P((double));
-extern double fd_atan __P((double));
-extern double fd_copysign __P((double, double));
-
-#elif defined(linux)
-
-#define fd_atan atan
-#define fd_atan2 atan2
-#define fd_ceil ceil
-#define fd_cos cos
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-#define fd_sin sin
-#define fd_sqrt sqrt
-#define fd_tan tan
-#define fd_copysign copysign
-
-extern double fd_asin __P((double));
-extern double fd_acos __P((double));
-extern double fd_exp __P((double));
-extern double fd_log __P((double));
-extern double fd_pow __P((double, double));
-
-#elif defined(OSF1)
-
-#define fd_acos acos
-#define fd_asin asin
-#define fd_atan atan
-#define fd_copysign copysign
-#define fd_cos cos
-#define fd_exp exp
-#define fd_fabs fabs
-#define fd_fmod fmod
-#define fd_sin sin
-#define fd_sqrt sqrt
-#define fd_tan tan
-
-extern double fd_atan2 __P((double, double));
-extern double fd_ceil __P((double));
-extern double fd_floor __P((double));
-extern double fd_log __P((double));
-extern double fd_pow __P((double, double));
-
-#elif defined(AIX)
-
-#define fd_acos acos
-#define fd_asin asin
-#define fd_atan2 atan2
-#define fd_copysign copysign
-#define fd_cos cos
-#define fd_exp exp
-#define fd_fabs fabs
-#define fd_floor floor
-#define fd_fmod fmod
-#define fd_log log
-#define fd_sin sin
-#define fd_sqrt sqrt
-
-extern double fd_atan __P((double));
-extern double fd_ceil __P((double));
-extern double fd_pow __P((double,double));
-extern double fd_tan __P((double));
-
-#else /* other platform.. generic paranoid slow fdlibm */
-
-extern double fd_acos __P((double));
-extern double fd_asin __P((double));
-extern double fd_atan __P((double));
-extern double fd_cos __P((double));
-extern double fd_sin __P((double));
-extern double fd_tan __P((double));
-
-extern double fd_exp __P((double));
-extern double fd_log __P((double));
-extern double fd_sqrt __P((double));
-
-extern double fd_ceil __P((double));
-extern double fd_fabs __P((double));
-extern double fd_floor __P((double));
-extern double fd_fmod __P((double, double));
-
-extern double fd_atan2 __P((double, double));
-extern double fd_pow __P((double, double));
-extern double fd_copysign __P((double, double));
-
-#endif
-
-#endif /* JS_USE_FDLIBM_MATH */
-
-#endif /* _LIBMATH_H */
-
diff --git a/src/extension/script/js/jslock.c b/src/extension/script/js/jslock.c
deleted file mode 100644
index 9709c8cc0..000000000
--- a/src/extension/script/js/jslock.c
+++ /dev/null
@@ -1,1241 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifdef JS_THREADSAFE
-
-/*
- * JS locking stubs.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include "jspubtd.h"
-#include "prthread.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jstypes.h"
-#include "jsbit.h"
-#include "jscntxt.h"
-#include "jsdtoa.h"
-#include "jsgc.h"
-#include "jslock.h"
-#include "jsscope.h"
-#include "jsstr.h"
-
-#define ReadWord(W) (W)
-
-#ifndef NSPR_LOCK
-
-#include <memory.h>
-
-static PRLock **global_locks;
-static uint32 global_lock_count = 1;
-static uint32 global_locks_log2 = 0;
-static uint32 global_locks_mask = 0;
-
-#define GLOBAL_LOCK_INDEX(id) (((uint32)(id) >> 2) & global_locks_mask)
-
-static void
-js_LockGlobal(void *id)
-{
- uint32 i = GLOBAL_LOCK_INDEX(id);
- PR_Lock(global_locks[i]);
-}
-
-static void
-js_UnlockGlobal(void *id)
-{
- uint32 i = GLOBAL_LOCK_INDEX(id);
- PR_Unlock(global_locks[i]);
-}
-
-/* Exclude Alpha NT. */
-#if defined(_WIN32) && defined(_M_IX86)
-#pragma warning( disable : 4035 )
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
- __asm {
- mov eax, ov
- mov ecx, nv
- mov ebx, w
- lock cmpxchg [ebx], ecx
- sete al
- and eax, 1h
- }
-}
-
-#elif defined(__GNUC__) && defined(__i386__)
-
-/* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
- unsigned int res;
-
- __asm__ __volatile__ (
- "lock\n"
- "cmpxchgl %2, (%1)\n"
- "sete %%al\n"
- "andl $1, %%eax\n"
- : "=a" (res)
- : "r" (w), "r" (nv), "a" (ov)
- : "cc", "memory");
- return (int)res;
-}
-
-#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-#if defined(__GNUC__)
- unsigned int res;
- JS_ASSERT(ov != nv);
- asm volatile ("\
-stbar\n\
-cas [%1],%2,%3\n\
-cmp %2,%3\n\
-be,a 1f\n\
-mov 1,%0\n\
-mov 0,%0\n\
-1:"
- : "=r" (res)
- : "r" (w), "r" (ov), "r" (nv));
- return (int)res;
-#else /* !__GNUC__ */
- extern int compare_and_swap(jsword*, jsword, jsword);
- JS_ASSERT(ov != nv);
- return compare_and_swap(w, ov, nv);
-#endif
-}
-
-#elif defined(AIX)
-
-#include <sys/atomic_op.h>
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
- return !_check_lock((atomic_p)w, ov, nv);
-}
-
-#else
-
-#error "Define NSPR_LOCK if your platform lacks a compare-and-swap instruction."
-
-#endif /* arch-tests */
-
-#endif /* !NSPR_LOCK */
-
-jsword
-js_CurrentThreadId()
-{
- return CurrentThreadId();
-}
-
-void
-js_InitLock(JSThinLock *tl)
-{
-#ifdef NSPR_LOCK
- tl->owner = 0;
- tl->fat = (JSFatLock*)JS_NEW_LOCK();
-#else
- memset(tl, 0, sizeof(JSThinLock));
-#endif
-}
-
-void
-js_FinishLock(JSThinLock *tl)
-{
-#ifdef NSPR_LOCK
- tl->owner = 0xdeadbeef;
- if (tl->fat)
- JS_DESTROY_LOCK(((JSLock*)tl->fat));
-#else
- JS_ASSERT(tl->owner == 0);
- JS_ASSERT(tl->fat == NULL);
-#endif
-}
-
-static void js_Dequeue(JSThinLock *);
-
-#ifdef DEBUG_SCOPE_COUNT
-
-#include <stdio.h>
-#include "jsdhash.h"
-
-static FILE *logfp;
-static JSDHashTable logtbl;
-
-typedef struct logentry {
- JSDHashEntryStub stub;
- char op;
- const char *file;
- int line;
-} logentry;
-
-static void
-logit(JSScope *scope, char op, const char *file, int line)
-{
- logentry *entry;
-
- if (!logfp) {
- logfp = fopen("/tmp/scope.log", "w");
- if (!logfp)
- return;
- setvbuf(logfp, NULL, _IONBF, 0);
- }
- fprintf(logfp, "%p %c %s %d\n", scope, op, file, line);
-
- if (!logtbl.entryStore &&
- !JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL,
- sizeof(logentry), 100)) {
- return;
- }
- entry = (logentry *) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_ADD);
- if (!entry)
- return;
- entry->stub.key = scope;
- entry->op = op;
- entry->file = file;
- entry->line = line;
-}
-
-void
-js_unlog_scope(JSScope *scope)
-{
- if (!logtbl.entryStore)
- return;
- (void) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_REMOVE);
-}
-
-# define LOGIT(scope,op) logit(scope, op, __FILE__, __LINE__)
-
-#else
-
-# define LOGIT(scope,op) /* nothing */
-
-#endif /* DEBUG_SCOPE_COUNT */
-
-/*
- * Return true if scope's ownercx, or the ownercx of a single-threaded scope
- * for which ownercx is waiting to become multi-threaded and shared, is cx.
- * That condition implies deadlock in ClaimScope if cx's thread were to wait
- * to share scope.
- *
- * (i) rt->gcLock held
- */
-static JSBool
-WillDeadlock(JSScope *scope, JSContext *cx)
-{
- JSContext *ownercx;
-
- do {
- ownercx = scope->ownercx;
- if (ownercx == cx) {
- JS_RUNTIME_METER(cx->runtime, deadlocksAvoided);
- return JS_TRUE;
- }
- } while (ownercx && (scope = ownercx->scopeToShare) != NULL);
- return JS_FALSE;
-}
-
-/*
- * Make scope multi-threaded, i.e. share its ownership among contexts in rt
- * using a "thin" or (if necessary due to contention) "fat" lock. Called only
- * from ClaimScope, immediately below, when we detect deadlock were we to wait
- * for scope's lock, because its ownercx is waiting on a scope owned by the
- * calling cx.
- *
- * (i) rt->gcLock held
- */
-static void
-ShareScope(JSRuntime *rt, JSScope *scope)
-{
- JSScope **todop;
-
- if (scope->u.link) {
- for (todop = &rt->scopeSharingTodo; *todop != scope;
- todop = &(*todop)->u.link) {
- JS_ASSERT(*todop != NO_SCOPE_SHARING_TODO);
- }
- *todop = scope->u.link;
- scope->u.link = NULL; /* null u.link for sanity ASAP */
- JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone);
- }
- js_InitLock(&scope->lock);
- if (scope == rt->setSlotScope) {
- /*
- * Nesting locks on another thread that's using scope->ownercx: give
- * the held lock a reentrancy count of 1 and set its lock.owner field
- * directly (no compare-and-swap needed while scope->ownercx is still
- * non-null). See below in ClaimScope, before the ShareScope call,
- * for more on why this is necessary.
- *
- * If NSPR_LOCK is defined, we cannot deadlock holding rt->gcLock and
- * acquiring scope->lock.fat here, against another thread holding that
- * fat lock and trying to grab rt->gcLock. This is because no other
- * thread can attempt to acquire scope->lock.fat until scope->ownercx
- * is null *and* our thread has released rt->gcLock, which interlocks
- * scope->ownercx's transition to null against tests of that member
- * in ClaimScope.
- */
- scope->lock.owner = scope->ownercx->thread;
-#ifdef NSPR_LOCK
- JS_ACQUIRE_LOCK((JSLock*)scope->lock.fat);
-#endif
- scope->u.count = 1;
- } else {
- scope->u.count = 0;
- }
- js_FinishSharingScope(rt, scope);
-}
-
-/*
- * js_FinishSharingScope is the tail part of ShareScope, split out to become a
- * subroutine of JS_EndRequest too. The bulk of the work here involves making
- * mutable strings in the scope's object's slots be immutable. We have to do
- * this because such strings will soon be available to multiple threads, so
- * their buffers can't be realloc'd any longer in js_ConcatStrings, and their
- * members can't be modified by js_ConcatStrings, js_MinimizeDependentStrings,
- * or js_UndependString.
- *
- * The last bit of work done by js_FinishSharingScope nulls scope->ownercx and
- * updates rt->sharedScopes.
- */
-#define MAKE_STRING_IMMUTABLE(rt, v, vp) \
- JS_BEGIN_MACRO \
- JSString *str_ = JSVAL_TO_STRING(v); \
- uint8 *flagp_ = js_GetGCThingFlags(str_); \
- if (*flagp_ & GCF_MUTABLE) { \
- if (JSSTRING_IS_DEPENDENT(str_) && \
- !js_UndependString(NULL, str_)) { \
- JS_RUNTIME_METER(rt, badUndependStrings); \
- *vp = JSVAL_VOID; \
- } else { \
- *flagp_ &= ~GCF_MUTABLE; \
- } \
- } \
- JS_END_MACRO
-
-void
-js_FinishSharingScope(JSRuntime *rt, JSScope *scope)
-{
- JSObject *obj;
- uint32 nslots;
- jsval v, *vp, *end;
-
- obj = scope->object;
- nslots = JS_MIN(obj->map->freeslot, obj->map->nslots);
- for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
- v = *vp;
- if (JSVAL_IS_STRING(v))
- MAKE_STRING_IMMUTABLE(rt, v, vp);
- }
-
- scope->ownercx = NULL; /* NB: set last, after lock init */
- JS_RUNTIME_METER(rt, sharedScopes);
-}
-
-/*
- * Given a scope with apparently non-null ownercx different from cx, try to
- * set ownercx to cx, claiming exclusive (single-threaded) ownership of scope.
- * If we claim ownership, return true. Otherwise, we wait for ownercx to be
- * set to null (indicating that scope is multi-threaded); or if waiting would
- * deadlock, we set ownercx to null ourselves via ShareScope. In any case,
- * once ownercx is null we return false.
- */
-static JSBool
-ClaimScope(JSScope *scope, JSContext *cx)
-{
- JSRuntime *rt;
- JSContext *ownercx;
- jsrefcount saveDepth;
- PRStatus stat;
-
- rt = cx->runtime;
- JS_RUNTIME_METER(rt, claimAttempts);
- JS_LOCK_GC(rt);
-
- /* Reload in case ownercx went away while we blocked on the lock. */
- while ((ownercx = scope->ownercx) != NULL) {
- /*
- * Avoid selflock if ownercx is dead, or is not running a request, or
- * has the same thread as cx. Set scope->ownercx to cx so that the
- * matching JS_UNLOCK_SCOPE or JS_UNLOCK_OBJ macro call will take the
- * fast path around the corresponding js_UnlockScope or js_UnlockObj
- * function call.
- *
- * If scope->u.link is non-null, scope has already been inserted on
- * the rt->scopeSharingTodo list, because another thread's context
- * already wanted to lock scope while ownercx was running a request.
- * We can't claim any scope whose u.link is non-null at this point,
- * even if ownercx->requestDepth is 0 (see below where we suspend our
- * request before waiting on rt->scopeSharingDone).
- */
- if (!scope->u.link &&
- (!js_ValidContextPointer(rt, ownercx) ||
- !ownercx->requestDepth ||
- ownercx->thread == cx->thread)) {
- JS_ASSERT(scope->u.count == 0);
- scope->ownercx = cx;
- JS_UNLOCK_GC(rt);
- JS_RUNTIME_METER(rt, claimedScopes);
- return JS_TRUE;
- }
-
- /*
- * Avoid deadlock if scope's owner context is waiting on a scope that
- * we own, by revoking scope's ownership. This approach to deadlock
- * avoidance works because the engine never nests scope locks, except
- * for the notable case of js_SetProtoOrParent (see jsobj.c).
- *
- * If cx could hold locks on ownercx->scopeToShare, or if ownercx
- * could hold locks on scope, we would need to keep reentrancy counts
- * for all such "flyweight" (ownercx != NULL) locks, so that control
- * would unwind properly once these locks became "thin" or "fat".
- * Apart from the js_SetProtoOrParent exception, the engine promotes
- * a scope from exclusive to shared access only when locking, never
- * when holding or unlocking.
- *
- * If ownercx's thread is calling js_SetProtoOrParent, trying to lock
- * the inner scope (the scope of the object being set as the prototype
- * of the outer object), ShareScope will find the outer object's scope
- * at rt->setSlotScope. If it's the same as scope, we give it a lock
- * held by ownercx's thread with reentrancy count of 1, then we return
- * here and break. After that we unwind to js_[GS]etSlotThreadSafe or
- * js_LockScope (our caller), where we wait on the newly-fattened lock
- * until ownercx's thread unwinds from js_SetProtoOrParent.
- *
- * Avoid deadlock before any of this scope/context cycle detection if
- * cx is on the active GC's thread, because in that case, no requests
- * will run until the GC completes. Any scope wanted by the GC (from
- * a finalizer) that can't be claimed must be slated for sharing.
- */
- if (rt->gcThread == cx->thread ||
- (ownercx->scopeToShare &&
- WillDeadlock(ownercx->scopeToShare, cx))) {
- ShareScope(rt, scope);
- break;
- }
-
- /*
- * Thanks to the non-zero NO_SCOPE_SHARING_TODO link terminator, we
- * can decide whether scope is on rt->scopeSharingTodo with a single
- * non-null test, and avoid double-insertion bugs.
- */
- if (!scope->u.link) {
- scope->u.link = rt->scopeSharingTodo;
- rt->scopeSharingTodo = scope;
- js_HoldObjectMap(cx, &scope->map);
- }
-
- /*
- * Inline JS_SuspendRequest before we wait on rt->scopeSharingDone,
- * saving and clearing cx->requestDepth so we don't deadlock if the
- * GC needs to run on ownercx.
- *
- * Unlike JS_SuspendRequest and JS_EndRequest, we must take care not
- * to decrement rt->requestCount if cx is active on the GC's thread,
- * because the GC has already reduced rt->requestCount to exclude all
- * such such contexts.
- */
- saveDepth = cx->requestDepth;
- if (saveDepth) {
- cx->requestDepth = 0;
- if (rt->gcThread != cx->thread) {
- JS_ASSERT(rt->requestCount > 0);
- rt->requestCount--;
- if (rt->requestCount == 0)
- JS_NOTIFY_REQUEST_DONE(rt);
- }
- }
-
- /*
- * We know that some other thread's context owns scope, which is now
- * linked onto rt->scopeSharingTodo, awaiting the end of that other
- * thread's request. So it is safe to wait on rt->scopeSharingDone.
- */
- cx->scopeToShare = scope;
- stat = PR_WaitCondVar(rt->scopeSharingDone, PR_INTERVAL_NO_TIMEOUT);
- JS_ASSERT(stat != PR_FAILURE);
-
- /*
- * Inline JS_ResumeRequest after waiting on rt->scopeSharingDone,
- * restoring cx->requestDepth. Same note as above for the inlined,
- * specialized JS_SuspendRequest code: beware rt->gcThread.
- */
- if (saveDepth) {
- if (rt->gcThread != cx->thread) {
- while (rt->gcLevel > 0)
- JS_AWAIT_GC_DONE(rt);
- rt->requestCount++;
- }
- cx->requestDepth = saveDepth;
- }
-
- /*
- * Don't clear cx->scopeToShare until after we're through waiting on
- * all condition variables protected by rt->gcLock -- that includes
- * rt->scopeSharingDone *and* rt->gcDone (hidden in JS_AWAIT_GC_DONE,
- * in the inlined JS_ResumeRequest code immediately above).
- *
- * Otherwise, the GC could easily deadlock with another thread that
- * owns a scope wanted by a finalizer. By keeping cx->scopeToShare
- * set till here, we ensure that such deadlocks are detected, which
- * results in the finalized object's scope being shared (it must, of
- * course, have other, live objects sharing it).
- */
- cx->scopeToShare = NULL;
- }
-
- JS_UNLOCK_GC(rt);
- return JS_FALSE;
-}
-
-/* Exported to js.c, which calls it via OBJ_GET_* and JSVAL_IS_* macros. */
-JS_FRIEND_API(jsval)
-js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
-{
- jsval v;
- JSScope *scope;
-#ifndef NSPR_LOCK
- JSThinLock *tl;
- jsword me;
-#endif
-
- /*
- * We handle non-native objects via JSObjectOps.getRequiredSlot, treating
- * all slots starting from 0 as required slots. A property definition or
- * some prior arrangement must have allocated slot.
- *
- * Note once again (see jspubtd.h, before JSGetRequiredSlotOp's typedef)
- * the crucial distinction between a |required slot number| that's passed
- * to the get/setRequiredSlot JSObjectOps, and a |reserved slot index|
- * passed to the JS_Get/SetReservedSlot APIs.
- */
- if (!OBJ_IS_NATIVE(obj))
- return OBJ_GET_REQUIRED_SLOT(cx, obj, slot);
-
- /*
- * Native object locking is inlined here to optimize the single-threaded
- * and contention-free multi-threaded cases.
- */
- scope = OBJ_SCOPE(obj);
- JS_ASSERT(scope->ownercx != cx);
- JS_ASSERT(obj->slots && slot < obj->map->freeslot);
-
- /*
- * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h).
- * Also avoid locking an object owning a sealed scope. If neither of those
- * special cases applies, try to claim scope's flyweight lock from whatever
- * context may have had it in an earlier request.
- */
- if (CX_THREAD_IS_RUNNING_GC(cx) ||
- (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
- (scope->ownercx && ClaimScope(scope, cx))) {
- return obj->slots[slot];
- }
-
-#ifndef NSPR_LOCK
- tl = &scope->lock;
- me = cx->thread;
- JS_ASSERT(me == CurrentThreadId());
- if (js_CompareAndSwap(&tl->owner, 0, me)) {
- /*
- * Got the lock with one compare-and-swap. Even so, someone else may
- * have mutated obj so it now has its own scope and lock, which would
- * require either a restart from the top of this routine, or a thin
- * lock release followed by fat lock acquisition.
- */
- if (scope == OBJ_SCOPE(obj)) {
- v = obj->slots[slot];
- if (!js_CompareAndSwap(&tl->owner, me, 0)) {
- /* Assert that scope locks never revert to flyweight. */
- JS_ASSERT(scope->ownercx != cx);
- LOGIT(scope, '1');
- scope->u.count = 1;
- js_UnlockObj(cx, obj);
- }
- return v;
- }
- if (!js_CompareAndSwap(&tl->owner, me, 0))
- js_Dequeue(tl);
- }
- else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
- return obj->slots[slot];
- }
-#endif
-
- js_LockObj(cx, obj);
- v = obj->slots[slot];
-
- /*
- * Test whether cx took ownership of obj's scope during js_LockObj.
- *
- * This does not mean that a given scope reverted to flyweight from "thin"
- * or "fat" -- it does mean that obj's map pointer changed due to another
- * thread setting a property, requiring obj to cease sharing a prototype
- * object's scope (whose lock was not flyweight, else we wouldn't be here
- * in the first place!).
- */
- scope = OBJ_SCOPE(obj);
- if (scope->ownercx != cx)
- js_UnlockScope(cx, scope);
- return v;
-}
-
-void
-js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
-{
- JSScope *scope;
-#ifndef NSPR_LOCK
- JSThinLock *tl;
- jsword me;
-#endif
-
- /* Any string stored in a thread-safe object must be immutable. */
- if (JSVAL_IS_STRING(v))
- MAKE_STRING_IMMUTABLE(cx->runtime, v, &v);
-
- /*
- * We handle non-native objects via JSObjectOps.setRequiredSlot, as above
- * for the Get case.
- */
- if (!OBJ_IS_NATIVE(obj)) {
- OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
- return;
- }
-
- /*
- * Native object locking is inlined here to optimize the single-threaded
- * and contention-free multi-threaded cases.
- */
- scope = OBJ_SCOPE(obj);
- JS_ASSERT(scope->ownercx != cx);
- JS_ASSERT(obj->slots && slot < obj->map->freeslot);
-
- /*
- * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h).
- * Also avoid locking an object owning a sealed scope. If neither of those
- * special cases applies, try to claim scope's flyweight lock from whatever
- * context may have had it in an earlier request.
- */
- if (CX_THREAD_IS_RUNNING_GC(cx) ||
- (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
- (scope->ownercx && ClaimScope(scope, cx))) {
- obj->slots[slot] = v;
- return;
- }
-
-#ifndef NSPR_LOCK
- tl = &scope->lock;
- me = cx->thread;
- JS_ASSERT(me == CurrentThreadId());
- if (js_CompareAndSwap(&tl->owner, 0, me)) {
- if (scope == OBJ_SCOPE(obj)) {
- obj->slots[slot] = v;
- if (!js_CompareAndSwap(&tl->owner, me, 0)) {
- /* Assert that scope locks never revert to flyweight. */
- JS_ASSERT(scope->ownercx != cx);
- LOGIT(scope, '1');
- scope->u.count = 1;
- js_UnlockObj(cx, obj);
- }
- return;
- }
- if (!js_CompareAndSwap(&tl->owner, me, 0))
- js_Dequeue(tl);
- }
- else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
- obj->slots[slot] = v;
- return;
- }
-#endif
-
- js_LockObj(cx, obj);
- obj->slots[slot] = v;
-
- /*
- * Same drill as above, in js_GetSlotThreadSafe. Note that we cannot
- * assume obj has its own mutable scope (where scope->object == obj) yet,
- * because OBJ_SET_SLOT is called for the "universal", common slots such
- * as JSSLOT_PROTO and JSSLOT_PARENT, without a prior js_GetMutableScope.
- * See also the JSPROP_SHARED attribute and its usage.
- */
- scope = OBJ_SCOPE(obj);
- if (scope->ownercx != cx)
- js_UnlockScope(cx, scope);
-}
-
-#ifndef NSPR_LOCK
-
-static JSFatLock *
-NewFatlock()
-{
- JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */
- if (!fl) return NULL;
- fl->susp = 0;
- fl->next = NULL;
- fl->prevp = NULL;
- fl->slock = PR_NewLock();
- fl->svar = PR_NewCondVar(fl->slock);
- return fl;
-}
-
-static void
-DestroyFatlock(JSFatLock *fl)
-{
- PR_DestroyLock(fl->slock);
- PR_DestroyCondVar(fl->svar);
- free(fl);
-}
-
-static JSFatLock *
-ListOfFatlocks(int listc)
-{
- JSFatLock *m;
- JSFatLock *m0;
- int i;
-
- JS_ASSERT(listc>0);
- m0 = m = NewFatlock();
- for (i=1; i<listc; i++) {
- m->next = NewFatlock();
- m = m->next;
- }
- return m0;
-}
-
-static void
-DeleteListOfFatlocks(JSFatLock *m)
-{
- JSFatLock *m0;
- for (; m; m=m0) {
- m0 = m->next;
- DestroyFatlock(m);
- }
-}
-
-static JSFatLockTable *fl_list_table = NULL;
-static uint32 fl_list_table_len = 0;
-static uint32 fl_list_chunk_len = 0;
-
-static JSFatLock *
-GetFatlock(void *id)
-{
- JSFatLock *m;
-
- uint32 i = GLOBAL_LOCK_INDEX(id);
- if (fl_list_table[i].free == NULL) {
-#ifdef DEBUG
- if (fl_list_table[i].taken)
- printf("Ran out of fat locks!\n");
-#endif
- fl_list_table[i].free = ListOfFatlocks(fl_list_chunk_len);
- }
- m = fl_list_table[i].free;
- fl_list_table[i].free = m->next;
- m->susp = 0;
- m->next = fl_list_table[i].taken;
- m->prevp = &fl_list_table[i].taken;
- if (fl_list_table[i].taken)
- fl_list_table[i].taken->prevp = &m->next;
- fl_list_table[i].taken = m;
- return m;
-}
-
-static void
-PutFatlock(JSFatLock *m, void *id)
-{
- uint32 i;
- if (m == NULL)
- return;
-
- /* Unlink m from fl_list_table[i].taken. */
- *m->prevp = m->next;
- if (m->next)
- m->next->prevp = m->prevp;
-
- /* Insert m in fl_list_table[i].free. */
- i = GLOBAL_LOCK_INDEX(id);
- m->next = fl_list_table[i].free;
- fl_list_table[i].free = m;
-}
-
-#endif /* !NSPR_LOCK */
-
-JSBool
-js_SetupLocks(int listc, int globc)
-{
-#ifndef NSPR_LOCK
- uint32 i;
-
- if (global_locks)
- return JS_TRUE;
-#ifdef DEBUG
- if (listc > 10000 || listc < 0) /* listc == fat lock list chunk length */
- printf("Bad number %d in js_SetupLocks()!\n", listc);
- if (globc > 100 || globc < 0) /* globc == number of global locks */
- printf("Bad number %d in js_SetupLocks()!\n", listc);
-#endif
- global_locks_log2 = JS_CeilingLog2(globc);
- global_locks_mask = JS_BITMASK(global_locks_log2);
- global_lock_count = JS_BIT(global_locks_log2);
- global_locks = (PRLock **) malloc(global_lock_count * sizeof(PRLock*));
- if (!global_locks)
- return JS_FALSE;
- for (i = 0; i < global_lock_count; i++) {
- global_locks[i] = PR_NewLock();
- if (!global_locks[i]) {
- global_lock_count = i;
- js_CleanupLocks();
- return JS_FALSE;
- }
- }
- fl_list_table = (JSFatLockTable *) malloc(i * sizeof(JSFatLockTable));
- if (!fl_list_table) {
- js_CleanupLocks();
- return JS_FALSE;
- }
- fl_list_table_len = global_lock_count;
- for (i = 0; i < global_lock_count; i++)
- fl_list_table[i].free = fl_list_table[i].taken = NULL;
- fl_list_chunk_len = listc;
-#endif /* !NSPR_LOCK */
- return JS_TRUE;
-}
-
-void
-js_CleanupLocks()
-{
-#ifndef NSPR_LOCK
- uint32 i;
-
- if (global_locks) {
- for (i = 0; i < global_lock_count; i++)
- PR_DestroyLock(global_locks[i]);
- free(global_locks);
- global_locks = NULL;
- global_lock_count = 1;
- global_locks_log2 = 0;
- global_locks_mask = 0;
- }
- if (fl_list_table) {
- for (i = 0; i < fl_list_table_len; i++) {
- DeleteListOfFatlocks(fl_list_table[i].free);
- fl_list_table[i].free = NULL;
- DeleteListOfFatlocks(fl_list_table[i].taken);
- fl_list_table[i].taken = NULL;
- }
- free(fl_list_table);
- fl_list_table = NULL;
- fl_list_table_len = 0;
- }
-#endif /* !NSPR_LOCK */
-}
-
-void
-js_InitContextForLocking(JSContext *cx)
-{
- cx->thread = CurrentThreadId();
- JS_ASSERT(Thin_GetWait(cx->thread) == 0);
-}
-
-#ifndef NSPR_LOCK
-
-/*
- * Fast locking and unlocking is implemented by delaying the allocation of a
- * system lock (fat lock) until contention. As long as a locking thread A
- * runs uncontended, the lock is represented solely by storing A's identity in
- * the object being locked.
- *
- * If another thread B tries to lock the object currently locked by A, B is
- * enqueued into a fat lock structure (which might have to be allocated and
- * pointed to by the object), and suspended using NSPR conditional variables
- * (wait). A wait bit (Bacon bit) is set in the lock word of the object,
- * signalling to A that when releasing the lock, B must be dequeued and
- * notified.
- *
- * The basic operation of the locking primitives (js_Lock, js_Unlock,
- * js_Enqueue, and js_Dequeue) is compare-and-swap. Hence, when locking into
- * the word pointed at by p, compare-and-swap(p, 0, A) success implies that p
- * is unlocked. Similarly, when unlocking p, if compare-and-swap(p, A, 0)
- * succeeds this implies that p is uncontended (no one is waiting because the
- * wait bit is not set).
- *
- * When dequeueing, the lock is released, and one of the threads suspended on
- * the lock is notified. If other threads still are waiting, the wait bit is
- * kept (in js_Enqueue), and if not, the fat lock is deallocated.
- *
- * The functions js_Enqueue, js_Dequeue, js_SuspendThread, and js_ResumeThread
- * are serialized using a global lock. For scalability, a hashtable of global
- * locks is used, which is indexed modulo the thin lock pointer.
- */
-
-/*
- * Invariants:
- * (i) global lock is held
- * (ii) fl->susp >= 0
- */
-static int
-js_SuspendThread(JSThinLock *tl)
-{
- JSFatLock *fl;
- PRStatus stat;
-
- if (tl->fat == NULL)
- fl = tl->fat = GetFatlock(tl);
- else
- fl = tl->fat;
- JS_ASSERT(fl->susp >= 0);
- fl->susp++;
- PR_Lock(fl->slock);
- js_UnlockGlobal(tl);
- stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT);
- JS_ASSERT(stat != PR_FAILURE);
- PR_Unlock(fl->slock);
- js_LockGlobal(tl);
- fl->susp--;
- if (fl->susp == 0) {
- PutFatlock(fl, tl);
- tl->fat = NULL;
- }
- return tl->fat == NULL;
-}
-
-/*
- * (i) global lock is held
- * (ii) fl->susp > 0
- */
-static void
-js_ResumeThread(JSThinLock *tl)
-{
- JSFatLock *fl = tl->fat;
- PRStatus stat;
-
- JS_ASSERT(fl != NULL);
- JS_ASSERT(fl->susp > 0);
- PR_Lock(fl->slock);
- js_UnlockGlobal(tl);
- stat = PR_NotifyCondVar(fl->svar);
- JS_ASSERT(stat != PR_FAILURE);
- PR_Unlock(fl->slock);
-}
-
-static void
-js_Enqueue(JSThinLock *tl, jsword me)
-{
- jsword o, n;
-
- js_LockGlobal(tl);
- for (;;) {
- o = ReadWord(tl->owner);
- n = Thin_SetWait(o);
- if (o != 0 && js_CompareAndSwap(&tl->owner, o, n)) {
- if (js_SuspendThread(tl))
- me = Thin_RemoveWait(me);
- else
- me = Thin_SetWait(me);
- }
- else if (js_CompareAndSwap(&tl->owner, 0, me)) {
- js_UnlockGlobal(tl);
- return;
- }
- }
-}
-
-static void
-js_Dequeue(JSThinLock *tl)
-{
- jsword o;
-
- js_LockGlobal(tl);
- o = ReadWord(tl->owner);
- JS_ASSERT(Thin_GetWait(o) != 0);
- JS_ASSERT(tl->fat != NULL);
- if (!js_CompareAndSwap(&tl->owner, o, 0)) /* release it */
- JS_ASSERT(0);
- js_ResumeThread(tl);
-}
-
-JS_INLINE void
-js_Lock(JSThinLock *tl, jsword me)
-{
- JS_ASSERT(me == CurrentThreadId());
- if (js_CompareAndSwap(&tl->owner, 0, me))
- return;
- if (Thin_RemoveWait(ReadWord(tl->owner)) != me)
- js_Enqueue(tl, me);
-#ifdef DEBUG
- else
- JS_ASSERT(0);
-#endif
-}
-
-JS_INLINE void
-js_Unlock(JSThinLock *tl, jsword me)
-{
- JS_ASSERT(me == CurrentThreadId());
- if (js_CompareAndSwap(&tl->owner, me, 0))
- return;
- if (Thin_RemoveWait(ReadWord(tl->owner)) == me)
- js_Dequeue(tl);
-#ifdef DEBUG
- else
- JS_ASSERT(0);
-#endif
-}
-
-#endif /* !NSPR_LOCK */
-
-void
-js_LockRuntime(JSRuntime *rt)
-{
- PR_Lock(rt->rtLock);
-#ifdef DEBUG
- rt->rtLockOwner = CurrentThreadId();
-#endif
-}
-
-void
-js_UnlockRuntime(JSRuntime *rt)
-{
-#ifdef DEBUG
- rt->rtLockOwner = 0;
-#endif
- PR_Unlock(rt->rtLock);
-}
-
-void
-js_LockScope(JSContext *cx, JSScope *scope)
-{
- jsword me = cx->thread;
-
- JS_ASSERT(me == CurrentThreadId());
- JS_ASSERT(scope->ownercx != cx);
- if (CX_THREAD_IS_RUNNING_GC(cx))
- return;
- if (scope->ownercx && ClaimScope(scope, cx))
- return;
-
- if (Thin_RemoveWait(ReadWord(scope->lock.owner)) == me) {
- JS_ASSERT(scope->u.count > 0);
- LOGIT(scope, '+');
- scope->u.count++;
- } else {
- JSThinLock *tl = &scope->lock;
- JS_LOCK0(tl, me);
- JS_ASSERT(scope->u.count == 0);
- LOGIT(scope, '1');
- scope->u.count = 1;
- }
-}
-
-void
-js_UnlockScope(JSContext *cx, JSScope *scope)
-{
- jsword me = cx->thread;
-
- /* We hope compilers use me instead of reloading cx->thread in the macro. */
- if (CX_THREAD_IS_RUNNING_GC(cx))
- return;
- if (cx->lockedSealedScope == scope) {
- cx->lockedSealedScope = NULL;
- return;
- }
-
- JS_ASSERT(scope->ownercx == NULL);
- JS_ASSERT(scope->u.count > 0);
- if (Thin_RemoveWait(ReadWord(scope->lock.owner)) != me) {
- JS_ASSERT(0); /* unbalanced unlock */
- return;
- }
- LOGIT(scope, '-');
- if (--scope->u.count == 0) {
- JSThinLock *tl = &scope->lock;
- JS_UNLOCK0(tl, me);
- }
-}
-
-/*
- * NB: oldscope may be null if our caller is js_GetMutableScope and it just
- * dropped the last reference to oldscope.
- */
-void
-js_TransferScopeLock(JSContext *cx, JSScope *oldscope, JSScope *newscope)
-{
- jsword me;
- JSThinLock *tl;
-
- JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, newscope));
-
- /*
- * If the last reference to oldscope went away, newscope needs no lock
- * state update.
- */
- if (!oldscope)
- return;
- JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, oldscope));
-
- /*
- * Special case in js_LockScope and js_UnlockScope for the GC calling
- * code that locks, unlocks, or mutates. Nothing to do in these cases,
- * because scope and newscope were "locked" by the GC thread, so neither
- * was actually locked.
- */
- if (CX_THREAD_IS_RUNNING_GC(cx))
- return;
-
- /*
- * Special case in js_LockObj and js_UnlockScope for locking the sealed
- * scope of an object that owns that scope (the prototype or mutated obj
- * for which OBJ_SCOPE(obj)->object == obj), and unlocking it.
- */
- JS_ASSERT(cx->lockedSealedScope != newscope);
- if (cx->lockedSealedScope == oldscope) {
- JS_ASSERT(newscope->ownercx == cx ||
- (!newscope->ownercx && newscope->u.count == 1));
- cx->lockedSealedScope = NULL;
- return;
- }
-
- /*
- * If oldscope is single-threaded, there's nothing to do.
- */
- if (oldscope->ownercx) {
- JS_ASSERT(oldscope->ownercx == cx);
- JS_ASSERT(newscope->ownercx == cx ||
- (!newscope->ownercx && newscope->u.count == 1));
- return;
- }
-
- /*
- * We transfer oldscope->u.count only if newscope is not single-threaded.
- * Flow unwinds from here through some number of JS_UNLOCK_SCOPE and/or
- * JS_UNLOCK_OBJ macro calls, which will decrement newscope->u.count only
- * if they find newscope->ownercx != cx.
- */
- if (newscope->ownercx != cx) {
- JS_ASSERT(!newscope->ownercx);
- newscope->u.count = oldscope->u.count;
- }
-
- /*
- * Reset oldscope's lock state so that it is completely unlocked.
- */
- LOGIT(oldscope, '0');
- oldscope->u.count = 0;
- tl = &oldscope->lock;
- me = cx->thread;
- JS_UNLOCK0(tl, me);
-}
-
-void
-js_LockObj(JSContext *cx, JSObject *obj)
-{
- JSScope *scope;
-
- JS_ASSERT(OBJ_IS_NATIVE(obj));
- for (;;) {
- scope = OBJ_SCOPE(obj);
- if (SCOPE_IS_SEALED(scope) && scope->object == obj &&
- !cx->lockedSealedScope) {
- cx->lockedSealedScope = scope;
- return;
- }
-
- js_LockScope(cx, scope);
-
- /* If obj still has this scope, we're done. */
- if (scope == OBJ_SCOPE(obj))
- return;
-
- /* Lost a race with a mutator; retry with obj's new scope. */
- js_UnlockScope(cx, scope);
- }
-}
-
-void
-js_UnlockObj(JSContext *cx, JSObject *obj)
-{
- JS_ASSERT(OBJ_IS_NATIVE(obj));
- js_UnlockScope(cx, OBJ_SCOPE(obj));
-}
-
-#ifdef DEBUG
-
-JSBool
-js_IsRuntimeLocked(JSRuntime *rt)
-{
- return CurrentThreadId() == rt->rtLockOwner;
-}
-
-JSBool
-js_IsObjLocked(JSContext *cx, JSObject *obj)
-{
- JSScope *scope = OBJ_SCOPE(obj);
-
- return MAP_IS_NATIVE(&scope->map) && js_IsScopeLocked(cx, scope);
-}
-
-JSBool
-js_IsScopeLocked(JSContext *cx, JSScope *scope)
-{
- /* Special case: the GC locking any object's scope, see js_LockScope. */
- if (CX_THREAD_IS_RUNNING_GC(cx))
- return JS_TRUE;
-
- /* Special case: locked object owning a sealed scope, see js_LockObj. */
- if (cx->lockedSealedScope == scope)
- return JS_TRUE;
-
- /*
- * General case: the scope is either exclusively owned (by cx), or it has
- * a thin or fat lock to cope with shared (concurrent) ownership.
- */
- if (scope->ownercx) {
- JS_ASSERT(scope->ownercx == cx);
- return JS_TRUE;
- }
- return CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner));
-}
-
-#endif /* DEBUG */
-#endif /* JS_THREADSAFE */
diff --git a/src/extension/script/js/jslock.h b/src/extension/script/js/jslock.h
deleted file mode 100644
index 9ece59c9b..000000000
--- a/src/extension/script/js/jslock.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#ifndef jslock_h__
-#define jslock_h__
-
-#ifdef JS_THREADSAFE
-
-#include "jstypes.h"
-#include "pratom.h"
-#include "prlock.h"
-#include "prcvar.h"
-
-#include "jsprvtd.h" /* for JSScope, etc. */
-#include "jspubtd.h" /* for JSRuntime, etc. */
-
-#define Thin_GetWait(W) ((jsword)(W) & 0x1)
-#define Thin_SetWait(W) ((jsword)(W) | 0x1)
-#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1)
-
-typedef struct JSFatLock JSFatLock;
-
-struct JSFatLock {
- int susp;
- PRLock *slock;
- PRCondVar *svar;
- JSFatLock *next;
- JSFatLock **prevp;
-};
-
-typedef struct JSThinLock {
- jsword owner;
- JSFatLock *fat;
-} JSThinLock;
-
-typedef PRLock JSLock;
-
-typedef struct JSFatLockTable {
- JSFatLock *free;
- JSFatLock *taken;
-} JSFatLockTable;
-
-/*
- * Atomic increment and decrement for a reference counter, given jsrefcount *p.
- * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work.
- */
-#define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p))
-#define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p))
-#define JS_ATOMIC_ADD(p,v) PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v))
-
-#define CurrentThreadId() (jsword)PR_GetCurrentThread()
-#define JS_CurrentThreadId() js_CurrentThreadId()
-#define JS_NEW_LOCK() PR_NewLock()
-#define JS_DESTROY_LOCK(l) PR_DestroyLock(l)
-#define JS_ACQUIRE_LOCK(l) PR_Lock(l)
-#define JS_RELEASE_LOCK(l) PR_Unlock(l)
-#define JS_LOCK0(P,M) js_Lock(P,M)
-#define JS_UNLOCK0(P,M) js_Unlock(P,M)
-
-#define JS_NEW_CONDVAR(l) PR_NewCondVar(l)
-#define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv)
-#define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to)
-#define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT
-#define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv)
-#define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv)
-
-/*
- * Include jsscope.h so JS_LOCK_OBJ macro callers don't have to include it.
- * Since there is a JSThinLock member in JSScope, we can't nest this include
- * much earlier (see JSThinLock's typedef, above). Yes, that means there is
- * an #include cycle between jslock.h and jsscope.h: moderate-sized XXX here,
- * to be fixed by moving JS_LOCK_SCOPE to jsscope.h, JS_LOCK_OBJ to jsobj.h,
- * and so on.
- *
- * We also need jsscope.h #ifdef DEBUG for SET_OBJ_INFO and SET_SCOPE_INFO,
- * but we do not want any nested includes that depend on DEBUG. Those lead
- * to build bustage when someone makes a change that depends in a subtle way
- * on jsscope.h being included directly or indirectly, but does not test by
- * building optimized as well as DEBUG.
- */
-#include "jsscope.h"
-
-#ifdef DEBUG
-
-#define SET_OBJ_INFO(obj_,file_,line_) \
- SET_SCOPE_INFO(OBJ_SCOPE(obj_),file_,line_)
-
-#define SET_SCOPE_INFO(scope_,file_,line_) \
- ((scope_)->ownercx ? (void)0 : \
- (JS_ASSERT((0 < (scope_)->u.count && (scope_)->u.count <= 4) || \
- SCOPE_IS_SEALED(scope_)), \
- (void)((scope_)->file[(scope_)->u.count-1] = (file_), \
- (scope_)->line[(scope_)->u.count-1] = (line_))))
-#endif /* DEBUG */
-
-#define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt)
-#define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt)
-
-/*
- * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects
- * (objects for which OBJ_IS_NATIVE returns true). All uses of these macros in
- * the engine are predicated on OBJ_IS_NATIVE or equivalent checks. These uses
- * are for optimizations above the JSObjectOps layer, under which object locks
- * normally hide.
- */
-#define JS_LOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \
- ? (void)0 \
- : (js_LockObj(cx, obj), \
- SET_OBJ_INFO(obj,__FILE__,__LINE__)))
-#define JS_UNLOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \
- ? (void)0 : js_UnlockObj(cx, obj))
-
-#define JS_LOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \
- (js_LockScope(cx, scope), \
- SET_SCOPE_INFO(scope,__FILE__,__LINE__)))
-#define JS_UNLOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \
- js_UnlockScope(cx, scope))
-#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) \
- js_TransferScopeLock(cx, scope, newscope)
-
-extern jsword js_CurrentThreadId();
-extern void js_LockRuntime(JSRuntime *rt);
-extern void js_UnlockRuntime(JSRuntime *rt);
-extern void js_LockObj(JSContext *cx, JSObject *obj);
-extern void js_UnlockObj(JSContext *cx, JSObject *obj);
-extern void js_LockScope(JSContext *cx, JSScope *scope);
-extern void js_UnlockScope(JSContext *cx, JSScope *scope);
-extern int js_SetupLocks(int,int);
-extern void js_CleanupLocks();
-extern void js_InitContextForLocking(JSContext *);
-extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *);
-extern JS_FRIEND_API(jsval)
-js_GetSlotThreadSafe(JSContext *, JSObject *, uint32);
-extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval);
-extern void js_InitLock(JSThinLock *);
-extern void js_FinishLock(JSThinLock *);
-extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope);
-
-#ifdef DEBUG
-
-#define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt)
-#define JS_IS_OBJ_LOCKED(cx,obj) js_IsObjLocked(cx,obj)
-#define JS_IS_SCOPE_LOCKED(cx,scope) js_IsScopeLocked(cx,scope)
-
-extern JSBool js_IsRuntimeLocked(JSRuntime *rt);
-extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj);
-extern JSBool js_IsScopeLocked(JSContext *cx, JSScope *scope);
-
-#else
-
-#define JS_IS_RUNTIME_LOCKED(rt) 0
-#define JS_IS_OBJ_LOCKED(cx,obj) 1
-#define JS_IS_SCOPE_LOCKED(cx,scope) 1
-
-#endif /* DEBUG */
-
-#define JS_LOCK_OBJ_VOID(cx, obj, e) \
- JS_BEGIN_MACRO \
- JS_LOCK_OBJ(cx, obj); \
- e; \
- JS_UNLOCK_OBJ(cx, obj); \
- JS_END_MACRO
-
-#define JS_LOCK_VOID(cx, e) \
- JS_BEGIN_MACRO \
- JSRuntime *_rt = (cx)->runtime; \
- JS_LOCK_RUNTIME_VOID(_rt, e); \
- JS_END_MACRO
-
-#if defined(JS_USE_ONLY_NSPR_LOCKS) || \
- !( (defined(_WIN32) && defined(_M_IX86)) || \
- (defined(__GNUC__) && defined(__i386__)) || \
- (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \
- defined(AIX) )
-
-#define NSPR_LOCK 1
-
-#undef JS_LOCK0
-#undef JS_UNLOCK0
-#define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M))
-#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat)))
-
-#else /* arch-tests */
-
-#undef NSPR_LOCK
-
-extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me);
-extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me);
-
-#endif /* arch-tests */
-
-#else /* !JS_THREADSAFE */
-
-#define JS_ATOMIC_INCREMENT(p) (++*(p))
-#define JS_ATOMIC_DECREMENT(p) (--*(p))
-#define JS_ATOMIC_ADD(p,v) (*(p) += (v))
-
-#define JS_CurrentThreadId() 0
-#define JS_NEW_LOCK() NULL
-#define JS_DESTROY_LOCK(l) ((void)0)
-#define JS_ACQUIRE_LOCK(l) ((void)0)
-#define JS_RELEASE_LOCK(l) ((void)0)
-#define JS_LOCK0(P,M) ((void)0)
-#define JS_UNLOCK0(P,M) ((void)0)
-
-#define JS_NEW_CONDVAR(l) NULL
-#define JS_DESTROY_CONDVAR(cv) ((void)0)
-#define JS_WAIT_CONDVAR(cv,to) ((void)0)
-#define JS_NOTIFY_CONDVAR(cv) ((void)0)
-#define JS_NOTIFY_ALL_CONDVAR(cv) ((void)0)
-
-#define JS_LOCK_RUNTIME(rt) ((void)0)
-#define JS_UNLOCK_RUNTIME(rt) ((void)0)
-#define JS_LOCK_OBJ(cx,obj) ((void)0)
-#define JS_UNLOCK_OBJ(cx,obj) ((void)0)
-#define JS_LOCK_OBJ_VOID(cx,obj,e) (e)
-#define JS_LOCK_SCOPE(cx,scope) ((void)0)
-#define JS_UNLOCK_SCOPE(cx,scope) ((void)0)
-#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0)
-
-#define JS_IS_RUNTIME_LOCKED(rt) 1
-#define JS_IS_OBJ_LOCKED(cx,obj) 1
-#define JS_IS_SCOPE_LOCKED(cx,scope) 1
-#define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
-
-#endif /* !JS_THREADSAFE */
-
-#define JS_LOCK_RUNTIME_VOID(rt,e) \
- JS_BEGIN_MACRO \
- JS_LOCK_RUNTIME(rt); \
- e; \
- JS_UNLOCK_RUNTIME(rt); \
- JS_END_MACRO
-
-#define JS_LOCK_GC(rt) JS_ACQUIRE_LOCK((rt)->gcLock)
-#define JS_UNLOCK_GC(rt) JS_RELEASE_LOCK((rt)->gcLock)
-#define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt))
-#define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT)
-#define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone)
-#define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \
- JS_NO_TIMEOUT)
-#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone)
-
-#define JS_LOCK(P,CX) JS_LOCK0(P,(CX)->thread)
-#define JS_UNLOCK(P,CX) JS_UNLOCK0(P,(CX)->thread)
-
-#ifndef SET_OBJ_INFO
-#define SET_OBJ_INFO(obj,f,l) ((void)0)
-#endif
-#ifndef SET_SCOPE_INFO
-#define SET_SCOPE_INFO(scope,f,l) ((void)0)
-#endif
-
-#endif /* jslock_h___ */
diff --git a/src/extension/script/js/jslocko.asm b/src/extension/script/js/jslocko.asm
deleted file mode 100644
index 2589bb7f9..000000000
--- a/src/extension/script/js/jslocko.asm
+++ /dev/null
@@ -1,59 +0,0 @@
-COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is an OS/2 implementation of js_CompareAndSwap in assembly
-
-The Initial Developer of the Original Code is IBM Corporation.
-Portions created by the Initial Developer are Copyright (C) 2001
-the Initial Developer. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
- |
-
- .486P
- .MODEL FLAT, OPTLINK
- .STACK
-
- .CODE
-
-;;;---------------------------------------------------------------------
-;;; int _Optlink js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-;;;---------------------------------------------------------------------
-js_CompareAndSwap PROC OPTLINK EXPORT
- push ebx
- mov ebx, eax
- mov eax, edx
- mov edx, ebx
- lock cmpxchg [ebx], ecx
- sete al
- and eax, 1h
- pop ebx
- ret
-js_CompareAndSwap endp
-
- END
diff --git a/src/extension/script/js/jslog2.c b/src/extension/script/js/jslog2.c
deleted file mode 100644
index 113c276d0..000000000
--- a/src/extension/script/js/jslog2.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "jsstddef.h"
-#include "jsbit.h"
-
-/*
-** Compute the log of the least power of 2 greater than or equal to n
-*/
-JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 n)
-{
- JSIntn log2 = 0;
-
- if (n & (n-1))
- log2++;
- if (n >> 16)
- log2 += 16, n >>= 16;
- if (n >> 8)
- log2 += 8, n >>= 8;
- if (n >> 4)
- log2 += 4, n >>= 4;
- if (n >> 2)
- log2 += 2, n >>= 2;
- if (n >> 1)
- log2++;
- return log2;
-}
-
-/*
-** Compute the log of the greatest power of 2 less than or equal to n.
-** This really just finds the highest set bit in the word.
-*/
-JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 n)
-{
- JSIntn log2 = 0;
-
- if (n >> 16)
- log2 += 16, n >>= 16;
- if (n >> 8)
- log2 += 8, n >>= 8;
- if (n >> 4)
- log2 += 4, n >>= 4;
- if (n >> 2)
- log2 += 2, n >>= 2;
- if (n >> 1)
- log2++;
- return log2;
-}
diff --git a/src/extension/script/js/jslong.c b/src/extension/script/js/jslong.c
deleted file mode 100644
index 76259e502..000000000
--- a/src/extension/script/js/jslong.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "jsstddef.h"
-#include "jstypes.h"
-#include "jslong.h"
-
-static JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
-static JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
-static JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
-
-#ifdef HAVE_WATCOM_BUG_2
-JSInt64 __pascal __loadds __export
- JSLL_Zero(void) { return ll_zero; }
-JSInt64 __pascal __loadds __export
- JSLL_MaxInt(void) { return ll_maxint; }
-JSInt64 __pascal __loadds __export
- JSLL_MinInt(void) { return ll_minint; }
-#else
-JS_PUBLIC_API(JSInt64) JSLL_Zero(void) { return ll_zero; }
-JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; }
-JS_PUBLIC_API(JSInt64) JSLL_MinInt(void) { return ll_minint; }
-#endif
-
-#ifndef JS_HAVE_LONG_LONG
-/*
-** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
-*/
-static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
-{
- JSUint32 d1, d0, q1, q0;
- JSUint32 r1, r0, m;
-
- d1 = jshi16(b);
- d0 = jslo16(b);
- r1 = a.hi % d1;
- q1 = a.hi / d1;
- m = q1 * d0;
- r1 = (r1 << 16) | jshi16(a.lo);
- if (r1 < m) {
- q1--, r1 += b;
- if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */
- && r1 < m) {
- q1--, r1 += b;
- }
- }
- r1 -= m;
- r0 = r1 % d1;
- q0 = r1 / d1;
- m = q0 * d0;
- r0 = (r0 << 16) | jslo16(a.lo);
- if (r0 < m) {
- q0--, r0 += b;
- if (r0 >= b
- && r0 < m) {
- q0--, r0 += b;
- }
- }
- *qp = (q1 << 16) | q0;
- *rp = r0 - m;
-}
-
-static JSUint32 CountLeadingZeros(JSUint32 a)
-{
- JSUint32 t;
- JSUint32 r = 32;
-
- if ((t = a >> 16) != 0)
- r -= 16, a = t;
- if ((t = a >> 8) != 0)
- r -= 8, a = t;
- if ((t = a >> 4) != 0)
- r -= 4, a = t;
- if ((t = a >> 2) != 0)
- r -= 2, a = t;
- if ((t = a >> 1) != 0)
- r -= 1, a = t;
- if (a & 1)
- r--;
- return r;
-}
-
-JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
-{
- JSUint32 n0, n1, n2;
- JSUint32 q0, q1;
- JSUint32 rsh, lsh;
-
- n0 = a.lo;
- n1 = a.hi;
-
- if (b.hi == 0) {
- if (b.lo > n1) {
- /* (0 q0) = (n1 n0) / (0 D0) */
-
- lsh = CountLeadingZeros(b.lo);
-
- if (lsh) {
- /*
- * Normalize, i.e. make the most significant bit of the
- * denominator be set.
- */
- b.lo = b.lo << lsh;
- n1 = (n1 << lsh) | (n0 >> (32 - lsh));
- n0 = n0 << lsh;
- }
-
- a.lo = n0, a.hi = n1;
- norm_udivmod32(&q0, &n0, a, b.lo);
- q1 = 0;
-
- /* remainder is in n0 >> lsh */
- } else {
- /* (q1 q0) = (n1 n0) / (0 d0) */
-
- if (b.lo == 0) /* user wants to divide by zero! */
- b.lo = 1 / b.lo; /* so go ahead and crash */
-
- lsh = CountLeadingZeros(b.lo);
-
- if (lsh == 0) {
- /*
- * From (n1 >= b.lo)
- * && (the most significant bit of b.lo is set),
- * conclude that
- * (the most significant bit of n1 is set)
- * && (the leading quotient digit q1 = 1).
- *
- * This special case is necessary, not an optimization
- * (Shifts counts of 32 are undefined).
- */
- n1 -= b.lo;
- q1 = 1;
- } else {
- /*
- * Normalize.
- */
- rsh = 32 - lsh;
-
- b.lo = b.lo << lsh;
- n2 = n1 >> rsh;
- n1 = (n1 << lsh) | (n0 >> rsh);
- n0 = n0 << lsh;
-
- a.lo = n1, a.hi = n2;
- norm_udivmod32(&q1, &n1, a, b.lo);
- }
-
- /* n1 != b.lo... */
-
- a.lo = n0, a.hi = n1;
- norm_udivmod32(&q0, &n0, a, b.lo);
-
- /* remainder in n0 >> lsh */
- }
-
- if (rp) {
- rp->lo = n0 >> lsh;
- rp->hi = 0;
- }
- } else {
- if (b.hi > n1) {
- /* (0 0) = (n1 n0) / (D1 d0) */
-
- q0 = 0;
- q1 = 0;
-
- /* remainder in (n1 n0) */
- if (rp) {
- rp->lo = n0;
- rp->hi = n1;
- }
- } else {
- /* (0 q0) = (n1 n0) / (d1 d0) */
-
- lsh = CountLeadingZeros(b.hi);
- if (lsh == 0) {
- /*
- * From (n1 >= b.hi)
- * && (the most significant bit of b.hi is set),
- * conclude that
- * (the most significant bit of n1 is set)
- * && (the quotient digit q0 = 0 or 1).
- *
- * This special case is necessary, not an optimization.
- */
-
- /*
- * The condition on the next line takes advantage of that
- * n1 >= b.hi (true due to control flow).
- */
- if (n1 > b.hi || n0 >= b.lo) {
- q0 = 1;
- a.lo = n0, a.hi = n1;
- JSLL_SUB(a, a, b);
- } else {
- q0 = 0;
- }
- q1 = 0;
-
- if (rp) {
- rp->lo = n0;
- rp->hi = n1;
- }
- } else {
- JSInt64 m;
-
- /*
- * Normalize.
- */
- rsh = 32 - lsh;
-
- b.hi = (b.hi << lsh) | (b.lo >> rsh);
- b.lo = b.lo << lsh;
- n2 = n1 >> rsh;
- n1 = (n1 << lsh) | (n0 >> rsh);
- n0 = n0 << lsh;
-
- a.lo = n1, a.hi = n2;
- norm_udivmod32(&q0, &n1, a, b.hi);
- JSLL_MUL32(m, q0, b.lo);
-
- if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
- q0--;
- JSLL_SUB(m, m, b);
- }
-
- q1 = 0;
-
- /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
- if (rp) {
- a.lo = n0, a.hi = n1;
- JSLL_SUB(a, a, m);
- rp->lo = (a.hi << rsh) | (a.lo >> lsh);
- rp->hi = a.hi >> lsh;
- }
- }
- }
- }
-
- if (qp) {
- qp->lo = q0;
- qp->hi = q1;
- }
-}
-#endif /* !JS_HAVE_LONG_LONG */
diff --git a/src/extension/script/js/jslong.h b/src/extension/script/js/jslong.h
deleted file mode 100644
index bde8bfbbf..000000000
--- a/src/extension/script/js/jslong.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-** File: jslong.h
-** Description: Portable access to 64 bit numerics
-**
-** Long-long (64-bit signed integer type) support. Some C compilers
-** don't support 64 bit integers yet, so we use these macros to
-** support both machines that do and don't.
-**/
-#ifndef jslong_h___
-#define jslong_h___
-
-#include "jstypes.h"
-
-JS_BEGIN_EXTERN_C
-
-/***********************************************************************
-** DEFINES: JSLL_MaxInt
-** JSLL_MinInt
-** JSLL_Zero
-** DESCRIPTION:
-** Various interesting constants and static variable
-** initializer
-***********************************************************************/
-#ifdef HAVE_WATCOM_BUG_2
-JSInt64 __pascal __loadds __export
- JSLL_MaxInt(void);
-JSInt64 __pascal __loadds __export
- JSLL_MinInt(void);
-JSInt64 __pascal __loadds __export
- JSLL_Zero(void);
-#else
-extern JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void);
-extern JS_PUBLIC_API(JSInt64) JSLL_MinInt(void);
-extern JS_PUBLIC_API(JSInt64) JSLL_Zero(void);
-#endif
-
-#define JSLL_MAXINT JSLL_MaxInt()
-#define JSLL_MININT JSLL_MinInt()
-#define JSLL_ZERO JSLL_Zero()
-
-#ifdef JS_HAVE_LONG_LONG
-
-#if JS_BYTES_PER_LONG == 8
-#define JSLL_INIT(hi, lo) ((hi ## L << 32) + lo ## L)
-#elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__)
-#define JSLL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64)
-#else
-#define JSLL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL)
-#endif
-
-/***********************************************************************
-** MACROS: JSLL_*
-** DESCRIPTION:
-** The following macros define portable access to the 64 bit
-** math facilities.
-**
-***********************************************************************/
-
-/***********************************************************************
-** MACROS: JSLL_<relational operators>
-**
-** JSLL_IS_ZERO Test for zero
-** JSLL_EQ Test for equality
-** JSLL_NE Test for inequality
-** JSLL_GE_ZERO Test for zero or positive
-** JSLL_CMP Compare two values
-***********************************************************************/
-#define JSLL_IS_ZERO(a) ((a) == 0)
-#define JSLL_EQ(a, b) ((a) == (b))
-#define JSLL_NE(a, b) ((a) != (b))
-#define JSLL_GE_ZERO(a) ((a) >= 0)
-#define JSLL_CMP(a, op, b) ((JSInt64)(a) op (JSInt64)(b))
-#define JSLL_UCMP(a, op, b) ((JSUint64)(a) op (JSUint64)(b))
-
-/***********************************************************************
-** MACROS: JSLL_<logical operators>
-**
-** JSLL_AND Logical and
-** JSLL_OR Logical or
-** JSLL_XOR Logical exclusion
-** JSLL_OR2 A disgusting deviation
-** JSLL_NOT Negation (one's compliment)
-***********************************************************************/
-#define JSLL_AND(r, a, b) ((r) = (a) & (b))
-#define JSLL_OR(r, a, b) ((r) = (a) | (b))
-#define JSLL_XOR(r, a, b) ((r) = (a) ^ (b))
-#define JSLL_OR2(r, a) ((r) = (r) | (a))
-#define JSLL_NOT(r, a) ((r) = ~(a))
-
-/***********************************************************************
-** MACROS: JSLL_<mathematical operators>
-**
-** JSLL_NEG Negation (two's compliment)
-** JSLL_ADD Summation (two's compliment)
-** JSLL_SUB Difference (two's compliment)
-***********************************************************************/
-#define JSLL_NEG(r, a) ((r) = -(a))
-#define JSLL_ADD(r, a, b) ((r) = (a) + (b))
-#define JSLL_SUB(r, a, b) ((r) = (a) - (b))
-
-/***********************************************************************
-** MACROS: JSLL_<mathematical operators>
-**
-** JSLL_MUL Product (two's compliment)
-** JSLL_DIV Quotient (two's compliment)
-** JSLL_MOD Modulus (two's compliment)
-***********************************************************************/
-#define JSLL_MUL(r, a, b) ((r) = (a) * (b))
-#define JSLL_DIV(r, a, b) ((r) = (a) / (b))
-#define JSLL_MOD(r, a, b) ((r) = (a) % (b))
-
-/***********************************************************************
-** MACROS: JSLL_<shifting operators>
-**
-** JSLL_SHL Shift left [0..64] bits
-** JSLL_SHR Shift right [0..64] bits with sign extension
-** JSLL_USHR Unsigned shift right [0..64] bits
-** JSLL_ISHL Signed shift left [0..64] bits
-***********************************************************************/
-#define JSLL_SHL(r, a, b) ((r) = (JSInt64)(a) << (b))
-#define JSLL_SHR(r, a, b) ((r) = (JSInt64)(a) >> (b))
-#define JSLL_USHR(r, a, b) ((r) = (JSUint64)(a) >> (b))
-#define JSLL_ISHL(r, a, b) ((r) = (JSInt64)(a) << (b))
-
-/***********************************************************************
-** MACROS: JSLL_<conversion operators>
-**
-** JSLL_L2I Convert to signed 32 bit
-** JSLL_L2UI Convert to unsigned 32 bit
-** JSLL_L2F Convert to floating point
-** JSLL_L2D Convert to floating point
-** JSLL_I2L Convert signed to 64 bit
-** JSLL_UI2L Convert unsigned to 64 bit
-** JSLL_F2L Convert float to 64 bit
-** JSLL_D2L Convert float to 64 bit
-***********************************************************************/
-#define JSLL_L2I(i, l) ((i) = (JSInt32)(l))
-#define JSLL_L2UI(ui, l) ((ui) = (JSUint32)(l))
-#define JSLL_L2F(f, l) ((f) = (JSFloat64)(l))
-#define JSLL_L2D(d, l) ((d) = (JSFloat64)(l))
-
-#define JSLL_I2L(l, i) ((l) = (JSInt64)(i))
-#define JSLL_UI2L(l, ui) ((l) = (JSInt64)(ui))
-#define JSLL_F2L(l, f) ((l) = (JSInt64)(f))
-#define JSLL_D2L(l, d) ((l) = (JSInt64)(d))
-
-/***********************************************************************
-** MACROS: JSLL_UDIVMOD
-** DESCRIPTION:
-** Produce both a quotient and a remainder given an unsigned
-** INPUTS: JSUint64 a: The dividend of the operation
-** JSUint64 b: The quotient of the operation
-** OUTPUTS: JSUint64 *qp: pointer to quotient
-** JSUint64 *rp: pointer to remainder
-***********************************************************************/
-#define JSLL_UDIVMOD(qp, rp, a, b) \
- (*(qp) = ((JSUint64)(a) / (b)), \
- *(rp) = ((JSUint64)(a) % (b)))
-
-#else /* !JS_HAVE_LONG_LONG */
-
-#ifdef IS_LITTLE_ENDIAN
-#define JSLL_INIT(hi, lo) {JS_INT32(lo), JS_INT32(hi)}
-#else
-#define JSLL_INIT(hi, lo) {JS_INT32(hi), JS_INT32(lo)}
-#endif
-
-#define JSLL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0))
-#define JSLL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo))
-#define JSLL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo))
-#define JSLL_GE_ZERO(a) (((a).hi >> 31) == 0)
-
-#ifdef DEBUG
-#define JSLL_CMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_CMP(a, op, b))
-#define JSLL_UCMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_UCMP(a, op, b))
-#else
-#define JSLL_CMP(a, op, b) JSLL_REAL_CMP(a, op, b)
-#define JSLL_UCMP(a, op, b) JSLL_REAL_UCMP(a, op, b)
-#endif
-
-#define JSLL_REAL_CMP(a,op,b) (((JSInt32)(a).hi op (JSInt32)(b).hi) || \
- (((a).hi == (b).hi) && ((a).lo op (b).lo)))
-#define JSLL_REAL_UCMP(a,op,b) (((a).hi op (b).hi) || \
- (((a).hi == (b).hi) && ((a).lo op (b).lo)))
-
-#define JSLL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \
- (r).hi = (a).hi & (b).hi)
-#define JSLL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \
- (r).hi = (a).hi | (b).hi)
-#define JSLL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \
- (r).hi = (a).hi ^ (b).hi)
-#define JSLL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \
- (r).hi = (r).hi | (a).hi)
-#define JSLL_NOT(r, a) ((r).lo = ~(a).lo, \
- (r).hi = ~(a).hi)
-
-#define JSLL_NEG(r, a) ((r).lo = -(JSInt32)(a).lo, \
- (r).hi = -(JSInt32)(a).hi - ((r).lo != 0))
-#define JSLL_ADD(r, a, b) { \
- JSInt64 _a, _b; \
- _a = a; _b = b; \
- (r).lo = _a.lo + _b.lo; \
- (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
-}
-
-#define JSLL_SUB(r, a, b) { \
- JSInt64 _a, _b; \
- _a = a; _b = b; \
- (r).lo = _a.lo - _b.lo; \
- (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
-}
-
-#define JSLL_MUL(r, a, b) { \
- JSInt64 _a, _b; \
- _a = a; _b = b; \
- JSLL_MUL32(r, _a.lo, _b.lo); \
- (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
-}
-
-#define jslo16(a) ((a) & JS_BITMASK(16))
-#define jshi16(a) ((a) >> 16)
-
-#define JSLL_MUL32(r, a, b) { \
- JSUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
- _a1 = jshi16(a), _a0 = jslo16(a); \
- _b1 = jshi16(b), _b0 = jslo16(b); \
- _y0 = _a0 * _b0; \
- _y1 = _a0 * _b1; \
- _y2 = _a1 * _b0; \
- _y3 = _a1 * _b1; \
- _y1 += jshi16(_y0); /* can't carry */ \
- _y1 += _y2; /* might carry */ \
- if (_y1 < _y2) \
- _y3 += (JSUint32)(JS_BIT(16)); /* propagate */ \
- (r).lo = (jslo16(_y1) << 16) + jslo16(_y0); \
- (r).hi = _y3 + jshi16(_y1); \
-}
-
-#define JSLL_UDIVMOD(qp, rp, a, b) jsll_udivmod(qp, rp, a, b)
-
-extern JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b);
-
-#define JSLL_DIV(r, a, b) { \
- JSInt64 _a, _b; \
- JSUint32 _negative = (JSInt32)(a).hi < 0; \
- if (_negative) { \
- JSLL_NEG(_a, a); \
- } else { \
- _a = a; \
- } \
- if ((JSInt32)(b).hi < 0) { \
- _negative ^= 1; \
- JSLL_NEG(_b, b); \
- } else { \
- _b = b; \
- } \
- JSLL_UDIVMOD(&(r), 0, _a, _b); \
- if (_negative) \
- JSLL_NEG(r, r); \
-}
-
-#define JSLL_MOD(r, a, b) { \
- JSInt64 _a, _b; \
- JSUint32 _negative = (JSInt32)(a).hi < 0; \
- if (_negative) { \
- JSLL_NEG(_a, a); \
- } else { \
- _a = a; \
- } \
- if ((JSInt32)(b).hi < 0) { \
- JSLL_NEG(_b, b); \
- } else { \
- _b = b; \
- } \
- JSLL_UDIVMOD(0, &(r), _a, _b); \
- if (_negative) \
- JSLL_NEG(r, r); \
-}
-
-#define JSLL_SHL(r, a, b) { \
- if (b) { \
- JSInt64 _a; \
- _a = a; \
- if ((b) < 32) { \
- (r).lo = _a.lo << ((b) & 31); \
- (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
- } else { \
- (r).lo = 0; \
- (r).hi = _a.lo << ((b) & 31); \
- } \
- } else { \
- (r) = (a); \
- } \
-}
-
-/* a is an JSInt32, b is JSInt32, r is JSInt64 */
-#define JSLL_ISHL(r, a, b) { \
- if (b) { \
- JSInt64 _a; \
- _a.lo = (a); \
- _a.hi = 0; \
- if ((b) < 32) { \
- (r).lo = (a) << ((b) & 31); \
- (r).hi = ((a) >> (32 - (b))); \
- } else { \
- (r).lo = 0; \
- (r).hi = (a) << ((b) & 31); \
- } \
- } else { \
- (r).lo = (a); \
- (r).hi = 0; \
- } \
-}
-
-#define JSLL_SHR(r, a, b) { \
- if (b) { \
- JSInt64 _a; \
- _a = a; \
- if ((b) < 32) { \
- (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
- (r).hi = (JSInt32)_a.hi >> ((b) & 31); \
- } else { \
- (r).lo = (JSInt32)_a.hi >> ((b) & 31); \
- (r).hi = (JSInt32)_a.hi >> 31; \
- } \
- } else { \
- (r) = (a); \
- } \
-}
-
-#define JSLL_USHR(r, a, b) { \
- if (b) { \
- JSInt64 _a; \
- _a = a; \
- if ((b) < 32) { \
- (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
- (r).hi = _a.hi >> ((b) & 31); \
- } else { \
- (r).lo = _a.hi >> ((b) & 31); \
- (r).hi = 0; \
- } \
- } else { \
- (r) = (a); \
- } \
-}
-
-#define JSLL_L2I(i, l) ((i) = (l).lo)
-#define JSLL_L2UI(ui, l) ((ui) = (l).lo)
-#define JSLL_L2F(f, l) { double _d; JSLL_L2D(_d, l); (f) = (JSFloat64)_d; }
-
-#define JSLL_L2D(d, l) { \
- int _negative; \
- JSInt64 _absval; \
- \
- _negative = (l).hi >> 31; \
- if (_negative) { \
- JSLL_NEG(_absval, l); \
- } else { \
- _absval = l; \
- } \
- (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
- if (_negative) \
- (d) = -(d); \
-}
-
-#define JSLL_I2L(l, i) { JSInt32 _i = (i) >> 31; (l).lo = (i); (l).hi = _i; }
-#define JSLL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0)
-#define JSLL_F2L(l, f) { double _d = (double)f; JSLL_D2L(l, _d); }
-
-#define JSLL_D2L(l, d) { \
- int _negative; \
- double _absval, _d_hi; \
- JSInt64 _lo_d; \
- \
- _negative = ((d) < 0); \
- _absval = _negative ? -(d) : (d); \
- \
- (l).hi = _absval / 4.294967296e9; \
- (l).lo = 0; \
- JSLL_L2D(_d_hi, l); \
- _absval -= _d_hi; \
- _lo_d.hi = 0; \
- if (_absval < 0) { \
- _lo_d.lo = -_absval; \
- JSLL_SUB(l, l, _lo_d); \
- } else { \
- _lo_d.lo = _absval; \
- JSLL_ADD(l, l, _lo_d); \
- } \
- \
- if (_negative) \
- JSLL_NEG(l, l); \
-}
-
-#endif /* !JS_HAVE_LONG_LONG */
-
-JS_END_EXTERN_C
-
-#endif /* jslong_h___ */
diff --git a/src/extension/script/js/jsmath.c b/src/extension/script/js/jsmath.c
deleted file mode 100644
index 9c6fcec0e..000000000
--- a/src/extension/script/js/jsmath.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS math package.
- */
-#include "jsstddef.h"
-#include "jslibmath.h"
-#include <stdlib.h>
-#include "jstypes.h"
-#include "jslong.h"
-#include "prmjtime.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jslock.h"
-#include "jsmath.h"
-#include "jsnum.h"
-#include "jsobj.h"
-
-#ifndef M_E
-#define M_E 2.7182818284590452354
-#endif
-#ifndef M_LOG2E
-#define M_LOG2E 1.4426950408889634074
-#endif
-#ifndef M_LOG10E
-#define M_LOG10E 0.43429448190325182765
-#endif
-#ifndef M_LN2
-#define M_LN2 0.69314718055994530942
-#endif
-#ifndef M_LN10
-#define M_LN10 2.30258509299404568402
-#endif
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
-#ifndef M_SQRT1_2
-#define M_SQRT1_2 0.70710678118654752440
-#endif
-
-static JSConstDoubleSpec math_constants[] = {
- {M_E, "E", 0, {0,0,0}},
- {M_LOG2E, "LOG2E", 0, {0,0,0}},
- {M_LOG10E, "LOG10E", 0, {0,0,0}},
- {M_LN2, "LN2", 0, {0,0,0}},
- {M_LN10, "LN10", 0, {0,0,0}},
- {M_PI, "PI", 0, {0,0,0}},
- {M_SQRT2, "SQRT2", 0, {0,0,0}},
- {M_SQRT1_2, "SQRT1_2", 0, {0,0,0}},
- {0,0,0,{0,0,0}}
-};
-
-static JSClass math_class = {
- "Math",
- 0,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-static JSBool
-math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_fabs(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_acos(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
-#ifdef XP_MAC
- if (x == 0)
- return js_NewNumberValue(cx, x, rval);
-#endif
- z = fd_asin(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
-#ifdef XP_MAC
- if (x == 0)
- return js_NewNumberValue(cx, x, rval);
-#endif
- z = fd_atan(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, y, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- if (!js_ValueToNumber(cx, argv[1], &y))
- return JS_FALSE;
- z = fd_atan2(x, y);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_ceil(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_cos(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
-#ifdef _WIN32
- if (!JSDOUBLE_IS_NaN(x)) {
- if (x == *cx->runtime->jsPositiveInfinity) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
- return JS_TRUE;
- }
- if (x == *cx->runtime->jsNegativeInfinity) {
- *rval = JSVAL_ZERO;
- return JS_TRUE;
- }
- }
-#endif
- z = fd_exp(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_floor(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_log(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z = *cx->runtime->jsNegativeInfinity;
- uintN i;
-
- if (argc == 0) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
- return JS_TRUE;
- }
- for (i = 0; i < argc; i++) {
- if (!js_ValueToNumber(cx, argv[i], &x))
- return JS_FALSE;
- if (JSDOUBLE_IS_NaN(x)) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
- if ((x==0)&&(x==z)&&(fd_copysign(1.0,z)==-1))
- z = x;
- else
- z = (x > z) ? x : z;
- }
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z = *cx->runtime->jsPositiveInfinity;
- uintN i;
-
- if (argc == 0) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
- return JS_TRUE;
- }
- for (i = 0; i < argc; i++) {
- if (!js_ValueToNumber(cx, argv[i], &x))
- return JS_FALSE;
- if (JSDOUBLE_IS_NaN(x)) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
- if ((x==0)&&(x==z)&&(fd_copysign(1.0,x)==-1))
- z = x;
- else
- z = (x < z) ? x : z;
- }
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, y, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- if (!js_ValueToNumber(cx, argv[1], &y))
- return JS_FALSE;
- z = fd_pow(x, y);
- return js_NewNumberValue(cx, z, rval);
-}
-
-/*
- * Math.random() support, lifted from java.util.Random.java.
- */
-static void
-random_setSeed(JSRuntime *rt, int64 seed)
-{
- int64 tmp;
-
- JSLL_I2L(tmp, 1000);
- JSLL_DIV(seed, seed, tmp);
- JSLL_XOR(tmp, seed, rt->rngMultiplier);
- JSLL_AND(rt->rngSeed, tmp, rt->rngMask);
-}
-
-static void
-random_init(JSRuntime *rt)
-{
- int64 tmp, tmp2;
-
- /* Do at most once. */
- if (rt->rngInitialized)
- return;
- rt->rngInitialized = JS_TRUE;
-
- /* rt->rngMultiplier = 0x5DEECE66DL */
- JSLL_ISHL(tmp, 0x5, 32);
- JSLL_UI2L(tmp2, 0xDEECE66DL);
- JSLL_OR(rt->rngMultiplier, tmp, tmp2);
-
- /* rt->rngAddend = 0xBL */
- JSLL_I2L(rt->rngAddend, 0xBL);
-
- /* rt->rngMask = (1L << 48) - 1 */
- JSLL_I2L(tmp, 1);
- JSLL_SHL(tmp2, tmp, 48);
- JSLL_SUB(rt->rngMask, tmp2, tmp);
-
- /* rt->rngDscale = (jsdouble)(1L << 53) */
- JSLL_SHL(tmp2, tmp, 53);
- JSLL_L2D(rt->rngDscale, tmp2);
-
- /* Finally, set the seed from current time. */
- random_setSeed(rt, PRMJ_Now());
-}
-
-static uint32
-random_next(JSRuntime *rt, int bits)
-{
- int64 nextseed, tmp;
- uint32 retval;
-
- JSLL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier);
- JSLL_ADD(nextseed, nextseed, rt->rngAddend);
- JSLL_AND(nextseed, nextseed, rt->rngMask);
- rt->rngSeed = nextseed;
- JSLL_USHR(tmp, nextseed, 48 - bits);
- JSLL_L2I(retval, tmp);
- return retval;
-}
-
-static jsdouble
-random_nextDouble(JSRuntime *rt)
-{
- int64 tmp, tmp2;
- jsdouble d;
-
- JSLL_ISHL(tmp, random_next(rt, 26), 27);
- JSLL_UI2L(tmp2, random_next(rt, 27));
- JSLL_ADD(tmp, tmp, tmp2);
- JSLL_L2D(d, tmp);
- return d / rt->rngDscale;
-}
-
-static JSBool
-math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSRuntime *rt;
- jsdouble z;
-
- rt = cx->runtime;
- JS_LOCK_RUNTIME(rt);
- random_init(rt);
- z = random_nextDouble(rt);
- JS_UNLOCK_RUNTIME(rt);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_copysign(fd_floor(x + 0.5), x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_sin(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_sqrt(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-static JSBool
-math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x, z;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- z = fd_tan(x);
- return js_NewNumberValue(cx, z, rval);
-}
-
-#if JS_HAS_TOSOURCE
-static JSBool
-math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- *rval = ATOM_KEY(cx->runtime->atomState.MathAtom);
- return JS_TRUE;
-}
-#endif
-
-static JSFunctionSpec math_static_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, math_toSource, 0, 0, 0},
-#endif
- {"abs", math_abs, 1, 0, 0},
- {"acos", math_acos, 1, 0, 0},
- {"asin", math_asin, 1, 0, 0},
- {"atan", math_atan, 1, 0, 0},
- {"atan2", math_atan2, 2, 0, 0},
- {"ceil", math_ceil, 1, 0, 0},
- {"cos", math_cos, 1, 0, 0},
- {"exp", math_exp, 1, 0, 0},
- {"floor", math_floor, 1, 0, 0},
- {"log", math_log, 1, 0, 0},
- {"max", math_max, 2, 0, 0},
- {"min", math_min, 2, 0, 0},
- {"pow", math_pow, 2, 0, 0},
- {"random", math_random, 0, 0, 0},
- {"round", math_round, 1, 0, 0},
- {"sin", math_sin, 1, 0, 0},
- {"sqrt", math_sqrt, 1, 0, 0},
- {"tan", math_tan, 1, 0, 0},
- {0,0,0,0,0}
-};
-
-JSObject *
-js_InitMathClass(JSContext *cx, JSObject *obj)
-{
- JSObject *Math;
-
- Math = JS_DefineObject(cx, obj, "Math", &math_class, NULL, 0);
- if (!Math)
- return NULL;
- if (!JS_DefineFunctions(cx, Math, math_static_methods))
- return NULL;
- if (!JS_DefineConstDoubles(cx, Math, math_constants))
- return NULL;
- return Math;
-}
diff --git a/src/extension/script/js/jsmath.h b/src/extension/script/js/jsmath.h
deleted file mode 100644
index 7a6b21657..000000000
--- a/src/extension/script/js/jsmath.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998-1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* -*- Mode: C; tab-width: 8 -*-
- * Copyright (C) 1998-1999 Netscape Communications Corporation, All Rights Reserved.
- */
-
-#ifndef jsmath_h___
-#define jsmath_h___
-/*
- * JS math functions.
- */
-
-JS_BEGIN_EXTERN_C
-
-extern JSObject *
-js_InitMathClass(JSContext *cx, JSObject *obj);
-
-JS_END_EXTERN_C
-
-#endif /* jsmath_h___ */
diff --git a/src/extension/script/js/jsnum.c b/src/extension/script/js/jsnum.c
deleted file mode 100644
index 6f6963b69..000000000
--- a/src/extension/script/js/jsnum.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * IBM Corp.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS number type and wrapper class.
- */
-#include "jsstddef.h"
-#if defined(XP_WIN) || defined(XP_OS2)
-#include <float.h>
-#endif
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdtoa.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsprf.h"
-#include "jsstr.h"
-
-static JSBool
-num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
- return JS_TRUE;
-}
-
-static JSBool
-num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble x;
-
- if (!js_ValueToNumber(cx, argv[0], &x))
- return JS_FALSE;
- *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
- return JS_TRUE;
-}
-
-static JSBool
-num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsdouble d;
- const jschar *bp, *ep;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- /* XXXbe js_strtod shouldn't require NUL termination */
- bp = js_UndependString(cx, str);
- if (!bp)
- return JS_FALSE;
- if (!js_strtod(cx, bp, &ep, &d))
- return JS_FALSE;
- if (ep == bp) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
- return js_NewNumberValue(cx, d, rval);
-}
-
-/* See ECMA 15.1.2.2. */
-static JSBool
-num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsint radix;
- jsdouble d;
- const jschar *bp, *ep;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
-
- if (argc > 1) {
- if (!js_ValueToECMAInt32(cx, argv[1], &radix))
- return JS_FALSE;
- } else
- radix = 0;
-
- if (radix != 0 && (radix < 2 || radix > 36)) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
- /* XXXbe js_strtointeger shouldn't require NUL termination */
- bp = js_UndependString(cx, str);
- if (!bp)
- return JS_FALSE;
- if (!js_strtointeger(cx, bp, &ep, radix, &d))
- return JS_FALSE;
- if (ep == bp) {
- *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
- return JS_TRUE;
- }
- return js_NewNumberValue(cx, d, rval);
-}
-
-const char js_Infinity_str[] = "Infinity";
-const char js_NaN_str[] = "NaN";
-const char js_isNaN_str[] = "isNaN";
-const char js_isFinite_str[] = "isFinite";
-const char js_parseFloat_str[] = "parseFloat";
-const char js_parseInt_str[] = "parseInt";
-
-static JSFunctionSpec number_functions[] = {
- {"isNaN", num_isNaN, 1,0,0},
- {"isFinite", num_isFinite, 1,0,0},
- {"parseFloat", num_parseFloat, 1,0,0},
- {"parseInt", num_parseInt, 2,0,0},
- {0,0,0,0,0}
-};
-
-static JSClass number_class = {
- "Number",
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-static JSBool
-Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsdouble d;
- jsval v;
-
- if (argc != 0) {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- } else {
- d = 0.0;
- }
- if (!js_NewNumberValue(cx, d, &v))
- return JS_FALSE;
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- *rval = v;
- return JS_TRUE;
- }
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
- return JS_TRUE;
-}
-
-#if JS_HAS_TOSOURCE
-static JSBool
-num_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
- jsdouble d;
- char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr;
- char buf[64];
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &number_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- JS_ASSERT(JSVAL_IS_NUMBER(v));
- d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
- numStr = JS_dtostr(numBuf, sizeof numBuf, DTOSTR_STANDARD, 0, d);
- if (!numStr) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- JS_snprintf(buf, sizeof buf, "(new %s(%s))", number_class.name, numStr);
- str = JS_NewStringCopyZ(cx, buf);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif
-
-/* The buf must be big enough for MIN_INT to fit including '-' and '\0'. */
-static char *
-IntToString(jsint i, char *buf, size_t bufSize)
-{
- char *cp;
- jsuint u;
-
- u = (i < 0) ? -i : i;
-
- cp = buf + bufSize; /* one past last buffer cell */
- *--cp = '\0'; /* null terminate the string to be */
-
- /*
- * Build the string from behind. We use multiply and subtraction
- * instead of modulus because that's much faster.
- */
- do {
- jsuint newu = u / 10;
- *--cp = (char)(u - newu * 10) + '0';
- u = newu;
- } while (u != 0);
-
- if (i < 0)
- *--cp = '-';
-
- return cp;
-}
-
-static JSBool
-num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
- jsdouble d;
- jsint base;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &number_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- JS_ASSERT(JSVAL_IS_NUMBER(v));
- d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
- base = 10;
- if (argc != 0) {
- if (!js_ValueToECMAInt32(cx, argv[0], &base))
- return JS_FALSE;
- if (base < 2 || base > 36) {
- char numBuf[12];
- char *numStr = IntToString(base, numBuf, sizeof numBuf);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
- numStr);
- return JS_FALSE;
- }
- }
- if (base == 10)
- str = js_NumberToString(cx, d);
- else {
- char *dStr = JS_dtobasestr(base, d);
- if (!dStr) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- str = JS_NewStringCopyZ(cx, dStr);
- free(dStr);
- }
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-num_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval)
-{
-/*
- * For now, forcibly ignore the first (or any) argument and return toString().
- * ECMA allows this, although it doesn't 'encourage it'.
- * [The first argument is being reserved by ECMA and we don't want it confused
- * with a radix]
- */
- return num_toString(cx, obj, 0, argv, rval);
-}
-
-static JSBool
-num_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (!JS_InstanceOf(cx, obj, &number_class, argv))
- return JS_FALSE;
- *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- return JS_TRUE;
-}
-
-
-#if JS_HAS_NUMBER_FORMATS
-#define MAX_PRECISION 100
-
-static JSBool
-num_to(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, JSDToStrMode zeroArgMode,
- JSDToStrMode oneArgMode, jsint precisionMin, jsint precisionMax, jsint precisionOffset)
-{
- jsval v;
- jsdouble d, precision;
- JSString *str;
- char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)], *numStr; /* Use MAX_PRECISION+1 because precisionOffset can be 1 */
-
- if (!JS_InstanceOf(cx, obj, &number_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- JS_ASSERT(JSVAL_IS_NUMBER(v));
- d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
-
- if (JSVAL_IS_VOID(argv[0])) {
- precision = 0.0;
- oneArgMode = zeroArgMode;
- } else {
- if (!js_ValueToNumber(cx, argv[0], &precision))
- return JS_FALSE;
- precision = js_DoubleToInteger(precision);
- if (precision < precisionMin || precision > precisionMax) {
- numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, precision);
- if (!numStr)
- JS_ReportOutOfMemory(cx);
- else
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_PRECISION_RANGE, numStr);
- return JS_FALSE;
- }
- }
-
- numStr = JS_dtostr(buf, sizeof buf, oneArgMode, (jsint)precision + precisionOffset, d);
- if (!numStr) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- str = JS_NewStringCopyZ(cx, numStr);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-num_toFixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
- return num_to(cx, obj, argc, argv, rval, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0);
-}
-
-static JSBool
-num_toExponential(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
- return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1);
-}
-
-static JSBool
-num_toPrecision(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
- return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0);
-}
-#endif /* JS_HAS_NUMBER_FORMATS */
-
-
-static JSFunctionSpec number_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, num_toSource, 0,0,0},
-#endif
- {js_toString_str, num_toString, 0,0,0},
- {js_toLocaleString_str, num_toLocaleString, 0,0,0},
- {js_valueOf_str, num_valueOf, 0,0,0},
-#if JS_HAS_NUMBER_FORMATS
- {"toFixed", num_toFixed, 1,0,0},
- {"toExponential", num_toExponential, 1,0,0},
- {"toPrecision", num_toPrecision, 1,0,0},
-#endif
- {0,0,0,0,0}
-};
-
-/* NB: Keep this in synch with number_constants[]. */
-enum nc_slot {
- NC_NaN,
- NC_POSITIVE_INFINITY,
- NC_NEGATIVE_INFINITY,
- NC_MAX_VALUE,
- NC_MIN_VALUE,
- NC_LIMIT
-};
-
-/*
- * Some to most C compilers forbid spelling these at compile time, or barf
- * if you try, so all but MAX_VALUE are set up by js_InitRuntimeNumberState
- * using union jsdpun.
- */
-static JSConstDoubleSpec number_constants[] = {
- {0, js_NaN_str, 0,{0,0,0}},
- {0, "POSITIVE_INFINITY", 0,{0,0,0}},
- {0, "NEGATIVE_INFINITY", 0,{0,0,0}},
- {1.7976931348623157E+308, "MAX_VALUE", 0,{0,0,0}},
- {0, "MIN_VALUE", 0,{0,0,0}},
- {0,0,0,{0,0,0}}
-};
-
-static jsdouble NaN;
-
-
-#if defined XP_WIN && \
- !defined __MWERKS__ && \
- (defined _M_IX86 || \
- (defined __GNUC__ && !defined __MINGW32__))
-
-/*
- * Set the exception mask to mask all exceptions and set the FPU precision
- * to 53 bit mantissa.
- * On Alpha platform this is handled via Compiler option.
- */
-#define FIX_FPU() _control87(MCW_EM | PC_53, MCW_EM | MCW_PC)
-
-#else
-
-#define FIX_FPU() ((void)0)
-
-#endif
-
-JSBool
-js_InitRuntimeNumberState(JSContext *cx)
-{
- JSRuntime *rt;
- jsdpun u;
-
- rt = cx->runtime;
- JS_ASSERT(!rt->jsNaN);
-
- FIX_FPU();
-
- u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
- u.s.lo = 0xffffffff;
- number_constants[NC_NaN].dval = NaN = u.d;
- rt->jsNaN = js_NewDouble(cx, NaN);
- if (!rt->jsNaN || !js_LockGCThing(cx, rt->jsNaN))
- return JS_FALSE;
-
- u.s.hi = JSDOUBLE_HI32_EXPMASK;
- u.s.lo = 0x00000000;
- number_constants[NC_POSITIVE_INFINITY].dval = u.d;
- rt->jsPositiveInfinity = js_NewDouble(cx, u.d);
- if (!rt->jsPositiveInfinity ||
- !js_LockGCThing(cx, rt->jsPositiveInfinity)) {
- return JS_FALSE;
- }
-
- u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK;
- u.s.lo = 0x00000000;
- number_constants[NC_NEGATIVE_INFINITY].dval = u.d;
- rt->jsNegativeInfinity = js_NewDouble(cx, u.d);
- if (!rt->jsNegativeInfinity ||
- !js_LockGCThing(cx, rt->jsNegativeInfinity)) {
- return JS_FALSE;
- }
-
- u.s.hi = 0;
- u.s.lo = 1;
- number_constants[NC_MIN_VALUE].dval = u.d;
-
- return JS_TRUE;
-}
-
-void
-js_FinishRuntimeNumberState(JSContext *cx)
-{
- JSRuntime *rt = cx->runtime;
-
- js_UnlockGCThingRT(rt, rt->jsNaN);
- js_UnlockGCThingRT(rt, rt->jsNegativeInfinity);
- js_UnlockGCThingRT(rt, rt->jsPositiveInfinity);
-
- rt->jsNaN = NULL;
- rt->jsNegativeInfinity = NULL;
- rt->jsPositiveInfinity = NULL;
-}
-
-JSObject *
-js_InitNumberClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto, *ctor;
- JSRuntime *rt;
-
- /* XXX must do at least once per new thread, so do it per JSContext... */
- FIX_FPU();
-
- if (!JS_DefineFunctions(cx, obj, number_functions))
- return NULL;
-
- proto = JS_InitClass(cx, obj, NULL, &number_class, Number, 1,
- NULL, number_methods, NULL, NULL);
- if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
- return NULL;
- OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO);
- if (!JS_DefineConstDoubles(cx, ctor, number_constants))
- return NULL;
-
- /* ECMA 15.1.1.1 */
- rt = cx->runtime;
- if (!JS_DefineProperty(cx, obj, js_NaN_str, DOUBLE_TO_JSVAL(rt->jsNaN),
- NULL, NULL, JSPROP_PERMANENT)) {
- return NULL;
- }
-
- /* ECMA 15.1.1.2 */
- if (!JS_DefineProperty(cx, obj, js_Infinity_str,
- DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
- NULL, NULL, JSPROP_PERMANENT)) {
- return NULL;
- }
- return proto;
-}
-
-jsdouble *
-js_NewDouble(JSContext *cx, jsdouble d)
-{
- jsdouble *dp;
-
- dp = (jsdouble *) js_AllocGCThing(cx, GCX_DOUBLE);
- if (!dp)
- return NULL;
- *dp = d;
- return dp;
-}
-
-void
-js_FinalizeDouble(JSContext *cx, jsdouble *dp)
-{
- *dp = NaN;
-}
-
-JSBool
-js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
-{
- jsdouble *dp;
-
- dp = js_NewDouble(cx, d);
- if (!dp)
- return JS_FALSE;
- *rval = DOUBLE_TO_JSVAL(dp);
- return JS_TRUE;
-}
-
-JSBool
-js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
-{
- jsint i;
- JSBool ok;
-
- SET_FPU();
-
- if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
- *rval = INT_TO_JSVAL(i);
- ok = JS_TRUE;
- } else {
- ok = js_NewDoubleValue(cx, d, rval);
- }
-
- RESTORE_FPU();
- return ok;
-}
-
-JSObject *
-js_NumberToObject(JSContext *cx, jsdouble d)
-{
- JSObject *obj;
- jsval v;
-
- obj = js_NewObject(cx, &number_class, NULL, NULL);
- if (!obj)
- return NULL;
- if (!js_NewNumberValue(cx, d, &v)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
- return obj;
-}
-
-JSString *
-js_NumberToString(JSContext *cx, jsdouble d)
-{
- jsint i;
- char buf[DTOSTR_STANDARD_BUFFER_SIZE];
- char *numStr;
-
- if (JSDOUBLE_IS_INT(d, i))
- numStr = IntToString(i, buf, sizeof buf);
- else {
- numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, d);
- if (!numStr) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- }
- return JS_NewStringCopyZ(cx, numStr);
-}
-
-JSBool
-js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
-{
- JSObject *obj;
- JSString *str;
- const jschar *bp, *ep;
-
- if (JSVAL_IS_OBJECT(v)) {
- obj = JSVAL_TO_OBJECT(v);
- if (!obj) {
- *dp = 0;
- return JS_TRUE;
- }
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
- return JS_FALSE;
- }
- if (JSVAL_IS_INT(v)) {
- *dp = (jsdouble)JSVAL_TO_INT(v);
- } else if (JSVAL_IS_DOUBLE(v)) {
- *dp = *JSVAL_TO_DOUBLE(v);
- } else if (JSVAL_IS_STRING(v)) {
- str = JSVAL_TO_STRING(v);
- /*
- * Note that ECMA doesn't treat a string beginning with a '0' as an
- * octal number here. This works because all such numbers will be
- * interpreted as decimal by js_strtod and will never get passed to
- * js_strtointeger (which would interpret them as octal).
- */
- /* XXXbe js_strtod shouldn't require NUL termination */
- bp = js_UndependString(cx, str);
- if (!bp)
- return JS_FALSE;
- if ((!js_strtod(cx, bp, &ep, dp) ||
- js_SkipWhiteSpace(ep) != bp + str->length) &&
- (!js_strtointeger(cx, bp, &ep, 0, dp) ||
- js_SkipWhiteSpace(ep) != bp + str->length)) {
- goto badstr;
- }
- } else if (JSVAL_IS_BOOLEAN(v)) {
- *dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
- } else {
-#if JS_BUG_FALLIBLE_TONUM
- str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
-badstr:
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN,
- JS_GetStringBytes(str));
-
- }
- return JS_FALSE;
-#else
-badstr:
- *dp = *cx->runtime->jsNaN;
-#endif
- }
- return JS_TRUE;
-}
-
-JSBool
-js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
-{
- jsdouble d;
-
- if (!js_ValueToNumber(cx, v, &d))
- return JS_FALSE;
- return js_DoubleToECMAInt32(cx, d, ip);
-}
-
-JSBool
-js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip)
-{
- jsdouble two32 = 4294967296.0;
- jsdouble two31 = 2147483648.0;
-
- if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
- *ip = 0;
- return JS_TRUE;
- }
- d = fmod(d, two32);
- d = (d >= 0) ? floor(d) : ceil(d) + two32;
- if (d >= two31)
- *ip = (int32)(d - two32);
- else
- *ip = (int32)d;
- return JS_TRUE;
-}
-
-JSBool
-js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
-{
- jsdouble d;
-
- if (!js_ValueToNumber(cx, v, &d))
- return JS_FALSE;
- return js_DoubleToECMAUint32(cx, d, ip);
-}
-
-JSBool
-js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip)
-{
- JSBool neg;
- jsdouble two32 = 4294967296.0;
-
- if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
- *ip = 0;
- return JS_TRUE;
- }
-
- neg = (d < 0);
- d = floor(neg ? -d : d);
- d = neg ? -d : d;
-
- d = fmod(d, two32);
-
- d = (d >= 0) ? d : d + two32;
- *ip = (uint32)d;
- return JS_TRUE;
-}
-
-JSBool
-js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
-{
- jsdouble d;
- JSString *str;
-
- if (JSVAL_IS_INT(v)) {
- *ip = JSVAL_TO_INT(v);
- return JS_TRUE;
- }
- if (!js_ValueToNumber(cx, v, &d))
- return JS_FALSE;
- if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
- str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
-
- }
- return JS_FALSE;
- }
- *ip = (int32)floor(d + 0.5); /* Round to nearest */
- return JS_TRUE;
-}
-
-JSBool
-js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
-{
- jsdouble d;
- jsuint i, m;
- JSBool neg;
-
- if (!js_ValueToNumber(cx, v, &d))
- return JS_FALSE;
- if (d == 0 || !JSDOUBLE_IS_FINITE(d)) {
- *ip = 0;
- return JS_TRUE;
- }
- i = (jsuint)d;
- if ((jsdouble)i == d) {
- *ip = (uint16)i;
- return JS_TRUE;
- }
- neg = (d < 0);
- d = floor(neg ? -d : d);
- d = neg ? -d : d;
- m = JS_BIT(16);
- d = fmod(d, (double)m);
- if (d < 0)
- d += m;
- *ip = (uint16) d;
- return JS_TRUE;
-}
-
-jsdouble
-js_DoubleToInteger(jsdouble d)
-{
- JSBool neg;
-
- if (d == 0)
- return d;
- if (!JSDOUBLE_IS_FINITE(d)) {
- if (JSDOUBLE_IS_NaN(d))
- return 0;
- return d;
- }
- neg = (d < 0);
- d = floor(neg ? -d : d);
- return neg ? -d : d;
-}
-
-
-JSBool
-js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp)
-{
- char cbuf[32];
- size_t i;
- char *cstr, *istr, *estr;
- JSBool negative;
- jsdouble d;
- const jschar *s1 = js_SkipWhiteSpace(s);
- size_t length = js_strlen(s1);
-
- /* Use cbuf to avoid malloc */
- if (length >= sizeof cbuf) {
- cstr = (char *) JS_malloc(cx, length + 1);
- if (!cstr)
- return JS_FALSE;
- } else {
- cstr = cbuf;
- }
-
- for (i = 0; i <= length; i++) {
- if (s1[i] >> 8) {
- cstr[i] = 0;
- break;
- }
- cstr[i] = (char)s1[i];
- }
-
- istr = cstr;
- if ((negative = (*istr == '-')) != 0 || *istr == '+')
- istr++;
- if (!strncmp(istr, js_Infinity_str, sizeof js_Infinity_str - 1)) {
- d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity);
- estr = istr + 8;
- } else {
- int err;
- d = JS_strtod(cstr, &estr, &err);
- if (err == JS_DTOA_ENOMEM) {
- JS_ReportOutOfMemory(cx);
- if (cstr != cbuf)
- JS_free(cx, cstr);
- return JS_FALSE;
- }
- if (err == JS_DTOA_ERANGE) {
- if (d == HUGE_VAL)
- d = *cx->runtime->jsPositiveInfinity;
- else if (d == -HUGE_VAL)
- d = *cx->runtime->jsNegativeInfinity;
- }
-#ifdef HPUX
- if (d == 0.0 && negative) {
- /*
- * "-0", "-1e-2000" come out as positive zero
- * here on HPUX. Force a negative zero instead.
- */
- JSDOUBLE_HI32(d) = JSDOUBLE_HI32_SIGNBIT;
- JSDOUBLE_LO32(d) = 0;
- }
-#endif
- }
-
- i = estr - cstr;
- if (cstr != cbuf)
- JS_free(cx, cstr);
- *ep = i ? s1 + i : s;
- *dp = d;
- return JS_TRUE;
-}
-
-struct BinaryDigitReader
-{
- uintN base; /* Base of number; must be a power of 2 */
- uintN digit; /* Current digit value in radix given by base */
- uintN digitMask; /* Mask to extract the next bit from digit */
- const jschar *digits; /* Pointer to the remaining digits */
- const jschar *end; /* Pointer to first non-digit */
-};
-
-/* Return the next binary digit from the number or -1 if done */
-static intN GetNextBinaryDigit(struct BinaryDigitReader *bdr)
-{
- intN bit;
-
- if (bdr->digitMask == 0) {
- uintN c;
-
- if (bdr->digits == bdr->end)
- return -1;
-
- c = *bdr->digits++;
- if ('0' <= c && c <= '9')
- bdr->digit = c - '0';
- else if ('a' <= c && c <= 'z')
- bdr->digit = c - 'a' + 10;
- else bdr->digit = c - 'A' + 10;
- bdr->digitMask = bdr->base >> 1;
- }
- bit = (bdr->digit & bdr->digitMask) != 0;
- bdr->digitMask >>= 1;
- return bit;
-}
-
-JSBool
-js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, jsdouble *dp)
-{
- JSBool negative;
- jsdouble value;
- const jschar *start;
- const jschar *s1 = js_SkipWhiteSpace(s);
-
- if ((negative = (*s1 == '-')) != 0 || *s1 == '+')
- s1++;
-
- if (base == 0) {
- /* No base supplied, or some base that evaluated to 0. */
- if (*s1 == '0') {
- /* It's either hex or octal; only increment char if str isn't '0' */
- if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
- s1 += 2;
- base = 16;
- } else { /* Octal */
- base = 8;
- }
- } else {
- base = 10; /* Default to decimal. */
- }
- } else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x')) {
- /* If base is 16, ignore hex prefix. */
- s1 += 2;
- }
-
- /*
- * Done with the preliminaries; find some prefix of the string that's
- * a number in the given base.
- */
- start = s1; /* Mark - if string is empty, we return NaN. */
- value = 0.0;
- for (;;) {
- uintN digit;
- jschar c = *s1;
- if ('0' <= c && c <= '9')
- digit = c - '0';
- else if ('a' <= c && c <= 'z')
- digit = c - 'a' + 10;
- else if ('A' <= c && c <= 'Z')
- digit = c - 'A' + 10;
- else
- break;
- if (digit >= (uintN)base)
- break;
- value = value * base + digit;
- s1++;
- }
-
- if (value >= 9007199254740992.0) {
- if (base == 10) {
- /*
- * If we're accumulating a decimal number and the number is >=
- * 2^53, then the result from the repeated multiply-add above may
- * be inaccurate. Call JS_strtod to get the correct answer.
- */
- size_t i;
- size_t length = s1 - start;
- char *cstr = (char *) JS_malloc(cx, length + 1);
- char *estr;
- int err=0;
-
- if (!cstr)
- return JS_FALSE;
- for (i = 0; i != length; i++)
- cstr[i] = (char)start[i];
- cstr[length] = 0;
-
- value = JS_strtod(cstr, &estr, &err);
- if (err == JS_DTOA_ENOMEM) {
- JS_ReportOutOfMemory(cx);
- JS_free(cx, cstr);
- return JS_FALSE;
- }
- if (err == JS_DTOA_ERANGE && value == HUGE_VAL)
- value = *cx->runtime->jsPositiveInfinity;
- JS_free(cx, cstr);
- } else if ((base & (base - 1)) == 0) {
- /*
- * The number may also be inaccurate for power-of-two bases. This
- * happens if the addition in value * base + digit causes a round-
- * down to an even least significant mantissa bit when the first
- * dropped bit is a one. If any of the following digits in the
- * number (which haven't been added in yet) are nonzero, then the
- * correct action would have been to round up instead of down. An
- * example occurs when reading the number 0x1000000000000081, which
- * rounds to 0x1000000000000000 instead of 0x1000000000000100.
- */
- struct BinaryDigitReader bdr;
- intN bit, bit2;
- intN j;
-
- bdr.base = base;
- bdr.digitMask = 0;
- bdr.digits = start;
- bdr.end = s1;
- value = 0.0;
-
- /* Skip leading zeros. */
- do {
- bit = GetNextBinaryDigit(&bdr);
- } while (bit == 0);
-
- if (bit == 1) {
- /* Gather the 53 significant bits (including the leading 1) */
- value = 1.0;
- for (j = 52; j; j--) {
- bit = GetNextBinaryDigit(&bdr);
- if (bit < 0)
- goto done;
- value = value*2 + bit;
- }
- /* bit2 is the 54th bit (the first dropped from the mantissa) */
- bit2 = GetNextBinaryDigit(&bdr);
- if (bit2 >= 0) {
- jsdouble factor = 2.0;
- intN sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */
- intN bit3;
-
- while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) {
- sticky |= bit3;
- factor *= 2;
- }
- value += bit2 & (bit | sticky);
- value *= factor;
- }
- done:;
- }
- }
- }
- /* We don't worry about inaccurate numbers for any other base. */
-
- if (s1 == start) {
- *dp = 0.0;
- *ep = s;
- } else {
- *dp = negative ? -value : value;
- *ep = s1;
- }
- return JS_TRUE;
-}
diff --git a/src/extension/script/js/jsnum.h b/src/extension/script/js/jsnum.h
deleted file mode 100644
index 46992e2b6..000000000
--- a/src/extension/script/js/jsnum.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsnum_h___
-#define jsnum_h___
-/*
- * JS number (IEEE double) interface.
- *
- * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
- * but floating point literals, results that overflow 31 bits, and division and
- * modulus operands and results require a 64-bit IEEE double. These are GC'ed
- * and pointed to by 32-bit jsvals on the stack and in object properties.
- *
- * When a JS number is treated as an object (followed by . or []), the runtime
- * wraps it with a JSObject whose valueOf method returns the unwrapped number.
- */
-
-JS_BEGIN_EXTERN_C
-
-/*
- * Stefan Hanske <sh990154@mail.uni-greifswald.de> reports:
- * ARM is a little endian architecture but 64 bit double words are stored
- * differently: the 32 bit words are in little endian byte order, the two words
- * are stored in big endian`s way.
- */
-
-#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
-#define CPU_IS_ARM
-#endif
-
-typedef union jsdpun {
- struct {
-#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
- uint32 lo, hi;
-#else
- uint32 hi, lo;
-#endif
- } s;
- jsdouble d;
-} jsdpun;
-
-#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2
-/*
- * This version of the macros is safe for the alias optimizations that gcc
- * does, but uses gcc-specific extensions.
- */
-
-#define JSDOUBLE_HI32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.hi; }))
-#define JSDOUBLE_LO32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.lo; }))
-#define JSDOUBLE_SET_HI32(x, y) \
- (__extension__ ({ jsdpun u; u.d = (x); u.s.hi = (y); (x) = u.d; }))
-#define JSDOUBLE_SET_LO32(x, y) \
- (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; }))
-
-#else /* not or old GNUC */
-
-/*
- * We don't know of any non-gcc compilers that perform alias optimization,
- * so this code should work.
- */
-
-#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
-#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
-#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
-#else
-#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
-#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
-#endif
-
-#define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y))
-#define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y))
-
-#endif /* not or old GNUC */
-
-#define JSDOUBLE_HI32_SIGNBIT 0x80000000
-#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
-#define JSDOUBLE_HI32_MANTMASK 0x000fffff
-
-#define JSDOUBLE_IS_NaN(x) \
- ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
- (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
-
-#define JSDOUBLE_IS_INFINITE(x) \
- ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
- !JSDOUBLE_LO32(x))
-
-#define JSDOUBLE_IS_FINITE(x) \
- ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
-
-#define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
- JSDOUBLE_LO32(d) == 0)
-
-/*
- * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
- * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
- * safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point
- * comparisons under MSVC.
- */
-#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) \
- && !JSDOUBLE_IS_NEGZERO(d) \
- && ((d) == (i = (jsint)(d))))
-
-/* Initialize number constants and runtime state for the first context. */
-extern JSBool
-js_InitRuntimeNumberState(JSContext *cx);
-
-extern void
-js_FinishRuntimeNumberState(JSContext *cx);
-
-/* Initialize the Number class, returning its prototype object. */
-extern JSObject *
-js_InitNumberClass(JSContext *cx, JSObject *obj);
-
-/*
- * String constants for global function names, used in jsapi.c and jsnum.c.
- */
-extern const char js_Infinity_str[];
-extern const char js_NaN_str[];
-extern const char js_isNaN_str[];
-extern const char js_isFinite_str[];
-extern const char js_parseFloat_str[];
-extern const char js_parseInt_str[];
-
-/* GC-allocate a new JS number. */
-extern jsdouble *
-js_NewDouble(JSContext *cx, jsdouble d);
-
-extern void
-js_FinalizeDouble(JSContext *cx, jsdouble *dp);
-
-extern JSBool
-js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
-
-extern JSBool
-js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
-
-/* Construct a Number instance that wraps around d. */
-extern JSObject *
-js_NumberToObject(JSContext *cx, jsdouble d);
-
-/* Convert a number to a GC'ed string. */
-extern JSString *
-js_NumberToString(JSContext *cx, jsdouble d);
-
-/*
- * Convert a value to a number, returning false after reporting any error,
- * otherwise returning true with *dp set.
- */
-extern JSBool
-js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
-
-/*
- * Convert a value or a double to an int32, according to the ECMA rules
- * for ToInt32.
- */
-extern JSBool
-js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
-
-extern JSBool
-js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
-
-/*
- * Convert a value or a double to a uint32, according to the ECMA rules
- * for ToUint32.
- */
-extern JSBool
-js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
-
-extern JSBool
-js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
-
-/*
- * Convert a value to a number, then to an int32 if it fits by rounding to
- * nearest; but failing with an error report if the double is out of range
- * or unordered.
- */
-extern JSBool
-js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
-
-/*
- * Convert a value to a number, then to a uint16 according to the ECMA rules
- * for ToUint16.
- */
-extern JSBool
-js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
-
-/*
- * Convert a jsdouble to an integral number, stored in a jsdouble.
- * If d is NaN, return 0. If d is an infinity, return it without conversion.
- */
-extern jsdouble
-js_DoubleToInteger(jsdouble d);
-
-/*
- * Similar to strtod except that it replaces overflows with infinities of the
- * correct sign, and underflows with zeros of the correct sign. Guaranteed to
- * return the closest double number to the given input in dp.
- *
- * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
- * the appropriate sign. The case of the "Infinity" string must match exactly.
- * If the string does not contain a number, set *ep to s and return 0.0 in dp.
- * Return false if out of memory.
- */
-extern JSBool
-js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
-
-/*
- * Similar to strtol except that it handles integers of arbitrary size.
- * Guaranteed to return the closest double number to the given input when radix
- * is 10 or a power of 2. Callers may see round-off errors for very large
- * numbers of a different radix than 10 or a power of 2.
- *
- * If the string does not contain a number, set *ep to s and return 0.0 in dp.
- * Return false if out of memory.
- */
-extern JSBool
-js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
-
-
-#ifdef XP_OS2
-/* XXX see bug 224487
- * On OS/2, some system function calls seem to change the FPU control word,
- * such that we crash with a floating underflow exception. The FIX_FPU() call
- * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the
- * OS/2 system call that horks the FPU control word. So, on OS/2, we need to do
- * what the comment at the top of this file (around line 80) suggests: setting
- * the FPU precision (& exceptions mask) before calling strtod or dtoa. Also,
- * we play nice by reverting to the previous FPU control word at the end of
- * those functions.
- *
- * Set the exception mask to mask all exceptions and set the FPU precision
- * to 53 bit mantissa.
- */
- #define SET_FPU() unsigned cw = _control87(0,0); \
- _control87((CW_DEFAULT & ~MCW_PC) | PC_53, 0xffff)
- #define RESTORE_FPU() _control87(cw, MCW_EM | MCW_IC | MCW_RC | MCW_PC)
-#else
- #define SET_FPU() ((void)0)
- #define RESTORE_FPU() ((void)0)
-#endif
-
-JS_END_EXTERN_C
-
-#endif /* jsnum_h___ */
diff --git a/src/extension/script/js/jsobj.c b/src/extension/script/js/jsobj.c
deleted file mode 100644
index 1da1f138b..000000000
--- a/src/extension/script/js/jsobj.c
+++ /dev/null
@@ -1,3900 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS object implementation.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jshash.h" /* Added by JSIFY */
-#include "jsdhash.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jsbool.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-#include "jsopcode.h"
-
-#include "jsdbgapi.h" /* whether or not JS_HAS_OBJ_WATCHPOINT */
-
-#ifdef JS_THREADSAFE
-#define NATIVE_DROP_PROPERTY js_DropProperty
-
-extern void
-js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop);
-#else
-#define NATIVE_DROP_PROPERTY NULL
-#endif
-
-#ifdef XP_MAC
-#pragma export on
-#endif
-
-JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = {
- js_NewObjectMap, js_DestroyObjectMap,
-#if defined JS_THREADSAFE && defined DEBUG
- _js_LookupProperty, js_DefineProperty,
-#else
- js_LookupProperty, js_DefineProperty,
-#endif
- js_GetProperty, js_SetProperty,
- js_GetAttributes, js_SetAttributes,
- js_DeleteProperty, js_DefaultValue,
- js_Enumerate, js_CheckAccess,
- NULL, NATIVE_DROP_PROPERTY,
- js_Call, js_Construct,
- NULL, js_HasInstance,
- js_SetProtoOrParent, js_SetProtoOrParent,
- js_Mark, js_Clear,
- js_GetRequiredSlot, js_SetRequiredSlot
-};
-
-#ifdef XP_MAC
-#pragma export off
-#endif
-
-JSClass js_ObjectClass = {
- js_Object_str,
- 0,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-#if JS_HAS_OBJ_PROTO_PROP
-
-static JSBool
-obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
-
-static JSBool
-obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
-
-static JSBool
-obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
-
-static JSPropertySpec object_props[] = {
- /* These two must come first; see object_props[slot].name usage below. */
- {js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT|JSPROP_SHARED,
- obj_getSlot, obj_setSlot},
- {js_parent_str,JSSLOT_PARENT,JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED,
- obj_getSlot, obj_setSlot},
- {js_count_str, 0, JSPROP_PERMANENT,obj_getCount, obj_getCount},
- {0,0,0,0,0}
-};
-
-/* NB: JSSLOT_PROTO and JSSLOT_PARENT are already indexes into object_props. */
-#define JSSLOT_COUNT 2
-
-static JSBool
-ReportStrictSlot(JSContext *cx, uint32 slot)
-{
- if (slot == JSSLOT_PROTO)
- return JS_TRUE;
- return JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_DEPRECATED_USAGE,
- object_props[slot].name);
-}
-
-static JSBool
-obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- uint32 slot;
- JSAccessMode mode;
- uintN attrs;
-
- slot = (uint32) JSVAL_TO_INT(id);
- if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot))
- return JS_FALSE;
- if (id == INT_TO_JSVAL(JSSLOT_PROTO)) {
- id = (jsid)cx->runtime->atomState.protoAtom;
- mode = JSACC_PROTO;
- } else {
- id = (jsid)cx->runtime->atomState.parentAtom;
- mode = JSACC_PARENT;
- }
- if (!OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, &attrs))
- return JS_FALSE;
- *vp = OBJ_GET_SLOT(cx, obj, slot);
- return JS_TRUE;
-}
-
-static JSBool
-obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSObject *pobj;
- uint32 slot;
- uintN attrs;
-
- if (!JSVAL_IS_OBJECT(*vp))
- return JS_TRUE;
- pobj = JSVAL_TO_OBJECT(*vp);
- slot = (uint32) JSVAL_TO_INT(id);
- if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot))
- return JS_FALSE;
-
- /* __parent__ is readonly and permanent, only __proto__ may be set. */
- if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_PROTO | JSACC_WRITE, vp, &attrs))
- return JS_FALSE;
-
- return js_SetProtoOrParent(cx, obj, slot, pobj);
-}
-
-static JSBool
-obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsval iter_state;
- jsid num_properties;
- JSBool ok;
-
- if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, JSSLOT_COUNT))
- return JS_FALSE;
-
- /* Get the number of properties to enumerate. */
- iter_state = JSVAL_NULL;
- ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties);
- if (!ok)
- goto out;
-
- if (!JSVAL_IS_INT(num_properties)) {
- JS_ASSERT(0);
- *vp = JSVAL_ZERO;
- goto out;
- }
- *vp = num_properties;
-
-out:
- if (iter_state != JSVAL_NULL)
- ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
- return ok;
-}
-
-#else /* !JS_HAS_OBJ_PROTO_PROP */
-
-#define object_props NULL
-
-#endif /* !JS_HAS_OBJ_PROTO_PROP */
-
-JSBool
-js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj)
-{
- JSRuntime *rt;
- JSObject *obj2, *oldproto;
- JSScope *scope, *newscope;
-
- /*
- * Serialize all proto and parent setting in order to detect cycles.
- * We nest locks in this function, and only here, in the following orders:
- *
- * (1) rt->setSlotLock < pobj's scope lock;
- * rt->setSlotLock < pobj's proto-or-parent's scope lock;
- * rt->setSlotLock < pobj's grand-proto-or-parent's scope lock;
- * etc...
- * (2) rt->setSlotLock < obj's scope lock < pobj's scope lock.
- *
- * We avoid AB-BA deadlock by restricting obj from being on pobj's parent
- * or proto chain (pobj may already be on obj's parent or proto chain; it
- * could be moving up or down). We finally order obj with respect to pobj
- * at the bottom of this routine (just before releasing rt->setSlotLock),
- * by making pobj be obj's prototype or parent.
- *
- * After we have set the slot and released rt->setSlotLock, another call
- * to js_SetProtoOrParent could nest locks according to the first order
- * list above, but it cannot deadlock with any other thread. For there
- * to be a deadlock, other parts of the engine would have to nest scope
- * locks in the opposite order. XXXbe ensure they don't!
- */
- rt = cx->runtime;
-#ifdef JS_THREADSAFE
-
- JS_ACQUIRE_LOCK(rt->setSlotLock);
- while (rt->setSlotBusy) {
- jsrefcount saveDepth;
-
- /* Take pains to avoid nesting rt->gcLock inside rt->setSlotLock! */
- JS_RELEASE_LOCK(rt->setSlotLock);
- saveDepth = JS_SuspendRequest(cx);
- JS_ACQUIRE_LOCK(rt->setSlotLock);
- if (rt->setSlotBusy)
- JS_WAIT_CONDVAR(rt->setSlotDone, JS_NO_TIMEOUT);
- JS_RELEASE_LOCK(rt->setSlotLock);
- JS_ResumeRequest(cx, saveDepth);
- JS_ACQUIRE_LOCK(rt->setSlotLock);
- }
- rt->setSlotBusy = JS_TRUE;
- JS_RELEASE_LOCK(rt->setSlotLock);
-
-#define SET_SLOT_DONE(rt) \
- JS_BEGIN_MACRO \
- JS_ACQUIRE_LOCK((rt)->setSlotLock); \
- (rt)->setSlotBusy = JS_FALSE; \
- JS_NOTIFY_ALL_CONDVAR((rt)->setSlotDone); \
- JS_RELEASE_LOCK((rt)->setSlotLock); \
- JS_END_MACRO
-
-#else
-
-#define SET_SLOT_DONE(rt) /* nothing */
-
-#endif
-
- obj2 = pobj;
- while (obj2) {
- if (obj2 == obj) {
- SET_SLOT_DONE(rt);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CYCLIC_VALUE,
-#if JS_HAS_OBJ_PROTO_PROP
- object_props[slot].name
-#else
- (slot == JSSLOT_PROTO) ? js_proto_str
- : js_parent_str
-#endif
- );
- return JS_FALSE;
- }
- obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot));
- }
-
- if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) {
- /* Check to see whether obj shares its prototype's scope. */
- JS_LOCK_OBJ(cx, obj);
- scope = OBJ_SCOPE(obj);
- oldproto = JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO));
- if (oldproto && OBJ_SCOPE(oldproto) == scope) {
- /* Either obj needs a new empty scope, or it should share pobj's. */
- if (!pobj ||
- !OBJ_IS_NATIVE(pobj) ||
- OBJ_GET_CLASS(cx, pobj) != LOCKED_OBJ_GET_CLASS(oldproto)) {
- /*
- * With no proto and no scope of its own, obj is truly empty.
- *
- * If pobj is not native, obj needs its own empty scope -- it
- * should not continue to share oldproto's scope once oldproto
- * is not on obj's prototype chain. That would put properties
- * from oldproto's scope ahead of properties defined by pobj,
- * in lookup order.
- *
- * If pobj's class differs from oldproto's, we may need a new
- * scope to handle differences in private and reserved slots,
- * so we suboptimally but safely make one.
- */
- scope = js_GetMutableScope(cx, obj);
- if (!scope) {
- JS_UNLOCK_OBJ(cx, obj);
- SET_SLOT_DONE(rt);
- return JS_FALSE;
- }
- } else if (OBJ_SCOPE(pobj) != scope) {
-#ifdef JS_THREADSAFE
- /*
- * We are about to nest scope locks. Help jslock.c:ShareScope
- * keep scope->u.count balanced for the JS_UNLOCK_SCOPE, while
- * avoiding deadlock, by recording scope in rt->setSlotScope.
- */
- if (scope->ownercx) {
- JS_ASSERT(scope->ownercx == cx);
- rt->setSlotScope = scope;
- }
-#endif
-
- /* We can't deadlock because we checked for cycles above (2). */
- JS_LOCK_OBJ(cx, pobj);
- newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map);
- obj->map = &newscope->map;
- js_DropObjectMap(cx, &scope->map, obj);
- JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
- scope = newscope;
-#ifdef JS_THREADSAFE
- rt->setSlotScope = NULL;
-#endif
- }
- }
- LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(pobj));
- JS_UNLOCK_SCOPE(cx, scope);
- } else {
- OBJ_SET_SLOT(cx, obj, slot, OBJECT_TO_JSVAL(pobj));
- }
-
- SET_SLOT_DONE(rt);
- return JS_TRUE;
-
-#undef SET_SLOT_DONE
-}
-
-JS_STATIC_DLL_CALLBACK(JSHashNumber)
-js_hash_object(const void *key)
-{
- return (JSHashNumber)key >> JSVAL_TAGBITS;
-}
-
-static JSHashEntry *
-MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
-{
- JSSharpObjectMap *map;
- JSHashTable *table;
- JSHashNumber hash;
- JSHashEntry **hep, *he;
- jsatomid sharpid;
- JSIdArray *ida;
- JSBool ok;
- jsint i, length;
- jsid id;
-#if JS_HAS_GETTER_SETTER
- JSObject *obj2;
- JSProperty *prop;
- uintN attrs;
-#endif
- jsval val;
-
- map = &cx->sharpObjectMap;
- table = map->table;
- hash = js_hash_object(obj);
- hep = JS_HashTableRawLookup(table, hash, obj);
- he = *hep;
- if (!he) {
- sharpid = 0;
- he = JS_HashTableRawAdd(table, hep, hash, obj, (void *)sharpid);
- if (!he) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- ida = JS_Enumerate(cx, obj);
- if (!ida)
- return NULL;
- ok = JS_TRUE;
- for (i = 0, length = ida->length; i < length; i++) {
- id = ida->vector[i];
-#if JS_HAS_GETTER_SETTER
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ok)
- break;
- if (prop) {
- ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
- if (ok) {
- if (OBJ_IS_NATIVE(obj2) &&
- (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
- val = JSVAL_NULL;
- if (attrs & JSPROP_GETTER)
- val = (jsval) ((JSScopeProperty*)prop)->getter;
- if (attrs & JSPROP_SETTER) {
- if (val != JSVAL_NULL) {
- /* Mark the getter, then set val to setter. */
- ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
- NULL)
- != NULL);
- }
- val = (jsval) ((JSScopeProperty*)prop)->setter;
- }
- } else {
- ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
- }
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- }
-#else
- ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
-#endif
- if (!ok)
- break;
- if (!JSVAL_IS_PRIMITIVE(val) &&
- !MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {
- ok = JS_FALSE;
- break;
- }
- }
- if (!ok || !idap)
- JS_DestroyIdArray(cx, ida);
- if (!ok)
- return NULL;
- } else {
- sharpid = (jsatomid) he->value;
- if (sharpid == 0) {
- sharpid = ++map->sharpgen << SHARP_ID_SHIFT;
- he->value = (void *) sharpid;
- }
- ida = NULL;
- }
- if (idap)
- *idap = ida;
- return he;
-}
-
-JSHashEntry *
-js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
- jschar **sp)
-{
- JSSharpObjectMap *map;
- JSHashTable *table;
- JSIdArray *ida;
- JSHashNumber hash;
- JSHashEntry *he, **hep;
- jsatomid sharpid;
- char buf[20];
- size_t len;
-
- /* Set to null in case we return an early error. */
- *sp = NULL;
- map = &cx->sharpObjectMap;
- table = map->table;
- if (!table) {
- table = JS_NewHashTable(8, js_hash_object, JS_CompareValues,
- JS_CompareValues, NULL, NULL);
- if (!table) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- map->table = table;
- }
-
- ida = NULL;
- if (map->depth == 0) {
- he = MarkSharpObjects(cx, obj, &ida);
- if (!he)
- goto bad;
- JS_ASSERT((((jsatomid) he->value) & SHARP_BIT) == 0);
- if (!idap) {
- JS_DestroyIdArray(cx, ida);
- ida = NULL;
- }
- } else {
- hash = js_hash_object(obj);
- hep = JS_HashTableRawLookup(table, hash, obj);
- he = *hep;
-
- /*
- * It's possible that the value of a property has changed from the
- * first time the object's properties are traversed (when the property
- * ids are entered into the hash table) to the second (when they are
- * converted to strings), i.e., the OBJ_GET_PROPERTY() call is not
- * idempotent.
- */
- if (!he) {
- he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);
- if (!he) {
- JS_ReportOutOfMemory(cx);
- goto bad;
- }
- *sp = NULL;
- sharpid = 0;
- goto out;
- }
- }
-
- sharpid = (jsatomid) he->value;
- if (sharpid == 0) {
- *sp = NULL;
- } else {
- len = JS_snprintf(buf, sizeof buf, "#%u%c",
- sharpid >> SHARP_ID_SHIFT,
- (sharpid & SHARP_BIT) ? '#' : '=');
- *sp = js_InflateString(cx, buf, len);
- if (!*sp) {
- if (ida)
- JS_DestroyIdArray(cx, ida);
- goto bad;
- }
- }
-
-out:
- JS_ASSERT(he);
- if ((sharpid & SHARP_BIT) == 0) {
- if (idap && !ida) {
- ida = JS_Enumerate(cx, obj);
- if (!ida) {
- if (*sp) {
- JS_free(cx, *sp);
- *sp = NULL;
- }
- goto bad;
- }
- }
- map->depth++;
- }
-
- if (idap)
- *idap = ida;
- return he;
-
-bad:
- /* Clean up the sharpObjectMap table on outermost error. */
- if (map->depth == 0) {
- map->sharpgen = 0;
- JS_HashTableDestroy(map->table);
- map->table = NULL;
- }
- return NULL;
-}
-
-void
-js_LeaveSharpObject(JSContext *cx, JSIdArray **idap)
-{
- JSSharpObjectMap *map;
- JSIdArray *ida;
-
- map = &cx->sharpObjectMap;
- JS_ASSERT(map->depth > 0);
- if (--map->depth == 0) {
- map->sharpgen = 0;
- JS_HashTableDestroy(map->table);
- map->table = NULL;
- }
- if (idap) {
- ida = *idap;
- if (ida) {
- JS_DestroyIdArray(cx, ida);
- *idap = NULL;
- }
- }
-}
-
-#define OBJ_TOSTRING_EXTRA 3 /* for 3 local GC roots */
-
-#if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE
-JSBool
-js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSBool ok, outermost;
- JSHashEntry *he;
- JSIdArray *ida;
- jschar *chars, *ochars, *vsharp;
- const jschar *idstrchars, *vchars;
- size_t nchars, idstrlength, gsoplength, vlength, vsharplength;
- char *comma;
- jsint i, j, length, valcnt;
- jsid id;
-#if JS_HAS_GETTER_SETTER
- JSObject *obj2;
- JSProperty *prop;
- uintN attrs;
-#endif
- jsval val[2];
- JSString *gsop[2];
- JSAtom *atom;
- JSString *idstr, *valstr, *str;
- int stackDummy;
-
- if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
- return JS_FALSE;
- }
-
- /*
- * obj_toString for 1.2 calls toSource, and doesn't want the extra parens
- * on the outside.
- */
- outermost = (cx->version != JSVERSION_1_2 && cx->sharpObjectMap.depth == 0);
- he = js_EnterSharpObject(cx, obj, &ida, &chars);
- if (!he)
- return JS_FALSE;
- if (IS_SHARP(he)) {
- /*
- * We didn't enter -- obj is already "sharp", meaning we've visited it
- * already in our depth first search, and therefore chars contains a
- * string of the form "#n#".
- */
- JS_ASSERT(!ida);
-#if JS_HAS_SHARP_VARS
- nchars = js_strlen(chars);
-#else
- chars[0] = '{';
- chars[1] = '}';
- chars[2] = 0;
- nchars = 2;
-#endif
- goto make_string;
- }
- JS_ASSERT(ida);
- ok = JS_TRUE;
-
- if (!chars) {
- /* If outermost, allocate 4 + 1 for "({})" and the terminator. */
- chars = (jschar *) malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));
- nchars = 0;
- if (!chars)
- goto error;
- if (outermost)
- chars[nchars++] = '(';
- } else {
- /* js_EnterSharpObject returned a string of the form "#n=" in chars. */
- MAKE_SHARP(he);
- nchars = js_strlen(chars);
- chars = (jschar *)
- realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
- if (!chars) {
- free(ochars);
- goto error;
- }
- if (outermost) {
- /*
- * No need for parentheses around the whole shebang, because #n=
- * unambiguously begins an object initializer, and never a block
- * statement.
- */
- outermost = JS_FALSE;
- }
- }
-
- chars[nchars++] = '{';
-
- comma = NULL;
-
- for (i = 0, length = ida->length; i < length; i++) {
- /* Get strings for id and value and GC-root them via argv. */
- id = ida->vector[i];
-
-#if JS_HAS_GETTER_SETTER
-
- ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
- if (!ok)
- goto error;
- valcnt = 0;
- if (prop) {
- ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
- if (!ok) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- goto error;
- }
- if (OBJ_IS_NATIVE(obj2) &&
- (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
- if (attrs & JSPROP_GETTER) {
- val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter;
-#ifdef OLD_GETTER_SETTER
- gsop[valcnt] =
- ATOM_TO_STRING(cx->runtime->atomState.getterAtom);
-#else
- gsop[valcnt] =
- ATOM_TO_STRING(cx->runtime->atomState.getAtom);
-#endif
- valcnt++;
- }
- if (attrs & JSPROP_SETTER) {
- val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter;
-#ifdef OLD_GETTER_SETTER
- gsop[valcnt] =
- ATOM_TO_STRING(cx->runtime->atomState.setterAtom);
-#else
- gsop[valcnt] =
- ATOM_TO_STRING(cx->runtime->atomState.setAtom);
-#endif
- valcnt++;
- }
- } else {
- valcnt = 1;
- gsop[0] = NULL;
- ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
- }
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- }
-
-#else /* !JS_HAS_GETTER_SETTER */
-
- valcnt = 1;
- gsop[0] = NULL;
- ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
-
-#endif /* !JS_HAS_GETTER_SETTER */
-
- if (!ok)
- goto error;
-
- /* Convert id to a jsval and then to a string. */
- atom = JSVAL_IS_INT(id) ? NULL : (JSAtom *)id;
- id = ID_TO_VALUE(id);
- idstr = js_ValueToString(cx, id);
- if (!idstr) {
- ok = JS_FALSE;
- goto error;
- }
- argv[0] = STRING_TO_JSVAL(idstr);
-
- /*
- * If id is a string that's a reserved identifier, or else id is not
- * an identifier at all, then it needs to be quoted.
- */
- if (atom && (ATOM_KEYWORD(atom) || !js_IsIdentifier(idstr))) {
- idstr = js_QuoteString(cx, idstr, (jschar)'\'');
- if (!idstr) {
- ok = JS_FALSE;
- goto error;
- }
- argv[0] = STRING_TO_JSVAL(idstr);
- }
- idstrchars = JSSTRING_CHARS(idstr);
- idstrlength = JSSTRING_LENGTH(idstr);
-
- for (j = 0; j < valcnt; j++) {
- /* Convert val[j] to its canonical source form. */
- valstr = js_ValueToSource(cx, val[j]);
- if (!valstr) {
- ok = JS_FALSE;
- goto error;
- }
- argv[1+j] = STRING_TO_JSVAL(valstr);
- vchars = JSSTRING_CHARS(valstr);
- vlength = JSSTRING_LENGTH(valstr);
-
-#ifndef OLD_GETTER_SETTER
- /* Remove 'function ' from beginning of valstr. */
- if (gsop[j]) {
- int n = strlen(js_function_str) + 1;
- vchars += n;
- vlength -= n;
- }
-#endif
-
- /* If val[j] is a non-sharp object, consider sharpening it. */
- vsharp = NULL;
- vsharplength = 0;
-#if JS_HAS_SHARP_VARS
- if (!JSVAL_IS_PRIMITIVE(val[j]) && vchars[0] != '#') {
- he = js_EnterSharpObject(cx, JSVAL_TO_OBJECT(val[j]), NULL,
- &vsharp);
- if (!he) {
- ok = JS_FALSE;
- goto error;
- }
- if (IS_SHARP(he)) {
- vchars = vsharp;
- vlength = js_strlen(vchars);
- } else {
- if (vsharp) {
- vsharplength = js_strlen(vsharp);
- MAKE_SHARP(he);
- }
- js_LeaveSharpObject(cx, NULL);
- }
- }
-#endif
-
- /* Allocate 1 + 1 at end for closing brace and terminating 0. */
- chars = (jschar *)
- realloc((ochars = chars),
- (nchars + (comma ? 2 : 0) +
- idstrlength + 1 +
- (gsop[j] ? 1 + JSSTRING_LENGTH(gsop[j]) : 0) +
- vsharplength + vlength +
- (outermost ? 2 : 1) + 1) * sizeof(jschar));
- if (!chars) {
- /* Save code space on error: let JS_free ignore null vsharp. */
- JS_free(cx, vsharp);
- free(ochars);
- goto error;
- }
-
- if (comma) {
- chars[nchars++] = comma[0];
- chars[nchars++] = comma[1];
- }
- comma = ", ";
-
-#ifdef OLD_GETTER_SETTER
- js_strncpy(&chars[nchars], idstrchars, idstrlength);
- nchars += idstrlength;
- if (gsop[j]) {
- chars[nchars++] = ' ';
- gsoplength = JSSTRING_LENGTH(gsop[j]);
- js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
- nchars += gsoplength;
- }
- chars[nchars++] = ':';
-#else
- if (gsop[j]) {
- gsoplength = JSSTRING_LENGTH(gsop[j]);
- js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
- nchars += gsoplength;
- chars[nchars++] = ' ';
- }
- js_strncpy(&chars[nchars], idstrchars, idstrlength);
- nchars += idstrlength;
- if (!gsop[j])
- chars[nchars++] = ':';
-#endif
- if (vsharplength) {
- js_strncpy(&chars[nchars], vsharp, vsharplength);
- nchars += vsharplength;
- }
- js_strncpy(&chars[nchars], vchars, vlength);
- nchars += vlength;
-
- if (vsharp)
- JS_free(cx, vsharp);
- }
- }
-
- chars[nchars++] = '}';
- if (outermost)
- chars[nchars++] = ')';
- chars[nchars] = 0;
-
- error:
- js_LeaveSharpObject(cx, &ida);
-
- if (!ok) {
- if (chars)
- free(chars);
- return ok;
- }
-
- if (!chars) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- make_string:
- str = js_NewString(cx, chars, nchars, 0);
- if (!str) {
- free(chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif /* JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE */
-
-JSBool
-js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jschar *chars;
- size_t nchars;
- const char *clazz, *prefix;
- JSString *str;
-
-#if JS_HAS_INITIALIZERS
- if (cx->version == JSVERSION_1_2)
- return js_obj_toSource(cx, obj, argc, argv, rval);
-#endif
-
- clazz = OBJ_GET_CLASS(cx, obj)->name;
- nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
- chars = (jschar *) JS_malloc(cx, (nchars + 1) * sizeof(jschar));
- if (!chars)
- return JS_FALSE;
-
- prefix = "[object ";
- nchars = 0;
- while ((chars[nchars] = (jschar)*prefix) != 0)
- nchars++, prefix++;
- while ((chars[nchars] = (jschar)*clazz) != 0)
- nchars++, clazz++;
- chars[nchars++] = ']';
- chars[nchars] = 0;
-
- str = js_NewString(cx, chars, nchars, 0);
- if (!str) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-obj_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
-}
-
-static JSBool
-obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSStackFrame *fp, *caller;
- JSBool indirectCall;
- JSObject *scopeobj;
- JSString *str;
- const char *file;
- uintN line;
- JSPrincipals *principals;
- JSScript *script;
- JSBool ok;
-#if JS_HAS_EVAL_THIS_SCOPE
- JSObject *callerScopeChain = NULL, *callerVarObj = NULL;
- JSBool setCallerScopeChain = JS_FALSE, setCallerVarObj = JS_FALSE;
-#endif
-
- fp = cx->fp;
- caller = JS_GetScriptedCaller(cx, fp);
- indirectCall = (caller && caller->pc && *caller->pc != JSOP_EVAL);
-
- if (JSVERSION_IS_ECMA(cx->version) &&
- indirectCall &&
- !JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_BAD_INDIRECT_CALL,
- js_eval_str)) {
- return JS_FALSE;
- }
-
- if (!JSVAL_IS_STRING(argv[0])) {
- *rval = argv[0];
- return JS_TRUE;
- }
-
-#if JS_HAS_SCRIPT_OBJECT
- /*
- * Script.prototype.compile/exec and Object.prototype.eval all take an
- * optional trailing argument that overrides the scope object.
- */
- scopeobj = NULL;
- if (argc >= 2) {
- if (!js_ValueToObject(cx, argv[1], &scopeobj))
- return JS_FALSE;
- argv[1] = OBJECT_TO_JSVAL(scopeobj);
- }
- if (!scopeobj)
-#endif
- {
-#if JS_HAS_EVAL_THIS_SCOPE
- /* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */
- if (indirectCall) {
- callerScopeChain = caller->scopeChain;
- if (obj != callerScopeChain) {
- scopeobj = js_NewObject(cx, &js_WithClass, obj,
- callerScopeChain);
- if (!scopeobj)
- return JS_FALSE;
-
- /* Set fp->scopeChain too, for the compiler. */
- caller->scopeChain = fp->scopeChain = scopeobj;
- setCallerScopeChain = JS_TRUE;
- }
-
- callerVarObj = caller->varobj;
- if (obj != callerVarObj) {
- /* Set fp->varobj too, for the compiler. */
- caller->varobj = fp->varobj = obj;
- setCallerVarObj = JS_TRUE;
- }
- }
- /* From here on, control must exit through label out with ok set. */
-#endif
-
-#if JS_BUG_EVAL_THIS_SCOPE
- /* An old version used the object in which eval was found for scope. */
- scopeobj = obj;
-#else
- /* Compile using caller's current scope object. */
- if (caller)
- scopeobj = caller->scopeChain;
-#endif
- }
-
- str = JSVAL_TO_STRING(argv[0]);
- if (caller) {
- file = caller->script->filename;
- line = js_PCToLineNumber(cx, caller->script, caller->pc);
- principals = JS_EvalFramePrincipals(cx, fp, caller);
- } else {
- file = NULL;
- line = 0;
- principals = NULL;
- }
-
- /* XXXbe set only for the compiler, which does not currently test it */
- fp->flags |= JSFRAME_EVAL;
- script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
- JSSTRING_CHARS(str),
- JSSTRING_LENGTH(str),
- file, line);
- if (!script) {
- ok = JS_FALSE;
- goto out;
- }
-
-#if !JS_BUG_EVAL_THIS_SCOPE
-#if JS_HAS_SCRIPT_OBJECT
- if (argc < 2)
-#endif
- {
- /* Execute using caller's new scope object (might be a Call object). */
- if (caller)
- scopeobj = caller->scopeChain;
- }
-#endif
- ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
- JS_DestroyScript(cx, script);
-
-out:
-#if JS_HAS_EVAL_THIS_SCOPE
- /* Restore OBJ_GET_PARENT(scopeobj) not callerScopeChain in case of Call. */
- if (setCallerScopeChain)
- caller->scopeChain = callerScopeChain;
- if (setCallerVarObj)
- caller->varobj = callerVarObj;
-#endif
- return ok;
-}
-
-JS_STATIC_DLL_CALLBACK(const void *)
-resolving_GetKey(JSDHashTable *table, JSDHashEntryHdr *hdr)
-{
- JSResolvingEntry *entry = (JSResolvingEntry *)hdr;
-
- return &entry->key;
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashNumber)
-resolving_HashKey(JSDHashTable *table, const void *ptr)
-{
- const JSResolvingKey *key = (const JSResolvingKey *)ptr;
-
- return ((JSDHashNumber)key->obj >> JSVAL_TAGBITS) ^ key->id;
-}
-
-JS_PUBLIC_API(JSBool)
-resolving_MatchEntry(JSDHashTable *table,
- const JSDHashEntryHdr *hdr,
- const void *ptr)
-{
- const JSResolvingEntry *entry = (const JSResolvingEntry *)hdr;
- const JSResolvingKey *key = (const JSResolvingKey *)ptr;
-
- return entry->key.obj == key->obj && entry->key.id == key->id;
-}
-
-static const JSDHashTableOps resolving_dhash_ops = {
- JS_DHashAllocTable,
- JS_DHashFreeTable,
- resolving_GetKey,
- resolving_HashKey,
- resolving_MatchEntry,
- JS_DHashMoveEntryStub,
- JS_DHashClearEntryStub,
- JS_DHashFinalizeStub,
- NULL
-};
-
-static JSBool
-StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
- JSResolvingEntry **entryp)
-{
- JSDHashTable *table;
- JSResolvingEntry *entry;
-
- table = cx->resolvingTable;
- if (!table) {
- table = JS_NewDHashTable(&resolving_dhash_ops, NULL,
- sizeof(JSResolvingEntry),
- JS_DHASH_MIN_SIZE);
- if (!table)
- goto outofmem;
- cx->resolvingTable = table;
- }
-
- entry = (JSResolvingEntry *)
- JS_DHashTableOperate(table, key, JS_DHASH_ADD);
- if (!entry)
- goto outofmem;
-
- if (entry->flags & flag) {
- /* An entry for (key, flag) exists already -- dampen recursion. */
- entry = NULL;
- } else {
- /* Fill in key if we were the first to add entry, then set flag. */
- if (!entry->key.obj)
- entry->key = *key;
- entry->flags |= flag;
- }
- *entryp = entry;
- return JS_TRUE;
-
-outofmem:
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
-}
-
-static void
-StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
- JSResolvingEntry *entry, uint32 generation)
-{
- JSDHashTable *table;
-
- /*
- * Clear flag from entry->flags and return early if other flags remain.
- * We must take care to re-lookup entry if the table has changed since
- * it was found by StartResolving.
- */
- table = cx->resolvingTable;
- if (table->generation != generation) {
- entry = (JSResolvingEntry *)
- JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP);
- }
- entry->flags &= ~flag;
- if (entry->flags)
- return;
-
- /*
- * Do a raw remove only if fewer entries were removed than would cause
- * alpha to be less than .5 (alpha is at most .75). Otherwise, we just
- * call JS_DHashTableOperate to re-lookup the key and remove its entry,
- * compressing or shrinking the table as needed.
- */
- if (table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2)
- JS_DHashTableRawRemove(table, &entry->hdr);
- else
- JS_DHashTableOperate(table, key, JS_DHASH_REMOVE);
-}
-
-#if JS_HAS_OBJ_WATCHPOINT
-
-static JSBool
-obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp,
- void *closure)
-{
- JSResolvingKey key;
- JSResolvingEntry *entry;
- uint32 generation;
- JSObject *funobj;
- jsval argv[3];
- JSBool ok;
-
- /* Avoid recursion on (obj, id) already being watched on cx. */
- key.obj = obj;
- key.id = id;
- if (!StartResolving(cx, &key, JSRESFLAG_WATCH, &entry))
- return JS_FALSE;
- if (!entry)
- return JS_TRUE;
- generation = cx->resolvingTable->generation;
-
- funobj = (JSObject *) closure;
- argv[0] = id;
- argv[1] = old;
- argv[2] = *nvp;
- ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(funobj), 3, argv, nvp);
- StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation);
- return ok;
-}
-
-static JSBool
-obj_watch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSFunction *fun;
- jsval userid, value;
- jsid propid;
- uintN attrs;
-
- fun = js_ValueToFunction(cx, &argv[1], 0);
- if (!fun)
- return JS_FALSE;
- argv[1] = OBJECT_TO_JSVAL(fun->object);
-
- /* Compute the unique int/atom symbol id needed by js_LookupProperty. */
- userid = argv[0];
- if (!JS_ValueToId(cx, userid, &propid))
- return JS_FALSE;
-
- if (!OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_WATCH, &value, &attrs))
- return JS_FALSE;
- if (attrs & JSPROP_READONLY)
- return JS_TRUE;
- return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, fun->object);
-}
-
-static JSBool
-obj_unwatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return JS_ClearWatchPoint(cx, obj, argv[0], NULL, NULL);
-}
-
-#endif /* JS_HAS_OBJ_WATCHPOINT */
-
-#if JS_HAS_NEW_OBJ_METHODS
-/*
- * Prototype and property query methods, to complement the 'in' and
- * 'instanceof' operators.
- */
-
-/* Proposed ECMA 15.2.4.5. */
-static JSBool
-obj_hasOwnProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsid id;
- JSObject *obj2;
- JSProperty *prop;
- JSScopeProperty *sprop;
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
- if (!prop) {
- *rval = JSVAL_FALSE;
- } else if (obj2 == obj) {
- *rval = JSVAL_TRUE;
- } else if (OBJ_IS_NATIVE(obj2)) {
- sprop = (JSScopeProperty *)prop;
- *rval = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop));
- } else {
- *rval = JSVAL_FALSE;
- }
- if (prop)
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- return JS_TRUE;
-}
-
-/* Proposed ECMA 15.2.4.6. */
-static JSBool
-obj_isPrototypeOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSBool b;
-
- if (!js_IsDelegate(cx, obj, *argv, &b))
- return JS_FALSE;
- *rval = BOOLEAN_TO_JSVAL(b);
- return JS_TRUE;
-}
-
-/* Proposed ECMA 15.2.4.7. */
-static JSBool
-obj_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsid id;
- uintN attrs;
- JSObject *obj2;
- JSProperty *prop;
- JSBool ok;
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
- return JS_FALSE;
-
- if (!prop) {
- *rval = JSVAL_FALSE;
- return JS_TRUE;
- }
-
- /*
- * XXX ECMA spec error compatible: return false unless hasOwnProperty.
- * The ECMA spec really should be fixed so propertyIsEnumerable and the
- * for..in loop agree on whether prototype properties are enumerable,
- * obviously by fixing this method (not by breaking the for..in loop!).
- *
- * We check here for shared permanent prototype properties, which should
- * be treated as if they are local to obj. They are an implementation
- * technique used to satisfy ECMA requirements; users should not be able
- * to distinguish a shared permanent proto-property from a local one.
- */
- if (obj2 != obj &&
- !(OBJ_IS_NATIVE(obj2) &&
- SPROP_IS_SHARED_PERMANENT((JSScopeProperty *)prop))) {
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- *rval = JSVAL_FALSE;
- return JS_TRUE;
- }
-
- ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
- OBJ_DROP_PROPERTY(cx, obj2, prop);
- if (ok)
- *rval = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0);
- return ok;
-}
-#endif /* JS_HAS_NEW_OBJ_METHODS */
-
-#if JS_HAS_GETTER_SETTER
-static JSBool
-obj_defineGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsval fval, junk;
- jsid id;
- JSBool found;
- uintN attrs;
-
- fval = argv[1];
- if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_GETTER_OR_SETTER,
- js_getter_str);
- return JS_FALSE;
- }
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
- if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, &found))
- return JS_FALSE;
- /*
- * Getters and setters are just like watchpoints from an access
- * control point of view.
- */
- if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs))
- return JS_FALSE;
- return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
- (JSPropertyOp) JSVAL_TO_OBJECT(fval), NULL,
- JSPROP_GETTER | JSPROP_SHARED, NULL);
-}
-
-static JSBool
-obj_defineSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsval fval, junk;
- jsid id;
- JSBool found;
- uintN attrs;
-
- fval = argv[1];
- if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_GETTER_OR_SETTER,
- js_setter_str);
- return JS_FALSE;
- }
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
- if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, &found))
- return JS_FALSE;
- /*
- * Getters and setters are just like watchpoints from an access
- * control point of view.
- */
- if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs))
- return JS_FALSE;
- return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
- NULL, (JSPropertyOp) JSVAL_TO_OBJECT(fval),
- JSPROP_SETTER | JSPROP_SHARED, NULL);
-}
-
-static JSBool
-obj_lookupGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsid id;
- JSObject *pobj;
- JSScopeProperty *sprop;
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop))
- return JS_FALSE;
- if (sprop) {
- if (sprop->attrs & JSPROP_GETTER)
- *rval = OBJECT_TO_JSVAL(sprop->getter);
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- }
- return JS_TRUE;
-}
-
-static JSBool
-obj_lookupSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jsid id;
- JSObject *pobj;
- JSScopeProperty *sprop;
-
- if (!JS_ValueToId(cx, argv[0], &id))
- return JS_FALSE;
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop))
- return JS_FALSE;
- if (sprop) {
- if (sprop->attrs & JSPROP_SETTER)
- *rval = OBJECT_TO_JSVAL(sprop->setter);
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- }
- return JS_TRUE;
-}
-#endif /* JS_HAS_GETTER_SETTER */
-
-#if JS_HAS_OBJ_WATCHPOINT
-const char js_watch_str[] = "watch";
-const char js_unwatch_str[] = "unwatch";
-#endif
-#if JS_HAS_NEW_OBJ_METHODS
-const char js_hasOwnProperty_str[] = "hasOwnProperty";
-const char js_isPrototypeOf_str[] = "isPrototypeOf";
-const char js_propertyIsEnumerable_str[] = "propertyIsEnumerable";
-#endif
-#if JS_HAS_GETTER_SETTER
-const char js_defineGetter_str[] = "__defineGetter__";
-const char js_defineSetter_str[] = "__defineSetter__";
-const char js_lookupGetter_str[] = "__lookupGetter__";
-const char js_lookupSetter_str[] = "__lookupSetter__";
-#endif
-
-static JSFunctionSpec object_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, js_obj_toSource, 0, 0, OBJ_TOSTRING_EXTRA},
-#endif
- {js_toString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA},
- {js_toLocaleString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA},
- {js_valueOf_str, obj_valueOf, 0,0,0},
- {js_eval_str, obj_eval, 1,0,0},
-#if JS_HAS_OBJ_WATCHPOINT
- {js_watch_str, obj_watch, 2,0,0},
- {js_unwatch_str, obj_unwatch, 1,0,0},
-#endif
-#if JS_HAS_NEW_OBJ_METHODS
- {js_hasOwnProperty_str, obj_hasOwnProperty, 1,0,0},
- {js_isPrototypeOf_str, obj_isPrototypeOf, 1,0,0},
- {js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0,0},
-#endif
-#if JS_HAS_GETTER_SETTER
- {js_defineGetter_str, obj_defineGetter, 2,0,0},
- {js_defineSetter_str, obj_defineSetter, 2,0,0},
- {js_lookupGetter_str, obj_lookupGetter, 1,0,0},
- {js_lookupSetter_str, obj_lookupSetter, 1,0,0},
-#endif
- {0,0,0,0,0}
-};
-
-static JSBool
-Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (argc == 0) {
- /* Trigger logic below to construct a blank object. */
- obj = NULL;
- } else {
- /* If argv[0] is null or undefined, obj comes back null. */
- if (!js_ValueToObject(cx, argv[0], &obj))
- return JS_FALSE;
- }
- if (!obj) {
- JS_ASSERT(!argc || JSVAL_IS_NULL(argv[0]) || JSVAL_IS_VOID(argv[0]));
- if (cx->fp->flags & JSFRAME_CONSTRUCTING)
- return JS_TRUE;
- obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- }
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
-}
-
-/*
- * ObjectOps and Class for with-statement stack objects.
- */
-static JSBool
-with_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
- JSProperty **propp
-#if defined JS_THREADSAFE && defined DEBUG
- , const char *file, uintN line
-#endif
- )
-{
- JSObject *proto;
- JSScopeProperty *sprop;
- JSStackFrame *fp;
-
- proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_LookupProperty(cx, obj, id, objp, propp);
- if (!OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp))
- return JS_FALSE;
-
- /*
- * Check whether id names an argument or local variable in an active
- * function. If so, pretend we didn't find it, so that the real arg or
- * var property can be found in the function's call object, later on in
- * the scope chain. But skip unshared arg and var properties -- those
- * result when a script explicitly sets a function "static" property of
- * the same name. See jsinterp.c:SetFunctionSlot.
- *
- * XXX blame pre-ECMA reflection of function args and vars as properties
- */
- if ((sprop = (JSScopeProperty *) *propp) &&
- (proto = *objp, OBJ_IS_NATIVE(proto)) &&
- (sprop->getter == js_GetArgument ||
- sprop->getter == js_GetLocalVariable) &&
- (sprop->attrs & JSPROP_SHARED)) {
- JS_ASSERT(OBJ_GET_CLASS(cx, proto) == &js_FunctionClass);
- for (fp = cx->fp; fp && (!fp->fun || fp->fun->native); fp = fp->down)
- continue;
- if (fp && fp->fun == (JSFunction *) JS_GetPrivate(cx, proto)) {
- OBJ_DROP_PROPERTY(cx, proto, *propp);
- *objp = NULL;
- *propp = NULL;
- }
- }
- return JS_TRUE;
-}
-
-static JSBool
-with_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_GetProperty(cx, obj, id, vp);
- return OBJ_GET_PROPERTY(cx, proto, id, vp);
-}
-
-static JSBool
-with_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_SetProperty(cx, obj, id, vp);
- return OBJ_SET_PROPERTY(cx, proto, id, vp);
-}
-
-static JSBool
-with_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_GetAttributes(cx, obj, id, prop, attrsp);
- return OBJ_GET_ATTRIBUTES(cx, proto, id, prop, attrsp);
-}
-
-static JSBool
-with_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_SetAttributes(cx, obj, id, prop, attrsp);
- return OBJ_SET_ATTRIBUTES(cx, proto, id, prop, attrsp);
-}
-
-static JSBool
-with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_DeleteProperty(cx, obj, id, rval);
- return OBJ_DELETE_PROPERTY(cx, proto, id, rval);
-}
-
-static JSBool
-with_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_DefaultValue(cx, obj, hint, vp);
- return OBJ_DEFAULT_VALUE(cx, proto, hint, vp);
-}
-
-static JSBool
-with_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
- jsval *statep, jsid *idp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_Enumerate(cx, obj, enum_op, statep, idp);
- return OBJ_ENUMERATE(cx, proto, enum_op, statep, idp);
-}
-
-static JSBool
-with_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
- jsval *vp, uintN *attrsp)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return js_CheckAccess(cx, obj, id, mode, vp, attrsp);
- return OBJ_CHECK_ACCESS(cx, proto, id, mode, vp, attrsp);
-}
-
-static JSObject *
-with_ThisObject(JSContext *cx, JSObject *obj)
-{
- JSObject *proto = OBJ_GET_PROTO(cx, obj);
- if (!proto)
- return obj;
- return OBJ_THIS_OBJECT(cx, proto);
-}
-
-JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = {
- js_NewObjectMap, js_DestroyObjectMap,
- with_LookupProperty, js_DefineProperty,
- with_GetProperty, with_SetProperty,
- with_GetAttributes, with_SetAttributes,
- with_DeleteProperty, with_DefaultValue,
- with_Enumerate, with_CheckAccess,
- with_ThisObject, NATIVE_DROP_PROPERTY,
- NULL, NULL,
- NULL, NULL,
- js_SetProtoOrParent, js_SetProtoOrParent,
- js_Mark, js_Clear,
- NULL, NULL
-};
-
-static JSObjectOps *
-with_getObjectOps(JSContext *cx, JSClass *clasp)
-{
- return &js_WithObjectOps;
-}
-
-JSClass js_WithClass = {
- "With",
- 0,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- with_getObjectOps,
- 0,0,0,0,0,0,0
-};
-
-#if JS_HAS_OBJ_PROTO_PROP
-static JSBool
-With(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSObject *parent, *proto;
- jsval v;
-
- if (!JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_DEPRECATED_USAGE,
- js_WithClass.name)) {
- return JS_FALSE;
- }
-
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- obj = js_NewObject(cx, &js_WithClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(obj);
- }
-
- parent = cx->fp->scopeChain;
- if (argc > 0) {
- if (!js_ValueToObject(cx, argv[0], &proto))
- return JS_FALSE;
- v = OBJECT_TO_JSVAL(proto);
- if (!obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PROTO), &v))
- return JS_FALSE;
- if (argc > 1) {
- if (!js_ValueToObject(cx, argv[1], &parent))
- return JS_FALSE;
- }
- }
- v = OBJECT_TO_JSVAL(parent);
- return obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PARENT), &v);
-}
-#endif
-
-JSObject *
-js_InitObjectClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
- jsval eval;
-
-#if JS_HAS_SHARP_VARS
- JS_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >= ATOM_INDEX_LIMIT_LOG2 + 1);
-#endif
-
- proto = JS_InitClass(cx, obj, NULL, &js_ObjectClass, Object, 1,
- object_props, object_methods, NULL, NULL);
- if (!proto)
- return NULL;
-
-#if JS_HAS_OBJ_PROTO_PROP
- if (!JS_InitClass(cx, obj, NULL, &js_WithClass, With, 0,
- NULL, NULL, NULL, NULL)) {
- return NULL;
- }
-#endif
-
- /* ECMA (15.1.2.1) says 'eval' is also a property of the global object. */
- if (!OBJ_GET_PROPERTY(cx, proto, (jsid)cx->runtime->atomState.evalAtom,
- &eval)) {
- return NULL;
- }
- if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.evalAtom,
- eval, NULL, NULL, 0, NULL)) {
- return NULL;
- }
-
- return proto;
-}
-
-void
-js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
- JSClass *clasp)
-{
- map->nrefs = nrefs;
- map->ops = ops;
- map->nslots = JS_INITIAL_NSLOTS;
- map->freeslot = JSSLOT_FREE(clasp);
-}
-
-JSObjectMap *
-js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
- JSClass *clasp, JSObject *obj)
-{
- return (JSObjectMap *) js_NewScope(cx, nrefs, ops, clasp, obj);
-}
-
-void
-js_DestroyObjectMap(JSContext *cx, JSObjectMap *map)
-{
- js_DestroyScope(cx, (JSScope *)map);
-}
-
-JSObjectMap *
-js_HoldObjectMap(JSContext *cx, JSObjectMap *map)
-{
- JS_ASSERT(map->nrefs >= 0);
- JS_ATOMIC_INCREMENT(&map->nrefs);
- return map;
-}
-
-JSObjectMap *
-js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj)
-{
- JS_ASSERT(map->nrefs > 0);
- JS_ATOMIC_DECREMENT(&map->nrefs);
- if (map->nrefs == 0) {
- map->ops->destroyObjectMap(cx, map);
- return NULL;
- }
- if (MAP_IS_NATIVE(map) && ((JSScope *)map)->object == obj)
- ((JSScope *)map)->object = NULL;
- return map;
-}
-
-static JSBool
-GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
- JSObject **protop);
-
-JSObject *
-js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
-{
- JSObject *obj, *ctor;
- JSObjectOps *ops;
- JSObjectMap *map;
- jsval cval;
- uint32 nslots, i;
- jsval *newslots;
-
- /* Allocate an object from the GC heap and zero it. */
- obj = (JSObject *) js_AllocGCThing(cx, GCX_OBJECT);
- if (!obj)
- return NULL;
-
- /* Bootstrap the ur-object, and make it the default prototype object. */
- if (!proto) {
- if (!GetClassPrototype(cx, parent, clasp->name, &proto))
- goto bad;
- if (!proto && !GetClassPrototype(cx, parent, js_Object_str, &proto))
- goto bad;
- }
-
- /* Always call the class's getObjectOps hook if it has one. */
- ops = clasp->getObjectOps
- ? clasp->getObjectOps(cx, clasp)
- : &js_ObjectOps;
-
- /*
- * Share proto's map only if it has the same JSObjectOps, and only if
- * proto's class has the same private and reserved slots, as obj's map
- * and class have.
- */
- if (proto &&
- (map = proto->map)->ops == ops &&
- ((clasp->flags ^ OBJ_GET_CLASS(cx, proto)->flags) &
- (JSCLASS_HAS_PRIVATE |
- (JSCLASS_RESERVED_SLOTS_MASK << JSCLASS_RESERVED_SLOTS_SHIFT)))
- == 0) {
- /* Default parent to the parent of the prototype's constructor. */
- if (!parent) {
- if (!OBJ_GET_PROPERTY(cx, proto,
- (jsid)cx->runtime->atomState.constructorAtom,
- &cval)) {
- goto bad;
- }
- if (JSVAL_IS_OBJECT(cval) && (ctor = JSVAL_TO_OBJECT(cval)) != NULL)
- parent = OBJ_GET_PARENT(cx, ctor);
- }
-
- /* Share the given prototype's map. */
- obj->map = js_HoldObjectMap(cx, map);
-
- /* Ensure that obj starts with the minimum slots for clasp. */
- nslots = JS_INITIAL_NSLOTS;
- } else {
- /* Leave parent alone. Allocate a new map for obj. */
- map = ops->newObjectMap(cx, 1, ops, clasp, obj);
- if (!map)
- goto bad;
- obj->map = map;
-
- /* Let ops->newObjectMap set nslots so as to reserve slots. */
- nslots = map->nslots;
- }
-
- /* Allocate a slots vector, with a -1'st element telling its length. */
- newslots = (jsval *) JS_malloc(cx, (nslots + 1) * sizeof(jsval));
- if (!newslots) {
- js_DropObjectMap(cx, obj->map, obj);
- obj->map = NULL;
- goto bad;
- }
- newslots[0] = nslots;
- newslots++;
-
- /* Set the proto, parent, and class properties. */
- newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
- newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);
- newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);
-
- /* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */
- for (i = JSSLOT_CLASS + 1; i < nslots; i++)
- newslots[i] = JSVAL_VOID;
-
- /* Store newslots after initializing all of 'em, just in case. */
- obj->slots = newslots;
-
- if (cx->runtime->objectHook)
- cx->runtime->objectHook(cx, obj, JS_TRUE, cx->runtime->objectHookData);
-
- return obj;
-
-bad:
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
-}
-
-static JSBool
-FindConstructor(JSContext *cx, JSObject *scope, const char *name, jsval *vp)
-{
- JSAtom *atom;
- JSObject *obj;
- JSObject *pobj;
- JSScopeProperty *sprop;
-
- atom = js_Atomize(cx, name, strlen(name), 0);
- if (!atom)
- return JS_FALSE;
-
- if (scope || (cx->fp && (scope = cx->fp->scopeChain) != NULL)) {
- /* Find the topmost object in the scope chain. */
- do {
- obj = scope;
- scope = OBJ_GET_PARENT(cx, obj);
- } while (scope);
- } else {
- obj = cx->globalObject;
- if (!obj) {
- *vp = JSVAL_VOID;
- return JS_TRUE;
- }
- }
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, (JSProperty**)&sprop))
- return JS_FALSE;
- if (!sprop) {
- *vp = JSVAL_VOID;
- return JS_TRUE;
- }
-
- JS_ASSERT(OBJ_IS_NATIVE(pobj));
- JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
- *vp = OBJ_GET_SLOT(cx, pobj, sprop->slot);
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- return JS_TRUE;
-}
-
-JSObject *
-js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent, uintN argc, jsval *argv)
-{
- jsval cval, rval;
- JSObject *obj, *ctor;
-
- if (!FindConstructor(cx, parent, clasp->name, &cval))
- return NULL;
- if (JSVAL_IS_PRIMITIVE(cval)) {
- js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK);
- return NULL;
- }
-
- /*
- * If proto or parent are NULL, set them to Constructor.prototype and/or
- * Constructor.__parent__, just like JSOP_NEW does.
- */
- ctor = JSVAL_TO_OBJECT(cval);
- if (!parent)
- parent = OBJ_GET_PARENT(cx, ctor);
- if (!proto) {
- if (!OBJ_GET_PROPERTY(cx, ctor,
- (jsid)cx->runtime->atomState.classPrototypeAtom,
- &rval)) {
- return NULL;
- }
- if (JSVAL_IS_OBJECT(rval))
- proto = JSVAL_TO_OBJECT(rval);
- }
-
- obj = js_NewObject(cx, clasp, proto, parent);
- if (!obj)
- return NULL;
-
- if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval))
- goto bad;
- return JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : obj;
-bad:
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
-}
-
-void
-js_FinalizeObject(JSContext *cx, JSObject *obj)
-{
- JSObjectMap *map;
-
- /* Cope with stillborn objects that have no map. */
- map = obj->map;
- if (!map)
- return;
- JS_ASSERT(obj->slots);
-
- if (cx->runtime->objectHook)
- cx->runtime->objectHook(cx, obj, JS_FALSE, cx->runtime->objectHookData);
-
- /* Remove all watchpoints with weak links to obj. */
- JS_ClearWatchPointsForObject(cx, obj);
-
- /*
- * Finalize obj first, in case it needs map and slots. Optimized to use
- * LOCKED_OBJ_GET_CLASS instead of OBJ_GET_CLASS, so we avoid "promoting"
- * obj's scope from lock-free to lock-full (see jslock.c:ClaimScope) when
- * we're called from the GC. Only the GC should call js_FinalizeObject,
- * and no other threads run JS (and possibly racing to update obj->slots)
- * while the GC is running.
- */
- LOCKED_OBJ_GET_CLASS(obj)->finalize(cx, obj);
-
- /* Drop map and free slots. */
- js_DropObjectMap(cx, map, obj);
- obj->map = NULL;
- JS_free(cx, obj->slots - 1);
- obj->slots = NULL;
-}
-
-/* XXXbe if one adds props, deletes earlier props, adds more, the last added
- won't recycle the deleted props' slots. */
-JSBool
-js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp)
-{
- JSObjectMap *map;
- uint32 nslots, i;
- size_t nbytes;
- jsval *newslots;
-
- map = obj->map;
- JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj);
- nslots = map->nslots;
- if (map->freeslot >= nslots) {
- nslots = map->freeslot;
- JS_ASSERT(nslots >= JS_INITIAL_NSLOTS);
- nslots += (nslots + 1) / 2;
-
- nbytes = (nslots + 1) * sizeof(jsval);
-#if defined _MSC_VER && _MSC_VER <= 800
- if (nbytes > 60000U) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-#endif
-
- newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes);
- if (!newslots)
- return JS_FALSE;
- for (i = 1 + newslots[0]; i <= nslots; i++)
- newslots[i] = JSVAL_VOID;
- newslots[0] = map->nslots = nslots;
- obj->slots = newslots + 1;
- }
-
-#ifdef TOO_MUCH_GC
- obj->slots[map->freeslot] = JSVAL_VOID;
-#endif
- *slotp = map->freeslot++;
- return JS_TRUE;
-}
-
-void
-js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
-{
- JSObjectMap *map;
- uint32 nslots;
- size_t nbytes;
- jsval *newslots;
-
- OBJ_CHECK_SLOT(obj, slot);
- obj->slots[slot] = JSVAL_VOID;
- map = obj->map;
- JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj);
- if (map->freeslot == slot + 1)
- map->freeslot = slot;
- nslots = map->nslots;
- if (nslots > JS_INITIAL_NSLOTS && map->freeslot < nslots / 2) {
- nslots = map->freeslot;
- nslots += nslots / 2;
- if (nslots < JS_INITIAL_NSLOTS)
- nslots = JS_INITIAL_NSLOTS;
- nbytes = (nslots + 1) * sizeof(jsval);
- newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes);
- if (!newslots)
- return;
- newslots[0] = map->nslots = nslots;
- obj->slots = newslots + 1;
- }
-}
-
-#if JS_BUG_EMPTY_INDEX_ZERO
-#define CHECK_FOR_EMPTY_INDEX(id) \
- JS_BEGIN_MACRO \
- if (JSSTRING_LENGTH(_str) == 0) \
- id = JSVAL_ZERO; \
- JS_END_MACRO
-#else
-#define CHECK_FOR_EMPTY_INDEX(id) /* nothing */
-#endif
-
-/* JSVAL_INT_MAX as a string */
-#define JSVAL_INT_MAX_STRING "1073741823"
-
-#define CHECK_FOR_FUNNY_INDEX(id) \
- JS_BEGIN_MACRO \
- if (!JSVAL_IS_INT(id)) { \
- JSAtom *atom_ = (JSAtom *)id; \
- JSString *str_ = ATOM_TO_STRING(atom_); \
- const jschar *cp_ = str_->chars; \
- JSBool negative_ = (*cp_ == '-'); \
- if (negative_) cp_++; \
- if (JS7_ISDEC(*cp_) && \
- str_->length - negative_ <= sizeof(JSVAL_INT_MAX_STRING)-1) { \
- id = CheckForFunnyIndex(id, cp_, negative_); \
- } else { \
- CHECK_FOR_EMPTY_INDEX(id); \
- } \
- } \
- JS_END_MACRO
-
-static jsid
-CheckForFunnyIndex(jsid id, const jschar *cp, JSBool negative)
-{
- jsuint index = JS7_UNDEC(*cp++);
- jsuint oldIndex = 0;
- jsuint c = 0;
-
- if (index != 0) {
- while (JS7_ISDEC(*cp)) {
- oldIndex = index;
- c = JS7_UNDEC(*cp);
- index = 10 * index + c;
- cp++;
- }
- }
- if (*cp == 0 &&
- (oldIndex < (JSVAL_INT_MAX / 10) ||
- (oldIndex == (JSVAL_INT_MAX / 10) &&
- c <= (JSVAL_INT_MAX % 10)))) {
- if (negative)
- index = 0 - index;
- id = INT_TO_JSVAL((jsint)index);
- }
- return id;
-}
-
-JSScopeProperty *
-js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
- JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
- uintN attrs, uintN flags, intN shortid)
-{
- JSScope *scope;
- JSScopeProperty *sprop;
-
- JS_LOCK_OBJ(cx, obj);
- scope = js_GetMutableScope(cx, obj);
- if (!scope) {
- sprop = NULL;
- } else {
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
- sprop = js_AddScopeProperty(cx, scope, id, getter, setter, slot, attrs,
- flags, shortid);
- }
- JS_UNLOCK_OBJ(cx, obj);
- return sprop;
-}
-
-JSScopeProperty *
-js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
- JSScopeProperty *sprop, uintN attrs, uintN mask,
- JSPropertyOp getter, JSPropertyOp setter)
-{
- JSScope *scope;
-
- JS_LOCK_OBJ(cx, obj);
- scope = js_GetMutableScope(cx, obj);
- if (!scope) {
- sprop = NULL;
- } else {
- sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop, attrs, mask,
- getter, setter);
- if (sprop) {
- PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, sprop->id,
- sprop);
- }
- }
- JS_UNLOCK_OBJ(cx, obj);
- return sprop;
-}
-
-JSBool
-js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- JSProperty **propp)
-{
- return js_DefineNativeProperty(cx, obj, id, value, getter, setter, attrs,
- 0, 0, propp);
-}
-
-JSBool
-js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN shortid, JSProperty **propp)
-{
- JSClass *clasp;
- JSScope *scope;
- JSScopeProperty *sprop;
-
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
-
-#if JS_HAS_GETTER_SETTER
- /*
- * If defining a getter or setter, we must check for its counterpart and
- * update the attributes and property ops. A getter or setter is really
- * only half of a property.
- */
- if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
- JSObject *pobj;
-
- /*
- * If JS_THREADSAFE and id is found, js_LookupProperty returns with
- * sprop non-null and pobj locked. If pobj == obj, the property is
- * already in obj and obj has its own (mutable) scope. So if we are
- * defining a getter whose setter was already defined, or vice versa,
- * finish the job via js_ChangeScopePropertyAttributes, and refresh
- * the property cache line for (obj, id) to map sprop.
- */
- if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop))
- return JS_FALSE;
- if (sprop &&
- pobj == obj &&
- (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
- sprop = js_ChangeScopePropertyAttrs(cx, OBJ_SCOPE(obj), sprop,
- attrs, sprop->attrs,
- (attrs & JSPROP_GETTER)
- ? getter
- : sprop->getter,
- (attrs & JSPROP_SETTER)
- ? setter
- : sprop->setter);
-
- /* NB: obj == pobj, so we can share unlock code at the bottom. */
- if (!sprop)
- goto bad;
- goto out;
- }
-
- if (sprop) {
- /* NB: call OBJ_DROP_PROPERTY, as pobj might not be native. */
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- sprop = NULL;
- }
- }
-#endif /* JS_HAS_GETTER_SETTER */
-
- /* Lock if object locking is required by this implementation. */
- JS_LOCK_OBJ(cx, obj);
-
- /* Use the object's class getter and setter by default. */
- clasp = LOCKED_OBJ_GET_CLASS(obj);
- if (!getter)
- getter = clasp->getProperty;
- if (!setter)
- setter = clasp->setProperty;
-
- /* Get obj's own scope if it has one, or create a new one for obj. */
- scope = js_GetMutableScope(cx, obj);
- if (!scope)
- goto bad;
-
- /* Add the property to scope, or replace an existing one of the same id. */
- if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES)
- attrs |= JSPROP_SHARED;
- sprop = js_AddScopeProperty(cx, scope, id, getter, setter,
- SPROP_INVALID_SLOT, attrs, flags, shortid);
- if (!sprop)
- goto bad;
-
- /* XXXbe called with lock held */
- if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), &value)) {
- (void) js_RemoveScopeProperty(cx, scope, id);
- goto bad;
- }
-
- if (SPROP_HAS_VALID_SLOT(sprop, scope))
- LOCKED_OBJ_SET_SLOT(obj, sprop->slot, value);
-
-#if JS_HAS_GETTER_SETTER
-out:
-#endif
- PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
- if (propp)
- *propp = (JSProperty *) sprop;
- else
- JS_UNLOCK_OBJ(cx, obj);
- return JS_TRUE;
-
-bad:
- JS_UNLOCK_OBJ(cx, obj);
- return JS_FALSE;
-}
-
-#if defined JS_THREADSAFE && defined DEBUG
-JS_FRIEND_API(JSBool)
-_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
- JSProperty **propp, const char *file, uintN line)
-#else
-JS_FRIEND_API(JSBool)
-js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
- JSProperty **propp)
-#endif
-{
- JSObject *start, *obj2, *proto;
- JSScope *scope;
- JSScopeProperty *sprop;
- JSClass *clasp;
- JSResolveOp resolve;
- JSResolvingKey key;
- JSResolvingEntry *entry;
- uint32 generation;
- JSNewResolveOp newresolve;
- uintN flags;
- uint32 format;
- JSBool ok;
-
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
-
- /* Search scopes starting with obj and following the prototype link. */
- start = obj;
- for (;;) {
- JS_LOCK_OBJ(cx, obj);
- SET_OBJ_INFO(obj, file, line);
- scope = OBJ_SCOPE(obj);
- if (scope->object == obj) {
- sprop = SCOPE_GET_PROPERTY(scope, id);
- } else {
- /* Shared prototype scope: try resolve before lookup. */
- sprop = NULL;
- }
-
- /* Try obj's class resolve hook if id was not found in obj's scope. */
- if (!sprop) {
- clasp = LOCKED_OBJ_GET_CLASS(obj);
- resolve = clasp->resolve;
- if (resolve != JS_ResolveStub) {
- /* Avoid recursion on (obj, id) already being resolved on cx. */
- key.obj = obj;
- key.id = id;
-
- /*
- * Once we have successfully added an entry for (obj, key) to
- * cx->resolvingTable, control must go through cleanup: before
- * returning. But note that JS_DHASH_ADD may find an existing
- * entry, in which case we bail to suppress runaway recursion.
- */
- if (!StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) {
- JS_UNLOCK_OBJ(cx, obj);
- return JS_FALSE;
- }
- if (!entry) {
- /* Already resolving id in obj -- dampen recursion. */
- JS_UNLOCK_OBJ(cx, obj);
- goto out;
- }
- generation = cx->resolvingTable->generation;
-
- /* Null *propp here so we can test it at cleanup: safely. */
- *propp = NULL;
-
- if (clasp->flags & JSCLASS_NEW_RESOLVE) {
- newresolve = (JSNewResolveOp)resolve;
- flags = 0;
- if (cx->fp && cx->fp->pc) {
- format = js_CodeSpec[*cx->fp->pc].format;
- if ((format & JOF_MODEMASK) != JOF_NAME)
- flags |= JSRESOLVE_QUALIFIED;
- if ((format & JOF_ASSIGNING) ||
- (cx->fp->flags & JSFRAME_ASSIGNING)) {
- flags |= JSRESOLVE_ASSIGNING;
- }
- }
- obj2 = (clasp->flags & JSCLASS_NEW_RESOLVE_GETS_START)
- ? start
- : NULL;
- JS_UNLOCK_OBJ(cx, obj);
-
- /* Protect id and all atoms from a GC nested in resolve. */
- JS_KEEP_ATOMS(cx->runtime);
- ok = newresolve(cx, obj, ID_TO_VALUE(id), flags, &obj2);
- JS_UNKEEP_ATOMS(cx->runtime);
- if (!ok)
- goto cleanup;
-
- JS_LOCK_OBJ(cx, obj);
- SET_OBJ_INFO(obj, file, line);
- if (obj2) {
- /* Resolved: juggle locks and lookup id again. */
- if (obj2 != obj) {
- JS_UNLOCK_OBJ(cx, obj);
- JS_LOCK_OBJ(cx, obj2);
- }
- scope = OBJ_SCOPE(obj2);
- if (!MAP_IS_NATIVE(&scope->map)) {
- /* Whoops, newresolve handed back a foreign obj2. */
- JS_ASSERT(obj2 != obj);
- JS_UNLOCK_OBJ(cx, obj2);
- ok = OBJ_LOOKUP_PROPERTY(cx, obj2, id, objp, propp);
- if (!ok || *propp)
- goto cleanup;
- JS_LOCK_OBJ(cx, obj2);
- } else {
- /*
- * Require that obj2 have its own scope now, as we
- * do for old-style resolve. If it doesn't, then
- * id was not truly resolved, and we'll find it in
- * the proto chain, or miss it if obj2's proto is
- * not on obj's proto chain. That last case is a
- * "too bad!" case.
- */
- if (scope->object == obj2)
- sprop = SCOPE_GET_PROPERTY(scope, id);
- }
- if (obj2 != obj && !sprop) {
- JS_UNLOCK_OBJ(cx, obj2);
- JS_LOCK_OBJ(cx, obj);
- }
- }
- } else {
- /*
- * Old resolve always requires id re-lookup if obj owns
- * its scope after resolve returns.
- */
- JS_UNLOCK_OBJ(cx, obj);
- ok = resolve(cx, obj, ID_TO_VALUE(id));
- if (!ok)
- goto cleanup;
- JS_LOCK_OBJ(cx, obj);
- SET_OBJ_INFO(obj, file, line);
- scope = OBJ_SCOPE(obj);
- JS_ASSERT(MAP_IS_NATIVE(&scope->map));
- if (scope->object == obj)
- sprop = SCOPE_GET_PROPERTY(scope, id);
- }
-
- cleanup:
- StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation);
- if (!ok || *propp)
- return ok;
- }
- }
-
- if (sprop) {
- JS_ASSERT(OBJ_SCOPE(obj) == scope);
- *objp = scope->object; /* XXXbe hide in jsscope.[ch] */
-
- *propp = (JSProperty *) sprop;
- return JS_TRUE;
- }
-
- proto = LOCKED_OBJ_GET_PROTO(obj);
- JS_UNLOCK_OBJ(cx, obj);
- if (!proto)
- break;
- if (!OBJ_IS_NATIVE(proto))
- return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
- obj = proto;
- }
-
-out:
- *objp = NULL;
- *propp = NULL;
- return JS_TRUE;
-}
-
-JS_FRIEND_API(JSBool)
-js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
- JSProperty **propp)
-{
- JSRuntime *rt;
- JSObject *obj, *pobj, *lastobj;
- JSScopeProperty *sprop;
- JSProperty *prop;
-
- rt = cx->runtime;
- obj = cx->fp->scopeChain;
- do {
- /* Try the property cache and return immediately on cache hit. */
- if (OBJ_IS_NATIVE(obj)) {
- JS_LOCK_OBJ(cx, obj);
- PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);
- if (sprop) {
- JS_ASSERT(OBJ_IS_NATIVE(obj));
- *objp = obj;
- *pobjp = obj;
- *propp = (JSProperty *) sprop;
- return JS_TRUE;
- }
- JS_UNLOCK_OBJ(cx, obj);
- }
-
- /* If cache miss, take the slow path. */
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
- return JS_FALSE;
- if (prop) {
- if (OBJ_IS_NATIVE(pobj)) {
- sprop = (JSScopeProperty *) prop;
- PROPERTY_CACHE_FILL(&rt->propertyCache, pobj, id, sprop);
- }
- *objp = obj;
- *pobjp = pobj;
- *propp = prop;
- return JS_TRUE;
- }
- lastobj = obj;
- } while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL);
-
- *objp = lastobj;
- *pobjp = NULL;
- *propp = NULL;
- return JS_TRUE;
-}
-
-JSObject *
-js_FindIdentifierBase(JSContext *cx, jsid id)
-{
- JSObject *obj, *pobj;
- JSProperty *prop;
-
- /*
- * Look for id's property along the "with" statement chain and the
- * statically-linked scope chain.
- */
- if (!js_FindProperty(cx, id, &obj, &pobj, &prop))
- return NULL;
- if (prop) {
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- return obj;
- }
-
- /*
- * Use the top-level scope from the scope chain, which won't end in the
- * same scope as cx->globalObject for cross-context function calls.
- */
- JS_ASSERT(obj);
-
- /*
- * Property not found. Give a strict warning if binding an undeclared
- * top-level variable.
- */
- if (JS_HAS_STRICT_OPTION(cx)) {
- JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id));
- if (!JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_UNDECLARED_VAR,
- JS_GetStringBytes(str))) {
- return NULL;
- }
- }
- return obj;
-}
-
-JSBool
-js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
-{
- JSObject *obj2;
- JSScopeProperty *sprop;
- JSScope *scope;
- uint32 slot;
-
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
-
- if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop))
- return JS_FALSE;
- if (!sprop) {
- jsval default_val;
-
-#if JS_BUG_NULL_INDEX_PROPS
- /* Indexed properties defaulted to null in old versions. */
- default_val = (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0)
- ? JSVAL_NULL
- : JSVAL_VOID;
-#else
- default_val = JSVAL_VOID;
-#endif
- *vp = default_val;
-
- if (!OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, ID_TO_VALUE(id), vp))
- return JS_FALSE;
-
- /*
- * Give a strict warning if foo.bar is evaluated by a script for an
- * object foo with no property named 'bar'.
- */
- if (JS_HAS_STRICT_OPTION(cx) &&
- *vp == default_val &&
- cx->fp && cx->fp->pc &&
- (*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM))
- {
- jsbytecode *pc, *endpc;
- JSString *str;
-
- /* Kludge to allow (typeof foo == "undefined") tests. */
- JS_ASSERT(cx->fp->script);
- pc = cx->fp->pc;
- pc += js_CodeSpec[*pc].length;
- endpc = cx->fp->script->code + cx->fp->script->length;
- while (pc < endpc) {
- if (*pc == JSOP_TYPEOF)
- return JS_TRUE;
- if (*pc != JSOP_GROUP)
- break;
- pc++;
- }
-
- /* Ok, bad undefined property reference: whine about it. */
- str = js_DecompileValueGenerator(cx, JS_FALSE, ID_TO_VALUE(id),
- NULL);
- if (!str ||
- !JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING|JSREPORT_STRICT,
- js_GetErrorMessage, NULL,
- JSMSG_UNDEFINED_PROP,
- JS_GetStringBytes(str))) {
- return JS_FALSE;
- }
- }
- return JS_TRUE;
- }
-
- if (!OBJ_IS_NATIVE(obj2)) {
- OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
- return OBJ_GET_PROPERTY(cx, obj2, id, vp);
- }
-
- /* Unlock obj2 before calling getter, relock after to avoid deadlock. */
- scope = OBJ_SCOPE(obj2);
- slot = sprop->slot;
- if (slot != SPROP_INVALID_SLOT) {
- JS_ASSERT(slot < obj2->map->freeslot);
- *vp = LOCKED_OBJ_GET_SLOT(obj2, slot);
-
- /* If sprop has a stub getter, we're done. */
- if (!sprop->getter)
- goto out;
- } else {
- *vp = JSVAL_VOID;
- }
-
- JS_UNLOCK_SCOPE(cx, scope);
- if (!SPROP_GET(cx, sprop, obj, obj2, vp))
- return JS_FALSE;
- JS_LOCK_SCOPE(cx, scope);
-
- if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
- LOCKED_OBJ_SET_SLOT(obj2, slot, *vp);
- PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj2, id, sprop);
- }
-
-out:
- JS_UNLOCK_SCOPE(cx, scope);
- return JS_TRUE;
-}
-
-JSBool
-js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
-{
- JSObject *pobj;
- JSScopeProperty *sprop;
- JSScope *scope;
- uintN attrs, flags;
- intN shortid;
- JSClass *clasp;
- JSPropertyOp getter, setter;
- jsval pval;
- uint32 slot;
-
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
-
- if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop))
- return JS_FALSE;
-
- if (sprop && !OBJ_IS_NATIVE(pobj)) {
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- sprop = NULL;
- }
-
- /*
- * Now either sprop is null, meaning id was not found in obj or one of its
- * prototypes; or sprop is non-null, meaning id was found in pobj's scope.
- * If JS_THREADSAFE and sprop is non-null, then scope is locked, and sprop
- * is held: we must OBJ_DROP_PROPERTY or JS_UNLOCK_SCOPE before we return
- * (the two are equivalent for native objects, but we use JS_UNLOCK_SCOPE
- * because it is cheaper).
- */
- attrs = JSPROP_ENUMERATE;
- flags = 0;
- shortid = 0;
- clasp = OBJ_GET_CLASS(cx, obj);
- getter = clasp->getProperty;
- setter = clasp->setProperty;
-
- if (sprop) {
- /*
- * Set scope for use below. It was locked by js_LookupProperty, and
- * we know pobj owns it (i.e., scope->object == pobj). Therefore we
- * optimize JS_UNLOCK_OBJ(cx, pobj) into JS_UNLOCK_SCOPE(cx, scope).
- */
- scope = OBJ_SCOPE(pobj);
-
- attrs = sprop->attrs;
- if ((attrs & JSPROP_READONLY) ||
- (SCOPE_IS_SEALED(scope) && pobj == obj)) {
- JS_UNLOCK_SCOPE(cx, scope);
- if ((attrs & JSPROP_READONLY) && JSVERSION_IS_ECMA(cx->version))
- return JS_TRUE;
- goto read_only_error;
- }
-
- if (pobj != obj) {
- /*
- * We found id in a prototype object: prepare to share or shadow.
- * NB: Thanks to the immutable, garbage-collected property tree
- * maintained by jsscope.c in cx->runtime, we needn't worry about
- * sprop going away behind our back after we've unlocked scope.
- */
- JS_UNLOCK_SCOPE(cx, scope);
-
- /* Don't clone a shared prototype property. */
- if (attrs & JSPROP_SHARED)
- return SPROP_SET(cx, sprop, obj, pobj, vp);
-
- /* Restore attrs to the ECMA default for new properties. */
- attrs = JSPROP_ENUMERATE;
-
- /*
- * Preserve the shortid, getter, and setter when shadowing any
- * property that has a shortid. An old API convention requires
- * that the property's getter and setter functions receive the
- * shortid, not id, when they are called on the shadow we are
- * about to create in obj's scope.
- */
- if (sprop->flags & SPROP_HAS_SHORTID) {
- flags = SPROP_HAS_SHORTID;
- shortid = sprop->shortid;
- getter = sprop->getter;
- setter = sprop->setter;
- }
-
- /*
- * Forget we found the proto-property now that we've copied any
- * needed member values.
- */
- sprop = NULL;
- }
-#ifdef __GNUC__ /* suppress bogus gcc warnings */
- } else {
- scope = NULL;
-#endif
- }
-
- if (!sprop) {
- if (SCOPE_IS_SEALED(OBJ_SCOPE(obj)) && OBJ_SCOPE(obj)->object == obj)
- goto read_only_error;
-
- /* Find or make a property descriptor with the right heritage. */
- JS_LOCK_OBJ(cx, obj);
- scope = js_GetMutableScope(cx, obj);
- if (!scope) {
- JS_UNLOCK_OBJ(cx, obj);
- return JS_FALSE;
- }
- if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES)
- attrs |= JSPROP_SHARED;
- sprop = js_AddScopeProperty(cx, scope, id, getter, setter,
- SPROP_INVALID_SLOT, attrs, flags, shortid);
- if (!sprop) {
- JS_UNLOCK_SCOPE(cx, scope);
- return JS_FALSE;
- }
-
- /* XXXbe called with obj locked */
- if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), vp)) {
- (void) js_RemoveScopeProperty(cx, scope, id);
- JS_UNLOCK_SCOPE(cx, scope);
- return JS_FALSE;
- }
-
- /* Initialize new property value (passed to setter) to undefined. */
- if (SPROP_HAS_VALID_SLOT(sprop, scope))
- LOCKED_OBJ_SET_SLOT(obj, sprop->slot, JSVAL_VOID);
-
- PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
- }
-
- /* Get the current property value from its slot. */
- slot = sprop->slot;
- if (slot != SPROP_INVALID_SLOT) {
- JS_ASSERT(slot < obj->map->freeslot);
- pval = LOCKED_OBJ_GET_SLOT(obj, slot);
-
- /* If sprop has a stub setter, keep scope locked and just store *vp. */
- if (!sprop->setter)
- goto set_slot;
- }
-
- /* Avoid deadlock by unlocking obj's scope while calling sprop's setter. */
- JS_UNLOCK_SCOPE(cx, scope);
-
- /* Let the setter modify vp before copying from it to obj->slots[slot]. */
- if (!SPROP_SET(cx, sprop, obj, obj, vp))
- return JS_FALSE;
-
- /* Relock obj's scope until we are done with sprop. */
- JS_LOCK_SCOPE(cx, scope);
-
- /*
- * Check whether sprop is still around (was not deleted), and whether it
- * has a slot (it may never have had one, or we may have lost a race with
- * someone who cleared scope).
- */
- if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
- set_slot:
- GC_POKE(cx, pval);
- LOCKED_OBJ_SET_SLOT(obj, slot, *vp);
- }
- JS_UNLOCK_SCOPE(cx, scope);
- return JS_TRUE;
-
- read_only_error: {
- JSString *str = js_DecompileValueGenerator(cx,
- JSDVG_IGNORE_STACK,
- ID_TO_VALUE(id),
- NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_READ_ONLY,
- JS_GetStringBytes(str));
- }
- return JS_FALSE;
- }
-}
-
-JSBool
-js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp)
-{
- JSBool noprop, ok;
- JSScopeProperty *sprop;
-
- noprop = !prop;
- if (noprop) {
- if (!js_LookupProperty(cx, obj, id, &obj, &prop))
- return JS_FALSE;
- if (!prop) {
- *attrsp = 0;
- return JS_TRUE;
- }
- if (!OBJ_IS_NATIVE(obj)) {
- ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, attrsp);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
- }
- }
- sprop = (JSScopeProperty *)prop;
- *attrsp = sprop->attrs;
- if (noprop)
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return JS_TRUE;
-}
-
-JSBool
-js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp)
-{
- JSBool noprop, ok;
- JSScopeProperty *sprop;
-
- noprop = !prop;
- if (noprop) {
- if (!js_LookupProperty(cx, obj, id, &obj, &prop))
- return JS_FALSE;
- if (!prop)
- return JS_TRUE;
- if (!OBJ_IS_NATIVE(obj)) {
- ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, attrsp);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
- }
- }
- sprop = (JSScopeProperty *)prop;
- sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
- *attrsp &
- ~(JSPROP_GETTER | JSPROP_SETTER), 0,
- sprop->getter, sprop->setter);
- if (noprop)
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return (sprop != NULL);
-}
-
-JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
-{
-#if JS_HAS_PROP_DELETE
-
- JSObject *proto;
- JSProperty *prop;
- JSScopeProperty *sprop;
- JSString *str;
- JSScope *scope;
- JSBool ok;
-
- *rval = JSVERSION_IS_ECMA(cx->version) ? JSVAL_TRUE : JSVAL_VOID;
-
- /*
- * Handle old bug that took empty string as zero index. Also convert
- * string indices to integers if appropriate.
- */
- CHECK_FOR_FUNNY_INDEX(id);
-
- if (!js_LookupProperty(cx, obj, id, &proto, &prop))
- return JS_FALSE;
- if (!prop || proto != obj) {
- /*
- * If the property was found in a native prototype, check whether it's
- * shared and permanent. Such a property stands for direct properties
- * in all delegating objects, matching ECMA semantics without bloating
- * each delegating object.
- */
- if (prop) {
- if (OBJ_IS_NATIVE(proto)) {
- sprop = (JSScopeProperty *)prop;
- if (SPROP_IS_SHARED_PERMANENT(sprop))
- *rval = JSVAL_FALSE;
- }
- OBJ_DROP_PROPERTY(cx, proto, prop);
- if (*rval == JSVAL_FALSE)
- return JS_TRUE;
- }
-
- /*
- * If no property, or the property comes unshared or impermanent from
- * a prototype, call the class's delProperty hook, passing rval as the
- * result parameter.
- */
- return OBJ_GET_CLASS(cx, obj)->delProperty(cx, obj, ID_TO_VALUE(id),
- rval);
- }
-
- sprop = (JSScopeProperty *)prop;
- if (sprop->attrs & JSPROP_PERMANENT) {
- OBJ_DROP_PROPERTY(cx, obj, prop);
- if (JSVERSION_IS_ECMA(cx->version)) {
- *rval = JSVAL_FALSE;
- return JS_TRUE;
- }
- str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
- ID_TO_VALUE(id), NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_PERMANENT, JS_GetStringBytes(str));
- }
- return JS_FALSE;
- }
-
- /* XXXbe called with obj locked */
- if (!LOCKED_OBJ_GET_CLASS(obj)->delProperty(cx, obj, SPROP_USERID(sprop),
- rval)) {
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return JS_FALSE;
- }
-
- scope = OBJ_SCOPE(obj);
- if (SPROP_HAS_VALID_SLOT(sprop, scope))
- GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot));
-
- PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, NULL);
- ok = js_RemoveScopeProperty(cx, scope, id);
- OBJ_DROP_PROPERTY(cx, obj, prop);
- return ok;
-
-#else /* !JS_HAS_PROP_DELETE */
-
- jsval null = JSVAL_NULL;
-
- *rval = JSVAL_VOID;
- return js_SetProperty(cx, obj, id, &null);
-
-#endif /* !JS_HAS_PROP_DELETE */
-}
-
-JSBool
-js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
-{
- jsval v;
- JSString *str;
-
- v = OBJECT_TO_JSVAL(obj);
- switch (hint) {
- case JSTYPE_STRING:
- /*
- * Propagate the exception if js_TryMethod finds an appropriate
- * method, and calling that method returned failure.
- */
- if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL,
- &v))
- return JS_FALSE;
-
- if (!JSVAL_IS_PRIMITIVE(v)) {
- if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
- return JS_FALSE;
-
- /*
- * JS1.2 never failed (except for malloc failure) to convert an
- * object to a string. ECMA requires an error if both toString
- * and valueOf fail to produce a primitive value.
- */
- if (!JSVAL_IS_PRIMITIVE(v) && cx->version == JSVERSION_1_2) {
- char *bytes = JS_smprintf("[object %s]",
- OBJ_GET_CLASS(cx, obj)->name);
- if (!bytes)
- return JS_FALSE;
- str = JS_NewString(cx, bytes, strlen(bytes));
- if (!str) {
- free(bytes);
- return JS_FALSE;
- }
- v = STRING_TO_JSVAL(str);
- goto out;
- }
- }
- break;
-
- default:
- if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
- return JS_FALSE;
- if (!JSVAL_IS_PRIMITIVE(v)) {
- JSType type = JS_TypeOfValue(cx, v);
- if (type == hint ||
- (type == JSTYPE_FUNCTION && hint == JSTYPE_OBJECT)) {
- goto out;
- }
- /* Don't convert to string (source object literal) for JS1.2. */
- if (cx->version == JSVERSION_1_2 && hint == JSTYPE_BOOLEAN)
- goto out;
- if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0,
- NULL, &v))
- return JS_FALSE;
- }
- break;
- }
- if (!JSVAL_IS_PRIMITIVE(v)) {
- /* Avoid recursive death through js_DecompileValueGenerator. */
- if (hint == JSTYPE_STRING) {
- str = JS_InternString(cx, OBJ_GET_CLASS(cx, obj)->name);
- if (!str)
- return JS_FALSE;
- } else {
- str = NULL;
- }
- *vp = OBJECT_TO_JSVAL(obj);
- str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, str);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_CONVERT_TO,
- JS_GetStringBytes(str),
- (hint == JSTYPE_VOID)
- ? "primitive type"
- : js_type_str[hint]);
- }
- return JS_FALSE;
- }
-out:
- *vp = v;
- return JS_TRUE;
-}
-
-JSIdArray *
-js_NewIdArray(JSContext *cx, jsint length)
-{
- JSIdArray *ida;
-
- ida = (JSIdArray *)
- JS_malloc(cx, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
- if (ida)
- ida->length = length;
- return ida;
-}
-
-JSIdArray *
-js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length)
-{
- ida = (JSIdArray *)
- JS_realloc(cx, ida, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
- if (ida)
- ida->length = length;
- return ida;
-}
-
-/* Private type used to iterate over all properties of a native JS object */
-typedef struct JSNativeIteratorState {
- jsint next_index; /* index into jsid array */
- JSIdArray *ida; /* All property ids in enumeration */
-} JSNativeIteratorState;
-
-/*
- * This function is used to enumerate the properties of native JSObjects
- * and those host objects that do not define a JSNewEnumerateOp-style iterator
- * function.
- */
-JSBool
-js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
- jsval *statep, jsid *idp)
-{
- JSObject *proto_obj;
- JSClass *clasp;
- JSEnumerateOp enumerate;
- JSScopeProperty *sprop, *lastProp;
- jsint i, length;
- JSScope *scope;
- JSIdArray *ida;
- JSNativeIteratorState *state;
-
- clasp = OBJ_GET_CLASS(cx, obj);
- enumerate = clasp->enumerate;
- if (clasp->flags & JSCLASS_NEW_ENUMERATE)
- return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
-
- switch (enum_op) {
-
- case JSENUMERATE_INIT:
- if (!enumerate(cx, obj))
- goto init_error;
- length = 0;
-
- /*
- * The set of all property ids is pre-computed when the iterator
- * is initialized so as to avoid problems with properties being
- * deleted during the iteration.
- */
- JS_LOCK_OBJ(cx, obj);
- scope = OBJ_SCOPE(obj);
-
- /*
- * If this object shares a scope with its prototype, don't enumerate
- * its properties. Otherwise they will be enumerated a second time
- * when the prototype object is enumerated.
- */
- proto_obj = OBJ_GET_PROTO(cx, obj);
- if (proto_obj && scope == OBJ_SCOPE(proto_obj)) {
- ida = js_NewIdArray(cx, 0);
- if (!ida) {
- JS_UNLOCK_OBJ(cx, obj);
- goto init_error;
- }
- } else {
- /* Object has a private scope; Enumerate all props in scope. */
- for (sprop = lastProp = SCOPE_LAST_PROP(scope); sprop;
- sprop = sprop->parent) {
- if ((sprop->attrs & JSPROP_ENUMERATE) &&
- !(sprop->flags & SPROP_IS_ALIAS) &&
- (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
- SCOPE_HAS_PROPERTY(scope, sprop))) {
- length++;
- }
- }
- ida = js_NewIdArray(cx, length);
- if (!ida) {
- JS_UNLOCK_OBJ(cx, obj);
- goto init_error;
- }
- i = length;
- for (sprop = lastProp; sprop; sprop = sprop->parent) {
- if ((sprop->attrs & JSPROP_ENUMERATE) &&
- !(sprop->flags & SPROP_IS_ALIAS) &&
- (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
- SCOPE_HAS_PROPERTY(scope, sprop))) {
- JS_ASSERT(i > 0);
- ida->vector[--i] = sprop->id;
- }
- }
- }
- JS_UNLOCK_OBJ(cx, obj);
-
- state = (JSNativeIteratorState *)
- JS_malloc(cx, sizeof(JSNativeIteratorState));
- if (!state) {
- JS_DestroyIdArray(cx, ida);
- goto init_error;
- }
- state->ida = ida;
- state->next_index = 0;
- *statep = PRIVATE_TO_JSVAL(state);
- if (idp)
- *idp = INT_TO_JSVAL(length);
- return JS_TRUE;
-
- case JSENUMERATE_NEXT:
- state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
- ida = state->ida;
- length = ida->length;
- if (state->next_index != length) {
- *idp = ida->vector[state->next_index++];
- return JS_TRUE;
- }
-
- /* Fall through ... */
-
- case JSENUMERATE_DESTROY:
- state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
- JS_DestroyIdArray(cx, state->ida);
- JS_free(cx, state);
- *statep = JSVAL_NULL;
- return JS_TRUE;
-
- default:
- JS_ASSERT(0);
- return JS_FALSE;
- }
-
-init_error:
- *statep = JSVAL_NULL;
- return JS_FALSE;
-}
-
-JSBool
-js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
- jsval *vp, uintN *attrsp)
-{
- JSObject *pobj;
- JSProperty *prop;
- JSScopeProperty *sprop;
- JSClass *clasp;
- JSBool ok;
-
- if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
- return JS_FALSE;
- if (!prop) {
- *vp = JSVAL_VOID;
- *attrsp = 0;
- clasp = OBJ_GET_CLASS(cx, obj);
- return !clasp->checkAccess ||
- clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
- }
- if (!OBJ_IS_NATIVE(pobj)) {
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp);
- }
- sprop = (JSScopeProperty *)prop;
- *vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)))
- ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
- : JSVAL_VOID;
- *attrsp = sprop->attrs;
- clasp = LOCKED_OBJ_GET_CLASS(obj);
- if (clasp->checkAccess) {
- JS_UNLOCK_OBJ(cx, pobj);
- ok = clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
- JS_LOCK_OBJ(cx, pobj);
- } else {
- ok = JS_TRUE;
- }
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- return ok;
-}
-
-#ifdef JS_THREADSAFE
-void
-js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop)
-{
- JS_UNLOCK_OBJ(cx, obj);
-}
-#endif
-
-static void
-ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
-{
- /*
- * The decompiler may need to access the args of the function in
- * progress rather than the one we had hoped to call.
- * So we switch the cx->fp to the frame below us. We stick the
- * current frame in the dormantFrameChain to protect it from gc.
- */
-
- JSStackFrame *fp = cx->fp;
- if (fp->down) {
- JS_ASSERT(!fp->dormantNext);
- fp->dormantNext = cx->dormantFrameChain;
- cx->dormantFrameChain = fp;
- cx->fp = fp->down;
- }
-
- js_ReportIsNotFunction(cx, vp, flags);
-
- if (fp->down) {
- JS_ASSERT(cx->dormantFrameChain == fp);
- cx->dormantFrameChain = fp->dormantNext;
- fp->dormantNext = NULL;
- cx->fp = fp;
- }
-}
-
-JSBool
-js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSClass *clasp;
-
- clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2]));
- if (!clasp->call) {
- ReportIsNotFunction(cx, &argv[-2], 0);
- return JS_FALSE;
- }
- return clasp->call(cx, obj, argc, argv, rval);
-}
-
-JSBool
-js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSClass *clasp;
-
- clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2]));
- if (!clasp->construct) {
- ReportIsNotFunction(cx, &argv[-2], JSV2F_CONSTRUCT);
- return JS_FALSE;
- }
- return clasp->construct(cx, obj, argc, argv, rval);
-}
-
-JSBool
-js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
-{
- JSClass *clasp;
-
- clasp = OBJ_GET_CLASS(cx, obj);
- if (clasp->hasInstance)
- return clasp->hasInstance(cx, obj, v, bp);
- *bp = JS_FALSE;
- return JS_TRUE;
-}
-
-JSBool
-js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
-{
- JSObject *obj2;
-
- *bp = JS_FALSE;
- if (JSVAL_IS_PRIMITIVE(v))
- return JS_TRUE;
- obj2 = JSVAL_TO_OBJECT(v);
- while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL) {
- if (obj2 == obj) {
- *bp = JS_TRUE;
- break;
- }
- }
- return JS_TRUE;
-}
-
-JSBool
-js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop)
-{
- return GetClassPrototype(cx, NULL, name, protop);
-}
-
-static JSBool
-GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
- JSObject **protop)
-{
- jsval v;
- JSObject *ctor;
-
- if (!FindConstructor(cx, scope, name, &v))
- return JS_FALSE;
- if (JSVAL_IS_FUNCTION(cx, v)) {
- ctor = JSVAL_TO_OBJECT(v);
- if (!OBJ_GET_PROPERTY(cx, ctor,
- (jsid)cx->runtime->atomState.classPrototypeAtom,
- &v)) {
- return JS_FALSE;
- }
- }
- *protop = JSVAL_IS_OBJECT(v) ? JSVAL_TO_OBJECT(v) : NULL;
- return JS_TRUE;
-}
-
-JSBool
-js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
- uintN attrs)
-{
- /*
- * Use the given attributes for the prototype property of the constructor,
- * as user-defined constructors have a DontEnum | DontDelete prototype (it
- * may be reset), while native or "system" constructors require DontEnum |
- * ReadOnly | DontDelete.
- */
- if (!OBJ_DEFINE_PROPERTY(cx, ctor,
- (jsid)cx->runtime->atomState.classPrototypeAtom,
- OBJECT_TO_JSVAL(proto), NULL, NULL,
- attrs, NULL)) {
- return JS_FALSE;
- }
-
- /*
- * ECMA says that Object.prototype.constructor, or f.prototype.constructor
- * for a user-defined function f, is DontEnum.
- */
- return OBJ_DEFINE_PROPERTY(cx, proto,
- (jsid)cx->runtime->atomState.constructorAtom,
- OBJECT_TO_JSVAL(ctor), NULL, NULL,
- 0, NULL);
-}
-
-JSBool
-js_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
-{
- JSObject *obj;
-
- if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
- obj = NULL;
- } else if (JSVAL_IS_OBJECT(v)) {
- obj = JSVAL_TO_OBJECT(v);
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_OBJECT, &v))
- return JS_FALSE;
- if (JSVAL_IS_OBJECT(v))
- obj = JSVAL_TO_OBJECT(v);
- } else {
- if (JSVAL_IS_STRING(v)) {
- obj = js_StringToObject(cx, JSVAL_TO_STRING(v));
- } else if (JSVAL_IS_INT(v)) {
- obj = js_NumberToObject(cx, (jsdouble)JSVAL_TO_INT(v));
- } else if (JSVAL_IS_DOUBLE(v)) {
- obj = js_NumberToObject(cx, *JSVAL_TO_DOUBLE(v));
- } else {
- JS_ASSERT(JSVAL_IS_BOOLEAN(v));
- obj = js_BooleanToObject(cx, JSVAL_TO_BOOLEAN(v));
- }
- if (!obj)
- return JS_FALSE;
- }
- *objp = obj;
- return JS_TRUE;
-}
-
-JSObject *
-js_ValueToNonNullObject(JSContext *cx, jsval v)
-{
- JSObject *obj;
- JSString *str;
-
- if (!js_ValueToObject(cx, v, &obj))
- return NULL;
- if (!obj) {
- str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
- if (str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_NO_PROPERTIES, JS_GetStringBytes(str));
- }
- }
- return obj;
-}
-
-JSBool
-js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval)
-{
-#if JS_HAS_VALUEOF_HINT
- jsval argv[1];
-
- argv[0] = ATOM_KEY(cx->runtime->atomState.typeAtoms[type]);
- return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 1, argv,
- rval);
-#else
- return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 0, NULL,
- rval);
-#endif
-}
-
-JSBool
-js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
- uintN argc, jsval *argv, jsval *rval)
-{
- JSErrorReporter older;
- jsval fval;
- JSBool ok;
-
- /*
- * Report failure only if an appropriate method was found, and calling it
- * returned failure. We propagate failure in this case to make exceptions
- * behave properly.
- */
- older = JS_SetErrorReporter(cx, NULL);
- if (OBJ_GET_PROPERTY(cx, obj, (jsid)atom, &fval) &&
- !JSVAL_IS_PRIMITIVE(fval)) {
- ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
- } else {
- ok = JS_TRUE;
- }
- JS_SetErrorReporter(cx, older);
- return ok;
-}
-
-#if JS_HAS_XDR
-
-#include "jsxdrapi.h"
-
-JSBool
-js_XDRObject(JSXDRState *xdr, JSObject **objp)
-{
- JSContext *cx;
- JSClass *clasp;
- const char *className;
- uint32 classId, classDef;
- JSBool ok;
- JSObject *proto;
-
- cx = xdr->cx;
- if (xdr->mode == JSXDR_ENCODE) {
- clasp = OBJ_GET_CLASS(cx, *objp);
- className = clasp->name;
- classId = JS_XDRFindClassIdByName(xdr, className);
- classDef = !classId;
- if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId))
- return JS_FALSE;
- } else {
- classDef = 0;
- className = NULL;
- clasp = NULL; /* quell GCC overwarning */
- }
-
- /* XDR a flag word followed (if true) by the class name. */
- if (!JS_XDRUint32(xdr, &classDef))
- return JS_FALSE;
- if (classDef && !JS_XDRCString(xdr, (char **) &className))
- return JS_FALSE;
-
- /* From here on, return through out: to free className if it was set. */
- ok = JS_XDRUint32(xdr, &classId);
- if (!ok)
- goto out;
-
- if (xdr->mode != JSXDR_ENCODE) {
- if (classDef) {
- ok = js_GetClassPrototype(cx, className, &proto);
- if (!ok)
- goto out;
- clasp = OBJ_GET_CLASS(cx, proto);
- ok = JS_XDRRegisterClass(xdr, clasp, &classId);
- if (!ok)
- goto out;
- } else {
- clasp = JS_XDRFindClassById(xdr, classId);
- if (!clasp) {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_FIND_CLASS, numBuf);
- ok = JS_FALSE;
- goto out;
- }
- }
- }
-
- if (!clasp->xdrObject) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_XDR_CLASS, clasp->name);
- ok = JS_FALSE;
- } else {
- ok = clasp->xdrObject(xdr, objp);
- }
-out:
- if (xdr->mode != JSXDR_ENCODE && className)
- JS_free(cx, (void *)className);
- return ok;
-}
-
-#endif /* JS_HAS_XDR */
-
-#ifdef DEBUG_brendan
-
-#include <stdio.h>
-#include <math.h>
-
-uint32 js_entry_count_max;
-uint32 js_entry_count_sum;
-double js_entry_count_sqsum;
-uint32 js_entry_count_hist[11];
-
-static void
-MeterEntryCount(uintN count)
-{
- if (count) {
- js_entry_count_sum += count;
- js_entry_count_sqsum += (double)count * count;
- if (count > js_entry_count_max)
- js_entry_count_max = count;
- }
- js_entry_count_hist[JS_MIN(count, 10)]++;
-}
-
-void
-js_DumpScopeMeters(JSRuntime *rt)
-{
- static FILE *logfp;
- if (!logfp)
- logfp = fopen("/tmp/scope.stats", "a");
-
- {
- double mean = 0., var = 0., sigma = 0.;
- double nscopes = rt->liveScopes;
- double nentrys = js_entry_count_sum;
- if (nscopes > 0 && nentrys >= 0) {
- mean = nentrys / nscopes;
- var = nscopes * js_entry_count_sqsum - nentrys * nentrys;
- if (var < 0.0 || nscopes <= 1)
- var = 0.0;
- else
- var /= nscopes * (nscopes - 1);
-
- /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
- sigma = (var != 0.) ? sqrt(var) : 0.;
- }
-
- fprintf(logfp,
- "scopes %g entries %g mean %g sigma %g max %u",
- nscopes, nentrys, mean, sigma, js_entry_count_max);
- }
-
- fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u\n",
- js_entry_count_hist[0], js_entry_count_hist[1],
- js_entry_count_hist[2], js_entry_count_hist[3],
- js_entry_count_hist[4], js_entry_count_hist[5],
- js_entry_count_hist[6], js_entry_count_hist[7],
- js_entry_count_hist[8], js_entry_count_hist[9],
- js_entry_count_hist[10]);
- js_entry_count_sum = js_entry_count_max = 0;
- js_entry_count_sqsum = 0;
- memset(js_entry_count_hist, 0, sizeof js_entry_count_hist);
- fflush(logfp);
-}
-
-#endif /* DEBUG_brendan */
-
-uint32
-js_Mark(JSContext *cx, JSObject *obj, void *arg)
-{
- JSScope *scope;
- JSScopeProperty *sprop;
- JSClass *clasp;
-
- JS_ASSERT(OBJ_IS_NATIVE(obj));
- scope = OBJ_SCOPE(obj);
-#ifdef DEBUG_brendan
- if (scope->object == obj)
- MeterEntryCount(scope->entryCount);
-#endif
-
- JS_ASSERT(!SCOPE_LAST_PROP(scope) ||
- SCOPE_HAS_PROPERTY(scope, SCOPE_LAST_PROP(scope)));
-
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
- continue;
- MARK_SCOPE_PROPERTY(sprop);
- if (!JSVAL_IS_INT(sprop->id))
- GC_MARK_ATOM(cx, (JSAtom *)sprop->id, arg);
-
-#if JS_HAS_GETTER_SETTER
- if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
-#ifdef GC_MARK_DEBUG
- char buf[64];
- JSAtom *atom = (JSAtom *)sprop->id;
- const char *id = (atom && ATOM_IS_STRING(atom))
- ? JS_GetStringBytes(ATOM_TO_STRING(atom))
- : "unknown";
-#endif
-
- if (sprop->attrs & JSPROP_GETTER) {
-#ifdef GC_MARK_DEBUG
- JS_snprintf(buf, sizeof buf, "%s %s",
- id, js_getter_str);
-#endif
- GC_MARK(cx,
- JSVAL_TO_GCTHING((jsval) sprop->getter),
- buf,
- arg);
- }
- if (sprop->attrs & JSPROP_SETTER) {
-#ifdef GC_MARK_DEBUG
- JS_snprintf(buf, sizeof buf, "%s %s",
- id, js_setter_str);
-#endif
- GC_MARK(cx,
- JSVAL_TO_GCTHING((jsval) sprop->setter),
- buf,
- arg);
- }
- }
-#endif /* JS_HAS_GETTER_SETTER */
- }
-
- /* No one runs while the GC is running, so we can use LOCKED_... here. */
- clasp = LOCKED_OBJ_GET_CLASS(obj);
- if (clasp->mark)
- (void) clasp->mark(cx, obj, arg);
-
- if (scope->object != obj) {
- /*
- * An unmutated object that shares a prototype's scope. We can't tell
- * how many slots are allocated and in use at obj->slots by looking at
- * scope, so we get obj->slots' length from its -1'st element.
- */
- return (uint32) obj->slots[-1];
- }
- return JS_MIN(obj->map->freeslot, obj->map->nslots);
-}
-
-void
-js_Clear(JSContext *cx, JSObject *obj)
-{
- JSScope *scope;
- JSRuntime *rt;
- JSScopeProperty *sprop;
- uint32 i, n;
-
- /*
- * Clear our scope and the property cache of all obj's properties only if
- * obj owns the scope (i.e., not if obj is unmutated and therefore sharing
- * its prototype's scope). NB: we do not clear any reserved slots lying
- * below JSSLOT_FREE(clasp).
- */
- JS_LOCK_OBJ(cx, obj);
- scope = OBJ_SCOPE(obj);
- if (scope->object == obj) {
- /* Clear the property cache before we clear the scope. */
- rt = cx->runtime;
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
- SCOPE_HAS_PROPERTY(scope, sprop)) {
- PROPERTY_CACHE_FILL(&rt->propertyCache, obj, sprop->id, NULL);
- }
- }
-
- /* Now that we're done using scope->lastProp/table, clear scope. */
- js_ClearScope(cx, scope);
-
- /* Clear slot values and reset freeslot so we're consistent. */
- i = scope->map.nslots;
- n = JSSLOT_FREE(LOCKED_OBJ_GET_CLASS(obj));
- while (--i >= n)
- obj->slots[i] = JSVAL_VOID;
- scope->map.freeslot = n;
- }
- JS_UNLOCK_OBJ(cx, obj);
-}
-
-jsval
-js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot)
-{
- jsval v;
-
- JS_LOCK_OBJ(cx, obj);
- v = (slot < (uint32) obj->slots[-1]) ? obj->slots[slot] : JSVAL_VOID;
- JS_UNLOCK_OBJ(cx, obj);
- return v;
-}
-
-void
-js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
-{
- uint32 nslots, rlimit, i;
- JSClass *clasp;
- jsval *newslots;
-
- JS_LOCK_OBJ(cx, obj);
- nslots = (uint32) obj->slots[-1];
- if (slot >= nslots) {
- clasp = LOCKED_OBJ_GET_CLASS(obj);
- rlimit = JSSLOT_START(clasp) + JSCLASS_RESERVED_SLOTS(clasp);
- JS_ASSERT(slot < rlimit);
- if (rlimit > nslots)
- nslots = rlimit;
-
- newslots = (jsval *)
- JS_realloc(cx, obj->slots - 1, (nslots + 1) * sizeof(jsval));
- if (!newslots) {
- JS_UNLOCK_OBJ(cx, obj);
- return;
- }
- for (i = 1 + newslots[0]; i <= rlimit; i++)
- newslots[i] = JSVAL_VOID;
- newslots[0] = nslots;
- if (OBJ_SCOPE(obj)->object == obj)
- obj->map->nslots = nslots;
- obj->slots = newslots + 1;
- }
-
- obj->slots[slot] = v;
- JS_UNLOCK_OBJ(cx, obj);
-}
-
-#ifdef DEBUG
-
-/* Routines to print out values during debugging. */
-
-void printChar(jschar *cp) {
- fprintf(stderr, "jschar* (0x%p) \"", (void *)cp);
- while (*cp)
- fputc(*cp++, stderr);
- fputc('"', stderr);
- fputc('\n', stderr);
-}
-
-void printString(JSString *str) {
- size_t i, n;
- jschar *s;
- fprintf(stderr, "string (0x%p) \"", (void *)str);
- s = JSSTRING_CHARS(str);
- for (i=0, n=JSSTRING_LENGTH(str); i < n; i++)
- fputc(s[i], stderr);
- fputc('"', stderr);
- fputc('\n', stderr);
-}
-
-void printVal(JSContext *cx, jsval val);
-
-void printObj(JSContext *cx, JSObject *jsobj) {
- jsuint i;
- jsval val;
- JSClass *clasp;
-
- fprintf(stderr, "object 0x%p\n", (void *)jsobj);
- clasp = OBJ_GET_CLASS(cx, jsobj);
- fprintf(stderr, "class 0x%p %s\n", (void *)clasp, clasp->name);
- for (i=0; i < jsobj->map->nslots; i++) {
- fprintf(stderr, "slot %3d ", i);
- val = jsobj->slots[i];
- if (JSVAL_IS_OBJECT(val))
- fprintf(stderr, "object 0x%p\n", (void *)JSVAL_TO_OBJECT(val));
- else
- printVal(cx, val);
- }
-}
-
-void printVal(JSContext *cx, jsval val) {
- fprintf(stderr, "val %d (0x%p) = ", (int)val, (void *)val);
- if (JSVAL_IS_NULL(val)) {
- fprintf(stderr, "null\n");
- } else if (JSVAL_IS_VOID(val)) {
- fprintf(stderr, "undefined\n");
- } else if (JSVAL_IS_OBJECT(val)) {
- printObj(cx, JSVAL_TO_OBJECT(val));
- } else if (JSVAL_IS_INT(val)) {
- fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val));
- } else if (JSVAL_IS_STRING(val)) {
- printString(JSVAL_TO_STRING(val));
- } else if (JSVAL_IS_DOUBLE(val)) {
- fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val));
- } else {
- JS_ASSERT(JSVAL_IS_BOOLEAN(val));
- fprintf(stderr, "(boolean) %s\n",
- JSVAL_TO_BOOLEAN(val) ? "true" : "false");
- }
- fflush(stderr);
-}
-
-void printId(JSContext *cx, jsid id) {
- fprintf(stderr, "id %d (0x%p) is ", (int)id, (void *)id);
- printVal(cx, ID_TO_VALUE(id));
-}
-
-void printAtom(JSAtom *atom) {
- printString(ATOM_TO_STRING(atom));
-}
-
-#endif
diff --git a/src/extension/script/js/jsobj.h b/src/extension/script/js/jsobj.h
deleted file mode 100644
index a523194db..000000000
--- a/src/extension/script/js/jsobj.h
+++ /dev/null
@@ -1,464 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsobj_h___
-#define jsobj_h___
-/*
- * JS object definitions.
- *
- * A JS object consists of a possibly-shared object descriptor containing
- * ordered property names, called the map; and a dense vector of property
- * values, called slots. The map/slot pointer pair is GC'ed, while the map
- * is reference counted and the slot vector is malloc'ed.
- */
-#include "jshash.h" /* Added by JSIFY */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-struct JSObjectMap {
- jsrefcount nrefs; /* count of all referencing objects */
- JSObjectOps *ops; /* high level object operation vtable */
- uint32 nslots; /* length of obj->slots vector */
- uint32 freeslot; /* index of next free obj->slots element */
-};
-
-/* Shorthand macros for frequently-made calls. */
-#if defined JS_THREADSAFE && defined DEBUG
-#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \
- (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
-#else
-#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \
- (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp)
-#endif
-#define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \
- (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp)
-#define OBJ_GET_PROPERTY(cx,obj,id,vp) \
- (obj)->map->ops->getProperty(cx,obj,id,vp)
-#define OBJ_SET_PROPERTY(cx,obj,id,vp) \
- (obj)->map->ops->setProperty(cx,obj,id,vp)
-#define OBJ_GET_ATTRIBUTES(cx,obj,id,prop,attrsp) \
- (obj)->map->ops->getAttributes(cx,obj,id,prop,attrsp)
-#define OBJ_SET_ATTRIBUTES(cx,obj,id,prop,attrsp) \
- (obj)->map->ops->setAttributes(cx,obj,id,prop,attrsp)
-#define OBJ_DELETE_PROPERTY(cx,obj,id,rval) \
- (obj)->map->ops->deleteProperty(cx,obj,id,rval)
-#define OBJ_DEFAULT_VALUE(cx,obj,hint,vp) \
- (obj)->map->ops->defaultValue(cx,obj,hint,vp)
-#define OBJ_ENUMERATE(cx,obj,enum_op,statep,idp) \
- (obj)->map->ops->enumerate(cx,obj,enum_op,statep,idp)
-#define OBJ_CHECK_ACCESS(cx,obj,id,mode,vp,attrsp) \
- (obj)->map->ops->checkAccess(cx,obj,id,mode,vp,attrsp)
-
-/* These four are time-optimized to avoid stub calls. */
-#define OBJ_THIS_OBJECT(cx,obj) \
- ((obj)->map->ops->thisObject \
- ? (obj)->map->ops->thisObject(cx,obj) \
- : (obj))
-#define OBJ_DROP_PROPERTY(cx,obj,prop) \
- ((obj)->map->ops->dropProperty \
- ? (obj)->map->ops->dropProperty(cx,obj,prop) \
- : (void)0)
-#define OBJ_GET_REQUIRED_SLOT(cx,obj,slot) \
- ((obj)->map->ops->getRequiredSlot \
- ? (obj)->map->ops->getRequiredSlot(cx, obj, slot) \
- : JSVAL_VOID)
-#define OBJ_SET_REQUIRED_SLOT(cx,obj,slot,v) \
- ((obj)->map->ops->setRequiredSlot \
- ? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v) \
- : (void)0)
-
-/*
- * In the original JS engine design, obj->slots pointed to a vector of length
- * JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object,
- * else of length obj->map->nslots. With the advent of JS_GetReservedSlot,
- * JS_SetReservedSlot, and JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h), the size
- * of the minimum length slots vector in the case where map is shared cannot
- * be constant. This length starts at JS_INITIAL_NSLOTS, but may advance to
- * include all the reserved slots.
- *
- * Therefore slots must be self-describing. Rather than tag its low order bit
- * (a bit is all we need) to distinguish initial length from reserved length,
- * we do "the BSTR thing": over-allocate slots by one jsval, and store the
- * *net* length (counting usable slots, which have non-negative obj->slots[]
- * indices) in obj->slots[-1]. All code that sets obj->slots must be aware of
- * this hack -- you have been warned, and jsobj.c has been updated!
- */
-struct JSObject {
- JSObjectMap *map;
- jsval *slots;
-};
-
-#define JSSLOT_PROTO 0
-#define JSSLOT_PARENT 1
-#define JSSLOT_CLASS 2
-#define JSSLOT_PRIVATE 3
-#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \
- ? JSSLOT_PRIVATE + 1 \
- : JSSLOT_CLASS + 1)
-
-#define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \
- + JSCLASS_RESERVED_SLOTS(clasp))
-
-#define JS_INITIAL_NSLOTS 5
-
-#ifdef DEBUG
-#define MAP_CHECK_SLOT(map,slot) \
- JS_ASSERT((uint32)slot < JS_MIN((map)->freeslot, (map)->nslots))
-#define OBJ_CHECK_SLOT(obj,slot) \
- MAP_CHECK_SLOT((obj)->map, slot)
-#else
-#define OBJ_CHECK_SLOT(obj,slot) ((void)0)
-#endif
-
-/* Fast macros for accessing obj->slots while obj is locked (if thread-safe). */
-#define LOCKED_OBJ_GET_SLOT(obj,slot) \
- (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot])
-#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \
- (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value))
-#define LOCKED_OBJ_GET_PROTO(obj) \
- JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO))
-#define LOCKED_OBJ_GET_CLASS(obj) \
- ((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS)))
-
-#ifdef JS_THREADSAFE
-
-/* Thread-safe functions and wrapper macros for accessing obj->slots. */
-#define OBJ_GET_SLOT(cx,obj,slot) \
- (OBJ_CHECK_SLOT(obj, slot), \
- (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \
- ? LOCKED_OBJ_GET_SLOT(obj, slot) \
- : js_GetSlotThreadSafe(cx, obj, slot))
-
-#define OBJ_SET_SLOT(cx,obj,slot,value) \
- (OBJ_CHECK_SLOT(obj, slot), \
- (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \
- ? (void) LOCKED_OBJ_SET_SLOT(obj, slot, value) \
- : js_SetSlotThreadSafe(cx, obj, slot, value))
-
-/*
- * If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a native
- * object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx),
- * to avoid needlessly switching from lock-free to lock-full scope when doing
- * GC on a different context from the last one to own the scope. The caller
- * in this case is probably a JSClass.mark function, e.g., fun_mark, or maybe
- * a finalizer.
- *
- * The GC runs only when all threads except the one on which the GC is active
- * are suspended at GC-safe points, so there is no hazard in directly accessing
- * obj->slots[slot] from the GC's thread, once rt->gcRunning has been set. See
- * jsgc.c for details.
- */
-#define THREAD_IS_RUNNING_GC(rt, thread) \
- ((rt)->gcRunning && (rt)->gcThread == (thread))
-
-#define CX_THREAD_IS_RUNNING_GC(cx) \
- THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread)
-
-#define GC_AWARE_GET_SLOT(cx, obj, slot) \
- ((OBJ_IS_NATIVE(obj) && CX_THREAD_IS_RUNNING_GC(cx)) \
- ? (obj)->slots[slot] \
- : OBJ_GET_SLOT(cx, obj, slot))
-
-#else /* !JS_THREADSAFE */
-
-#define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot)
-#define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value)
-#define GC_AWARE_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot)
-
-#endif /* !JS_THREADSAFE */
-
-/* Thread-safe proto, parent, and class access macros. */
-#define OBJ_GET_PROTO(cx,obj) \
- JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO))
-#define OBJ_SET_PROTO(cx,obj,proto) \
- OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto))
-
-#define OBJ_GET_PARENT(cx,obj) \
- JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT))
-#define OBJ_SET_PARENT(cx,obj,parent) \
- OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent))
-
-#define OBJ_GET_CLASS(cx,obj) \
- ((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS)))
-
-/* Test whether a map or object is native. */
-#define MAP_IS_NATIVE(map) \
- ((map)->ops == &js_ObjectOps || \
- ((map)->ops && (map)->ops->newObjectMap == js_ObjectOps.newObjectMap))
-
-#define OBJ_IS_NATIVE(obj) MAP_IS_NATIVE((obj)->map)
-
-extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
-extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
-extern JSClass js_ObjectClass;
-extern JSClass js_WithClass;
-
-struct JSSharpObjectMap {
- jsrefcount depth;
- jsatomid sharpgen;
- JSHashTable *table;
-};
-
-#define SHARP_BIT ((jsatomid) 1)
-#define BUSY_BIT ((jsatomid) 2)
-#define SHARP_ID_SHIFT 2
-#define IS_SHARP(he) ((jsatomid)(he)->value & SHARP_BIT)
-#define MAKE_SHARP(he) ((he)->value = (void*)((jsatomid)(he)->value|SHARP_BIT))
-#define IS_BUSY(he) ((jsatomid)(he)->value & BUSY_BIT)
-#define MAKE_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value|BUSY_BIT))
-#define CLEAR_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value&~BUSY_BIT))
-
-extern JSHashEntry *
-js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
- jschar **sp);
-
-extern void
-js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
-
-extern JSBool
-js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-extern JSBool
-js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-extern JSObject *
-js_InitObjectClass(JSContext *cx, JSObject *obj);
-
-/* Select Object.prototype method names shared between jsapi.c and jsobj.c. */
-extern const char js_watch_str[];
-extern const char js_unwatch_str[];
-extern const char js_hasOwnProperty_str[];
-extern const char js_isPrototypeOf_str[];
-extern const char js_propertyIsEnumerable_str[];
-extern const char js_defineGetter_str[];
-extern const char js_defineSetter_str[];
-extern const char js_lookupGetter_str[];
-extern const char js_lookupSetter_str[];
-
-extern void
-js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
- JSClass *clasp);
-
-extern JSObjectMap *
-js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
- JSClass *clasp, JSObject *obj);
-
-extern void
-js_DestroyObjectMap(JSContext *cx, JSObjectMap *map);
-
-extern JSObjectMap *
-js_HoldObjectMap(JSContext *cx, JSObjectMap *map);
-
-extern JSObjectMap *
-js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj);
-
-extern JSObject *
-js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
-
-extern JSObject *
-js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
- JSObject *parent, uintN argc, jsval *argv);
-
-extern void
-js_FinalizeObject(JSContext *cx, JSObject *obj);
-
-extern JSBool
-js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
-
-extern void
-js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot);
-
-/*
- * Find or create a property named by id in obj's scope, with the given getter
- * and setter, slot, attributes, and other members.
- */
-extern JSScopeProperty *
-js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
- JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
- uintN attrs, uintN flags, intN shortid);
-
-/*
- * Change sprop to have the given attrs, getter, and setter in scope, morphing
- * it into a potentially new JSScopeProperty. Return a pointer to the changed
- * or identical property.
- */
-extern JSScopeProperty *
-js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
- JSScopeProperty *sprop, uintN attrs, uintN mask,
- JSPropertyOp getter, JSPropertyOp setter);
-
-/*
- * On error, return false. On success, if propp is non-null, return true with
- * obj locked and with a held property in *propp; if propp is null, return true
- * but release obj's lock first. Therefore all callers who pass non-null propp
- * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to
- * drop the held property, and to release the lock on obj.
- */
-extern JSBool
-js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- JSProperty **propp);
-
-extern JSBool
-js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
- JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN shortid, JSProperty **propp);
-
-/*
- * Unlike js_DefineProperty, propp must be non-null. On success, and if id was
- * found, return true with *objp non-null and locked, and with a held property
- * stored in *propp. If successful but id was not found, return true with both
- * *objp and *propp null. Therefore all callers who receive a non-null *propp
- * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp).
- */
-#if defined JS_THREADSAFE && defined DEBUG
-extern JS_FRIEND_API(JSBool)
-_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
- JSProperty **propp, const char *file, uintN line);
-
-#define js_LookupProperty(cx,obj,id,objp,propp) \
- _js_LookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
-#else
-extern JS_FRIEND_API(JSBool)
-js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
- JSProperty **propp);
-#endif
-
-extern JS_FRIEND_API(JSBool)
-js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
- JSProperty **propp);
-
-extern JSObject *
-js_FindIdentifierBase(JSContext *cx, jsid id);
-
-extern JSObject *
-js_FindVariableScope(JSContext *cx, JSFunction **funp);
-
-extern JSBool
-js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
-
-extern JSBool
-js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
-
-extern JSBool
-js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp);
-
-extern JSBool
-js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
- uintN *attrsp);
-
-extern JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval);
-
-extern JSBool
-js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
-
-extern JSIdArray *
-js_NewIdArray(JSContext *cx, jsint length);
-
-extern JSIdArray *
-js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length);
-
-extern JSBool
-js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
- jsval *statep, jsid *idp);
-
-extern JSBool
-js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
- jsval *vp, uintN *attrsp);
-
-extern JSBool
-js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
-
-extern JSBool
-js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-extern JSBool
-js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
-
-extern JSBool
-js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj);
-
-extern JSBool
-js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
-
-extern JSBool
-js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop);
-
-extern JSBool
-js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
- uintN attrs);
-
-extern JSBool
-js_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
-
-extern JSObject *
-js_ValueToNonNullObject(JSContext *cx, jsval v);
-
-extern JSBool
-js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval);
-
-extern JSBool
-js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
- uintN argc, jsval *argv, jsval *rval);
-
-extern JSBool
-js_XDRObject(JSXDRState *xdr, JSObject **objp);
-
-extern uint32
-js_Mark(JSContext *cx, JSObject *obj, void *arg);
-
-extern void
-js_Clear(JSContext *cx, JSObject *obj);
-
-extern jsval
-js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot);
-
-extern void
-js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v);
-
-JS_END_EXTERN_C
-
-#endif /* jsobj_h___ */
diff --git a/src/extension/script/js/jsopcode.c b/src/extension/script/js/jsopcode.c
deleted file mode 100644
index 166f602d5..000000000
--- a/src/extension/script/js/jsopcode.c
+++ /dev/null
@@ -1,2660 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS bytecode descriptors, disassemblers, and decompilers.
- */
-#include "jsstddef.h"
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsdtoa.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jslock.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-const char js_const_str[] = "const";
-const char js_var_str[] = "var";
-const char js_function_str[] = "function";
-const char js_in_str[] = "in";
-const char js_instanceof_str[] = "instanceof";
-const char js_new_str[] = "new";
-const char js_delete_str[] = "delete";
-const char js_typeof_str[] = "typeof";
-const char js_void_str[] = "void";
-const char js_null_str[] = "null";
-const char js_this_str[] = "this";
-const char js_false_str[] = "false";
-const char js_true_str[] = "true";
-
-const char *js_incop_str[] = {"++", "--"};
-
-/* Pollute the namespace locally for MSVC Win16, but not for WatCom. */
-#ifdef __WINDOWS_386__
- #ifdef FAR
- #undef FAR
- #endif
-#else /* !__WINDOWS_386__ */
-#ifndef FAR
-#define FAR
-#endif
-#endif /* !__WINDOWS_386__ */
-
-const JSCodeSpec FAR js_CodeSpec[] = {
-#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
- {name,token,length,nuses,ndefs,prec,format},
-#include "jsopcode.tbl"
-#undef OPDEF
-};
-
-uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0];
-
-/************************************************************************/
-
-static ptrdiff_t
-GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
-{
- uint32 type;
-
- type = (js_CodeSpec[*pc].format & JOF_TYPEMASK);
- if (JOF_TYPE_IS_EXTENDED_JUMP(type))
- return GET_JUMPX_OFFSET(pc2);
- return GET_JUMP_OFFSET(pc2);
-}
-
-#ifdef DEBUG
-
-JS_FRIEND_API(void)
-js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp)
-{
- jsbytecode *pc, *end;
- uintN len;
-
- pc = script->code;
- end = pc + script->length;
- while (pc < end) {
- if (pc == script->main)
- fputs("main:\n", fp);
- len = js_Disassemble1(cx, script, pc,
- PTRDIFF(pc, script->code, jsbytecode),
- lines, fp);
- if (!len)
- return;
- pc += len;
- }
-}
-
-JS_FRIEND_API(uintN)
-js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
- JSBool lines, FILE *fp)
-{
- JSOp op;
- const JSCodeSpec *cs;
- intN len, off;
- JSAtom *atom;
- JSString *str;
- char *cstr;
-
- op = (JSOp)*pc;
- if (op >= JSOP_LIMIT) {
- char numBuf1[12], numBuf2[12];
- JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
- JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
- return 0;
- }
- cs = &js_CodeSpec[op];
- len = (intN)cs->length;
- fprintf(fp, "%05u:", loc);
- if (lines)
- fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
- fprintf(fp, " %s", cs->name);
- switch (cs->format & JOF_TYPEMASK) {
- case JOF_BYTE:
- if (op == JSOP_TRAP) {
- op = JS_GetTrapOpcode(cx, script, pc);
- if (op == JSOP_LIMIT)
- return 0;
- len = (intN)js_CodeSpec[op].length;
- }
- break;
-
- case JOF_JUMP:
- case JOF_JUMPX:
- off = GetJumpOffset(pc, pc);
- fprintf(fp, " %u (%d)", loc + off, off);
- break;
-
- case JOF_CONST:
- atom = GET_ATOM(cx, script, pc);
- str = js_ValueToSource(cx, ATOM_KEY(atom));
- if (!str)
- return 0;
- cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
- if (!cstr)
- return 0;
- fprintf(fp, " %s", cstr);
- JS_free(cx, cstr);
- break;
-
- case JOF_UINT16:
- fprintf(fp, " %u", GET_ARGC(pc));
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JOF_TABLESWITCH:
- {
- jsbytecode *pc2;
- jsint i, low, high;
-
- pc2 = pc;
- off = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- low = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- high = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
- for (i = low; i <= high; i++) {
- off = GetJumpOffset(pc, pc2);
- fprintf(fp, "\n\t%d: %d", i, off);
- pc2 += JUMP_OFFSET_LEN;
- }
- len = 1 + pc2 - pc;
- break;
- }
-
- case JOF_LOOKUPSWITCH:
- {
- jsbytecode *pc2;
- jsint npairs;
-
- pc2 = pc;
- off = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- npairs = (jsint) GET_ATOM_INDEX(pc2);
- pc2 += ATOM_INDEX_LEN;
- fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
- while (npairs) {
- atom = GET_ATOM(cx, script, pc2);
- pc2 += ATOM_INDEX_LEN;
- off = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
-
- str = js_ValueToSource(cx, ATOM_KEY(atom));
- if (!str)
- return 0;
- cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
- JSSTRING_LENGTH(str));
- if (!cstr)
- return 0;
- fprintf(fp, "\n\t%s: %d", cstr, off);
- JS_free(cx, cstr);
- npairs--;
- }
- len = 1 + pc2 - pc;
- break;
- }
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
- case JOF_QARG:
- fprintf(fp, " %u", GET_ARGNO(pc));
- break;
-
- case JOF_QVAR:
- fprintf(fp, " %u", GET_VARNO(pc));
- break;
-
-#if JS_HAS_LEXICAL_CLOSURE
- case JOF_DEFLOCALVAR:
- fprintf(fp, " %u", GET_VARNO(pc));
- pc += VARNO_LEN;
- atom = GET_ATOM(cx, script, pc);
- str = js_ValueToSource(cx, ATOM_KEY(atom));
- if (!str)
- return 0;
- cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
- if (!cstr)
- return 0;
- fprintf(fp, " %s", cstr);
- JS_free(cx, cstr);
- break;
-#endif
-
- default: {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_UNKNOWN_FORMAT, numBuf);
- return 0;
- }
- }
- fputs("\n", fp);
- return len;
-}
-
-#endif /* DEBUG */
-
-/************************************************************************/
-
-/*
- * Sprintf, but with unlimited and automatically allocated buffering.
- */
-typedef struct Sprinter {
- JSContext *context; /* context executing the decompiler */
- JSArenaPool *pool; /* string allocation pool */
- char *base; /* base address of buffer in pool */
- size_t size; /* size of buffer allocated at base */
- ptrdiff_t offset; /* offset of next free char in buffer */
-} Sprinter;
-
-#define INIT_SPRINTER(cx, sp, ap, off) \
- ((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0, \
- (sp)->offset = off)
-
-#define OFF2STR(sp,off) ((sp)->base + (off))
-#define STR2OFF(sp,str) ((str) - (sp)->base)
-#define RETRACT(sp,str) ((sp)->offset = STR2OFF(sp, str))
-
-static JSBool
-SprintAlloc(Sprinter *sp, size_t nb)
-{
- if (!sp->base) {
- JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb);
- } else {
- JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb);
- }
- if (!sp->base) {
- JS_ReportOutOfMemory(sp->context);
- return JS_FALSE;
- }
- sp->size += nb;
- return JS_TRUE;
-}
-
-static ptrdiff_t
-SprintPut(Sprinter *sp, const char *s, size_t len)
-{
- ptrdiff_t nb, offset;
- char *bp;
-
- /* Allocate space for s, including the '\0' at the end. */
- nb = (sp->offset + len + 1) - sp->size;
- if (nb > 0 && !SprintAlloc(sp, nb))
- return -1;
-
- /* Advance offset and copy s into sp's buffer. */
- offset = sp->offset;
- sp->offset += len;
- bp = sp->base + offset;
- memmove(bp, s, len);
- bp[len] = 0;
- return offset;
-}
-
-static ptrdiff_t
-Sprint(Sprinter *sp, const char *format, ...)
-{
- va_list ap;
- char *bp;
- ptrdiff_t offset;
-
- va_start(ap, format);
- bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */
- va_end(ap);
- if (!bp) {
- JS_ReportOutOfMemory(sp->context);
- return -1;
- }
- offset = SprintPut(sp, bp, strlen(bp));
- free(bp);
- return offset;
-}
-
-const jschar js_EscapeMap[] = {
- '\b', 'b',
- '\f', 'f',
- '\n', 'n',
- '\r', 'r',
- '\t', 't',
- '\v', 'v',
- '"', '"',
- '\'', '\'',
- '\\', '\\',
- 0
-};
-
-static char *
-QuoteString(Sprinter *sp, JSString *str, jschar quote)
-{
- ptrdiff_t off, len, nb;
- const jschar *s, *t, *u, *z;
- char *bp;
- jschar c;
- JSBool ok;
-
- /* Sample off first for later return value pointer computation. */
- off = sp->offset;
- if (quote && Sprint(sp, "%c", (char)quote) < 0)
- return NULL;
-
- /* Loop control variables: z points at end of string sentinel. */
- s = JSSTRING_CHARS(str);
- z = s + JSSTRING_LENGTH(str);
- for (t = s; t < z; s = ++t) {
- /* Move t forward from s past un-quote-worthy characters. */
- c = *t;
- while (JS_ISPRINT(c) && c != quote && c != '\\' && !(c >> 8)) {
- c = *++t;
- if (t == z)
- break;
- }
- len = PTRDIFF(t, s, jschar);
-
- /* Allocate space for s, including the '\0' at the end. */
- nb = (sp->offset + len + 1) - sp->size;
- if (nb > 0 && !SprintAlloc(sp, nb))
- return NULL;
-
- /* Advance sp->offset and copy s into sp's buffer. */
- bp = sp->base + sp->offset;
- sp->offset += len;
- while (--len >= 0)
- *bp++ = (char) *s++;
- *bp = '\0';
-
- if (t == z)
- break;
-
- /* Use js_EscapeMap, \u, or \x only if necessary. */
- if ((u = js_strchr(js_EscapeMap, c)) != NULL)
- ok = Sprint(sp, "\\%c", (char)u[1]) >= 0;
- else
- ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
- if (!ok)
- return NULL;
- }
-
- /* Sprint the closing quote and return the quoted string. */
- if (quote && Sprint(sp, "%c", (char)quote) < 0)
- return NULL;
- return OFF2STR(sp, off);
-}
-
-JSString *
-js_QuoteString(JSContext *cx, JSString *str, jschar quote)
-{
- void *mark;
- Sprinter sprinter;
- char *bytes;
- JSString *escstr;
-
- mark = JS_ARENA_MARK(&cx->tempPool);
- INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);
- bytes = QuoteString(&sprinter, str, quote);
- escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL;
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return escstr;
-}
-
-/************************************************************************/
-
-struct JSPrinter {
- Sprinter sprinter; /* base class state */
- JSArenaPool pool; /* string allocation pool */
- uintN indent; /* indentation in spaces */
- JSBool pretty; /* pretty-print: indent, use newlines */
- JSScript *script; /* script being printed */
- JSScope *scope; /* script function scope */
-};
-
-JSPrinter *
-js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty)
-{
- JSPrinter *jp;
- JSStackFrame *fp;
- JSObjectMap *map;
-
- jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter));
- if (!jp)
- return NULL;
- INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
- JS_InitArenaPool(&jp->pool, name, 256, 1);
- jp->indent = indent;
- jp->pretty = pretty;
- jp->script = NULL;
- jp->scope = NULL;
- fp = cx->fp;
- if (fp && fp->fun && fp->fun->object) {
- map = fp->fun->object->map;
- if (MAP_IS_NATIVE(map))
- jp->scope = (JSScope *)map;
- }
- return jp;
-}
-
-void
-js_DestroyPrinter(JSPrinter *jp)
-{
- JS_FinishArenaPool(&jp->pool);
- JS_free(jp->sprinter.context, jp);
-}
-
-JSString *
-js_GetPrinterOutput(JSPrinter *jp)
-{
- JSContext *cx;
- JSString *str;
-
- cx = jp->sprinter.context;
- if (!jp->sprinter.base)
- return cx->runtime->emptyString;
- str = JS_NewStringCopyZ(cx, jp->sprinter.base);
- if (!str)
- return NULL;
- JS_FreeArenaPool(&jp->pool);
- INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
- return str;
-}
-
-int
-js_printf(JSPrinter *jp, const char *format, ...)
-{
- va_list ap;
- char *bp, *fp;
- int cc;
-
- if (*format == '\0')
- return 0;
-
- va_start(ap, format);
-
- /* If pretty-printing, expand magic tab into a run of jp->indent spaces. */
- if (*format == '\t') {
- if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)
- return -1;
- format++;
- }
-
- /* Suppress newlines (must be once per format, at the end) if not pretty. */
- fp = NULL;
- if (!jp->pretty && format[cc = strlen(format)-1] == '\n') {
- fp = JS_strdup(jp->sprinter.context, format);
- if (!fp)
- return -1;
- fp[cc] = '\0';
- format = fp;
- }
-
- /* Allocate temp space, convert format, and put. */
- bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */
- if (fp) {
- JS_free(jp->sprinter.context, fp);
- format = NULL;
- }
- if (!bp) {
- JS_ReportOutOfMemory(jp->sprinter.context);
- return -1;
- }
-
- cc = strlen(bp);
- if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)
- cc = -1;
- free(bp);
-
- va_end(ap);
- return cc;
-}
-
-JSBool
-js_puts(JSPrinter *jp, const char *s)
-{
- return SprintPut(&jp->sprinter, s, strlen(s)) >= 0;
-}
-
-/************************************************************************/
-
-typedef struct SprintStack {
- Sprinter sprinter; /* sprinter for postfix to infix buffering */
- ptrdiff_t *offsets; /* stack of postfix string offsets */
- jsbytecode *opcodes; /* parallel stack of JS opcodes */
- uintN top; /* top of stack index */
- JSPrinter *printer; /* permanent output goes here */
-} SprintStack;
-
-/* Gap between stacked strings to allow for insertion of parens and commas. */
-#define PAREN_SLOP (2 + 1)
-
-/*
- * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME,
- * JSOP_SETPROP, and JSOP_SETELEM, respectively. See the first assertion in
- * PushOff.
- */
-#define JSOP_GETPROP2 254
-#define JSOP_GETELEM2 255
-
-static JSBool
-PushOff(SprintStack *ss, ptrdiff_t off, JSOp op)
-{
- uintN top;
-
-#if JSOP_LIMIT > JSOP_GETPROP2
-#error JSOP_LIMIT must be <= JSOP_GETPROP2
-#endif
- if (!SprintAlloc(&ss->sprinter, PAREN_SLOP))
- return JS_FALSE;
-
- /* ss->top points to the next free slot; be paranoid about overflow. */
- top = ss->top;
- JS_ASSERT(top < ss->printer->script->depth);
- if (top >= ss->printer->script->depth) {
- JS_ReportOutOfMemory(ss->sprinter.context);
- return JS_FALSE;
- }
-
- /* The opcodes stack must contain real bytecodes that index js_CodeSpec. */
- ss->offsets[top] = off;
- ss->opcodes[top] = (op == JSOP_GETPROP2) ? JSOP_GETPROP
- : (op == JSOP_GETELEM2) ? JSOP_GETELEM
- : (jsbytecode) op;
- ss->top = ++top;
- ss->sprinter.offset += PAREN_SLOP;
- return JS_TRUE;
-}
-
-static ptrdiff_t
-PopOff(SprintStack *ss, JSOp op)
-{
- uintN top;
- const JSCodeSpec *cs, *topcs;
- ptrdiff_t off;
-
- /* ss->top points to the next free slot; be paranoid about underflow. */
- top = ss->top;
- JS_ASSERT(top != 0);
- if (top == 0)
- return 0;
-
- ss->top = --top;
- topcs = &js_CodeSpec[ss->opcodes[top]];
- cs = &js_CodeSpec[op];
- if (topcs->prec != 0 && topcs->prec < cs->prec) {
- ss->offsets[top] -= 2;
- ss->sprinter.offset = ss->offsets[top];
- off = Sprint(&ss->sprinter, "(%s)",
- OFF2STR(&ss->sprinter, ss->sprinter.offset + 2));
- } else {
- off = ss->sprinter.offset = ss->offsets[top];
- }
- return off;
-}
-
-#if JS_HAS_SWITCH_STATEMENT
-typedef struct TableEntry {
- jsval key;
- ptrdiff_t offset;
-} TableEntry;
-
-static int
-CompareOffsets(const void *v1, const void *v2, void *arg)
-{
- const TableEntry *te1 = (const TableEntry *) v1,
- *te2 = (const TableEntry *) v2;
-
- return te1->offset - te2->offset;
-}
-
-static JSBool
-Decompile(SprintStack *ss, jsbytecode *pc, intN nb);
-
-static JSBool
-DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
- jsbytecode *pc, ptrdiff_t switchLength,
- ptrdiff_t defaultOffset, JSBool isCondSwitch)
-{
- JSContext *cx;
- JSPrinter *jp;
- char *lval, *rval;
- uintN i;
- ptrdiff_t diff, off, off2, caseExprOff;
- jsval key;
- JSString *str;
-
- cx = ss->sprinter.context;
- jp = ss->printer;
-
- lval = OFF2STR(&ss->sprinter, PopOff(ss, JSOP_NOP));
- js_printf(jp, "\tswitch (%s) {\n", lval);
-
- if (tableLength) {
- diff = table[0].offset - defaultOffset;
- if (diff > 0) {
- jp->indent += 2;
- js_printf(jp, "\tdefault:\n");
- jp->indent += 2;
- if (!Decompile(ss, pc + defaultOffset, diff))
- return JS_FALSE;
- jp->indent -= 4;
- }
-
- caseExprOff = isCondSwitch
- ? (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length
- : 0;
-
- for (i = 0; i < tableLength; i++) {
- off = table[i].offset;
- if (i + 1 < tableLength)
- off2 = table[i + 1].offset;
- else
- off2 = switchLength;
-
- key = table[i].key;
- if (isCondSwitch) {
- ptrdiff_t nextCaseExprOff;
-
- /*
- * key encodes the JSOP_CASE bytecode's offset from switchtop.
- * The next case expression follows immediately, unless we are
- * at the last case.
- */
- nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);
- nextCaseExprOff += js_CodeSpec[pc[nextCaseExprOff]].length;
- jp->indent += 2;
- if (!Decompile(ss, pc + caseExprOff,
- nextCaseExprOff - caseExprOff)) {
- return JS_FALSE;
- }
- caseExprOff = nextCaseExprOff;
- } else {
- /*
- * key comes from an atom, not the decompiler, so we need to
- * quote it if it's a string literal.
- */
- str = js_ValueToString(cx, key);
- if (!str)
- return JS_FALSE;
- jp->indent += 2;
- if (JSVAL_IS_STRING(key)) {
- rval = QuoteString(&ss->sprinter, str, (jschar)'"');
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- } else {
- rval = JS_GetStringBytes(str);
- }
- js_printf(jp, "\tcase %s:\n", rval);
- }
-
- jp->indent += 2;
- if (off <= defaultOffset && defaultOffset < off2) {
- diff = defaultOffset - off;
- if (diff != 0) {
- if (!Decompile(ss, pc + off, diff))
- return JS_FALSE;
- off = defaultOffset;
- }
- jp->indent -= 2;
- js_printf(jp, "\tdefault:\n");
- jp->indent += 2;
- }
- if (!Decompile(ss, pc + off, off2 - off))
- return JS_FALSE;
- jp->indent -= 4;
- }
- }
-
- if (defaultOffset == switchLength) {
- jp->indent += 2;
- js_printf(jp, "\tdefault:\n");
- jp->indent -= 2;
- }
- js_printf(jp, "\t}\n");
- return JS_TRUE;
-}
-#endif
-
-static JSAtom *
-GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot)
-{
- JSScope *scope;
- JSScopeProperty *sprop;
- JSObject *obj, *proto;
-
- scope = jp->scope;
- while (scope) {
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (sprop->getter != getter)
- continue;
- JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
- JS_ASSERT(!JSVAL_IS_INT(sprop->id));
- if ((uintN) sprop->shortid == slot)
- return (JSAtom *) sprop->id;
- }
- obj = scope->object;
- if (!obj)
- break;
- proto = OBJ_GET_PROTO(jp->sprinter.context, obj);
- if (!proto)
- break;
- scope = OBJ_SCOPE(proto);
- }
- return NULL;
-}
-
-static const char *
-VarPrefix(jssrcnote *sn)
-{
- const char *kw;
- static char buf[8];
-
- kw = NULL;
- if (sn) {
- if (SN_TYPE(sn) == SRC_VAR)
- kw = js_var_str;
- else if (SN_TYPE(sn) == SRC_CONST)
- kw = js_const_str;
- }
- if (!kw)
- return "";
- JS_snprintf(buf, sizeof buf, "%s ", kw);
- return buf;
-}
-
-static JSBool
-Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
-{
- JSContext *cx;
- JSPrinter *jp, *jp2;
- jsbytecode *endpc, *done, *forelem_tail, *forelem_done;
- ptrdiff_t len, todo, oplen, cond, next, tail;
- JSOp op, lastop, saveop;
- const JSCodeSpec *cs, *topcs;
- jssrcnote *sn, *sn2;
- const char *lval, *rval, *xval, *fmt;
- jsint i, argc;
- char **argv;
- JSAtom *atom;
- JSObject *obj;
- JSFunction *fun;
- JSString *str;
- JSBool ok;
- jsval val;
-
-/*
- * Local macros
- */
-#define DECOMPILE_CODE(pc,nb) if (!Decompile(ss, pc, nb)) return JS_FALSE
-#define POP_STR() OFF2STR(&ss->sprinter, PopOff(ss, op))
-#define LOCAL_ASSERT(expr) JS_ASSERT(expr); if (!(expr)) return JS_FALSE
-
-/*
- * Get atom from script's atom map, quote/escape its string appropriately into
- * rval, and select fmt from the quoted and unquoted alternatives.
- */
-#define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval) \
- JS_BEGIN_MACRO \
- jschar quote_; \
- atom = GET_ATOM(cx, jp->script, pc); \
- if (ATOM_KEYWORD(atom)) { \
- quote_ = '\''; \
- fmt = qfmt; \
- } else { \
- quote_ = 0; \
- fmt = ufmt; \
- } \
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_); \
- if (!rval) \
- return JS_FALSE; \
- JS_END_MACRO
-
- cx = ss->sprinter.context;
- jp = ss->printer;
- endpc = pc + nb;
- forelem_tail = forelem_done = NULL;
- todo = -2; /* NB: different from Sprint() error return. */
- tail = -1;
- op = JSOP_NOP;
- sn = NULL;
- rval = NULL;
-
- while (pc < endpc) {
- lastop = op;
- op = saveop = (JSOp) *pc;
- if (op >= JSOP_LIMIT) {
- switch (op) {
- case JSOP_GETPROP2:
- saveop = JSOP_GETPROP;
- break;
- case JSOP_GETELEM2:
- saveop = JSOP_GETELEM;
- break;
- default:;
- }
- }
- cs = &js_CodeSpec[saveop];
- len = oplen = cs->length;
-
- if (cs->token) {
- switch (cs->nuses) {
- case 2:
- rval = POP_STR();
- lval = POP_STR();
- sn = js_GetSrcNote(jp->script, pc);
- if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
- /* Print only the right operand of the assignment-op. */
- todo = SprintPut(&ss->sprinter, rval, strlen(rval));
- } else {
- todo = Sprint(&ss->sprinter, "%s %s %s",
- lval, cs->token, rval);
- }
- break;
-
- case 1:
- rval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);
- break;
-
- case 0:
-#if JS_HAS_GETTER_SETTER
- if (op == JSOP_GETTER || op == JSOP_SETTER) {
- todo = -2;
- break;
- }
-#endif
- todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));
- break;
-
- default:
- todo = -2;
- break;
- }
- } else {
- switch (op) {
- case JSOP_NOP:
- /*
- * Check for a do-while loop, a for-loop with an empty
- * initializer part, a labeled statement, a function
- * definition, or try/finally.
- */
- sn = js_GetSrcNote(jp->script, pc);
- todo = -2;
- switch (sn ? SN_TYPE(sn) : SRC_NULL) {
-#if JS_HAS_DO_WHILE_LOOP
- case SRC_WHILE:
- js_printf(jp, "\tdo {\n");
- jp->indent += 4;
- break;
-#endif /* JS_HAS_DO_WHILE_LOOP */
-
- case SRC_FOR:
- rval = "";
-
- do_forloop:
- /* Skip the JSOP_NOP or JSOP_POP bytecode. */
- pc++;
-
- /* Get the cond, next, and loop-closing tail offsets. */
- cond = js_GetSrcNoteOffset(sn, 0);
- next = js_GetSrcNoteOffset(sn, 1);
- tail = js_GetSrcNoteOffset(sn, 2);
- LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
-
- /* Print the keyword and the possibly empty init-part. */
- js_printf(jp, "\tfor (%s;", rval);
-
- if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
- /* Decompile the loop condition. */
- DECOMPILE_CODE(pc, cond);
- js_printf(jp, " %s", POP_STR());
- }
-
- /* Need a semicolon whether or not there was a cond. */
- js_puts(jp, ";");
-
- if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
- /* Decompile the loop updater. */
- DECOMPILE_CODE(pc + next, tail - next - 1);
- js_printf(jp, " %s", POP_STR());
- }
-
- /* Do the loop body. */
- js_puts(jp, ") {\n");
- jp->indent += 4;
- oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
- DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
-
- /* Set len so pc skips over the entire loop. */
- len = tail + js_CodeSpec[pc[tail]].length;
- break;
-
- case SRC_LABEL:
- atom = js_GetAtom(cx, &jp->script->atomMap,
- (jsatomid) js_GetSrcNoteOffset(sn, 0));
- jp->indent -= 4;
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "\t%s:\n", rval);
- jp->indent += 4;
- break;
-
- case SRC_LABELBRACE:
- atom = js_GetAtom(cx, &jp->script->atomMap,
- (jsatomid) js_GetSrcNoteOffset(sn, 0));
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "\t%s: {\n", rval);
- jp->indent += 4;
- break;
-
- case SRC_ENDBRACE:
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
- break;
-
- case SRC_CATCH:
- jp->indent -= 4;
- sn = js_GetSrcNote(jp->script, pc);
- pc += oplen;
- js_printf(jp, "\t} catch (");
-
- LOCAL_ASSERT(*pc == JSOP_NAME);
- pc += js_CodeSpec[JSOP_NAME].length;
- LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);
- pc += js_CodeSpec[JSOP_PUSHOBJ].length;
- LOCAL_ASSERT(*pc == JSOP_NEWINIT);
- pc += js_CodeSpec[JSOP_NEWINIT].length;
- LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
- pc += js_CodeSpec[JSOP_EXCEPTION].length;
- LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);
- atom = GET_ATOM(cx, jp->script, pc);
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "%s", rval);
- pc += js_CodeSpec[JSOP_INITCATCHVAR].length;
- LOCAL_ASSERT(*pc == JSOP_ENTERWITH);
- pc += js_CodeSpec[JSOP_ENTERWITH].length;
-
- len = js_GetSrcNoteOffset(sn, 0);
- if (len) {
- js_printf(jp, " if ");
- DECOMPILE_CODE(pc, len);
- js_printf(jp, "%s", POP_STR());
- pc += len;
- LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
- pc += js_CodeSpec[*pc].length;
- }
-
- js_printf(jp, ") {\n");
- jp->indent += 4;
- len = 0;
- break;
-
- case SRC_FUNCDEF:
- atom = js_GetAtom(cx, &jp->script->atomMap,
- (jsatomid) js_GetSrcNoteOffset(sn, 0));
- JS_ASSERT(ATOM_IS_OBJECT(atom));
- do_function:
- obj = ATOM_TO_OBJECT(atom);
- fun = (JSFunction *) JS_GetPrivate(cx, obj);
- jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),
- jp->indent, jp->pretty);
- if (!jp2)
- return JS_FALSE;
- jp2->scope = jp->scope;
- if (js_DecompileFunction(jp2, fun)) {
- str = js_GetPrinterOutput(jp2);
- if (str)
- js_printf(jp, "%s\n", JS_GetStringBytes(str));
- }
- js_DestroyPrinter(jp2);
- break;
-
- default:;
- }
- case JSOP_RETRVAL:
- break;
-
- case JSOP_GROUP:
- /* Use last real op so PopOff adds parens if needed. */
- todo = PopOff(ss, lastop);
-
- /* Now add user-supplied parens only if PopOff did not. */
- cs = &js_CodeSpec[lastop];
- topcs = &js_CodeSpec[ss->opcodes[ss->top]];
- if (topcs->prec >= cs->prec) {
- todo = Sprint(&ss->sprinter, "(%s)",
- OFF2STR(&ss->sprinter, todo));
- }
- break;
-
- case JSOP_PUSH:
- case JSOP_PUSHOBJ:
- case JSOP_BINDNAME:
- todo = Sprint(&ss->sprinter, "");
- break;
-
-#if JS_HAS_EXCEPTIONS
- case JSOP_TRY:
- js_printf(jp, "\ttry {\n");
- jp->indent += 4;
- todo = -2;
- break;
-
- {
- static const char finally_cookie[] = "finally-cookie";
-
- case JSOP_FINALLY:
- jp->indent -= 4;
- js_printf(jp, "\t} finally {\n");
- jp->indent += 4;
-
- /*
- * We must push an empty string placeholder for gosub's return
- * address, popped by JSOP_RETSUB and counted by script->depth
- * but not by ss->top (see JSOP_SETSP, below).
- */
- todo = Sprint(&ss->sprinter, finally_cookie);
- break;
-
- case JSOP_RETSUB:
- rval = POP_STR();
- LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0);
- todo = -2;
- break;
- }
-
- case JSOP_SWAP:
- /*
- * We don't generate this opcode currently, and previously we
- * did not need to decompile it. If old, serialized bytecode
- * uses it still, we should fall through and set todo = -2.
- */
- /* FALL THROUGH */
-
- case JSOP_GOSUB:
- case JSOP_GOSUBX:
- /*
- * JSOP_GOSUB and GOSUBX have no effect on the decompiler's
- * string stack because the next op in bytecode order finds
- * the stack balanced by a JSOP_RETSUB executed elsewhere.
- */
- todo = -2;
- break;
-
- case JSOP_SETSP:
- /*
- * The compiler models operand stack depth and fixes the stack
- * pointer on entry to a catch clause based on its depth model.
- * The decompiler must match the code generator's model, which
- * is why JSOP_FINALLY pushes a cookie that JSOP_RETSUB pops.
- */
- ss->top = (uintN) GET_ATOM_INDEX(pc);
- break;
-
- case JSOP_EXCEPTION:
- /*
- * The only other JSOP_EXCEPTION case occurs as part of a code
- * sequence that follows a SRC_CATCH-annotated JSOP_NOP.
- */
- sn = js_GetSrcNote(jp->script, pc);
- LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);
- todo = -2;
- break;
-#endif /* JS_HAS_EXCEPTIONS */
-
- case JSOP_POP:
- case JSOP_POPV:
- sn = js_GetSrcNote(jp->script, pc);
- switch (sn ? SN_TYPE(sn) : SRC_NULL) {
- case SRC_FOR:
- rval = POP_STR();
- todo = -2;
- goto do_forloop;
-
- case SRC_PCDELTA:
- /* Pop and save to avoid blowing stack depth budget. */
- lval = JS_strdup(cx, POP_STR());
- if (!lval)
- return JS_FALSE;
-
- /*
- * The offset tells distance to the end of the right-hand
- * operand of the comma operator.
- */
- done = pc + len;
- pc += js_GetSrcNoteOffset(sn, 0);
- len = 0;
-
- if (!Decompile(ss, done, pc - done)) {
- JS_free(cx, (char *)lval);
- return JS_FALSE;
- }
-
- /* Pop Decompile result and print comma expression. */
- rval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
- JS_free(cx, (char *)lval);
- break;
-
- case SRC_HIDDEN:
- /* Hide this pop, it's from a goto in a with or for/in. */
- todo = -2;
- break;
-
- default:
- rval = POP_STR();
- if (*rval != '\0')
- js_printf(jp, "\t%s;\n", rval);
- todo = -2;
- break;
- }
- break;
-
- case JSOP_POP2:
- (void) PopOff(ss, op);
- (void) PopOff(ss, op);
- todo = -2;
- break;
-
- {
- static const char with_cookie[] = "with-cookie";
-
- case JSOP_ENTERWITH:
- sn = js_GetSrcNote(jp->script, pc);
- if (sn && SN_TYPE(sn) == SRC_HIDDEN) {
- todo = -2;
- break;
- }
- rval = POP_STR();
- js_printf(jp, "\twith (%s) {\n", rval);
- jp->indent += 4;
- todo = Sprint(&ss->sprinter, with_cookie);
- break;
-
- case JSOP_LEAVEWITH:
- sn = js_GetSrcNote(jp->script, pc);
- todo = -2;
- if (sn && SN_TYPE(sn) == SRC_HIDDEN)
- break;
- rval = POP_STR();
- LOCAL_ASSERT(strcmp(rval, with_cookie) == 0);
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
- break;
- }
-
- case JSOP_SETRVAL:
- case JSOP_RETURN:
- rval = POP_STR();
- if (*rval != '\0')
- js_printf(jp, "\t%s %s;\n", cs->name, rval);
- else
- js_printf(jp, "\t%s;\n", cs->name);
- todo = -2;
- break;
-
-#if JS_HAS_EXCEPTIONS
- case JSOP_THROW:
- sn = js_GetSrcNote(jp->script, pc);
- todo = -2;
- if (sn && SN_TYPE(sn) == SRC_HIDDEN)
- break;
- rval = POP_STR();
- js_printf(jp, "\t%s %s;\n", cs->name, rval);
- break;
-#endif /* JS_HAS_EXCEPTIONS */
-
- case JSOP_GOTO:
- case JSOP_GOTOX:
- sn = js_GetSrcNote(jp->script, pc);
- switch (sn ? SN_TYPE(sn) : SRC_NULL) {
- case SRC_CONT2LABEL:
- atom = js_GetAtom(cx, &jp->script->atomMap,
- (jsatomid) js_GetSrcNoteOffset(sn, 0));
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "\tcontinue %s;\n", rval);
- break;
- case SRC_CONTINUE:
- js_printf(jp, "\tcontinue;\n");
- break;
- case SRC_BREAK2LABEL:
- atom = js_GetAtom(cx, &jp->script->atomMap,
- (jsatomid) js_GetSrcNoteOffset(sn, 0));
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "\tbreak %s;\n", rval);
- break;
- case SRC_HIDDEN:
- break;
- default:
- js_printf(jp, "\tbreak;\n");
- break;
- }
- todo = -2;
- break;
-
- case JSOP_IFEQ:
- case JSOP_IFEQX:
- len = GetJumpOffset(pc, pc);
- sn = js_GetSrcNote(jp->script, pc);
-
- switch (sn ? SN_TYPE(sn) : SRC_NULL) {
- case SRC_IF:
- case SRC_IF_ELSE:
- rval = POP_STR();
- js_printf(jp, "\tif (%s) {\n", rval);
- jp->indent += 4;
- if (SN_TYPE(sn) == SRC_IF) {
- DECOMPILE_CODE(pc + oplen, len - oplen);
- } else {
- len = js_GetSrcNoteOffset(sn, 0);
- DECOMPILE_CODE(pc + oplen, len - oplen);
- jp->indent -= 4;
- pc += len;
- LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
- oplen = js_CodeSpec[*pc].length;
- len = GetJumpOffset(pc, pc);
- js_printf(jp, "\t} else {\n");
- jp->indent += 4;
- DECOMPILE_CODE(pc + oplen, len - oplen);
- }
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
- todo = -2;
- break;
-
- case SRC_WHILE:
- rval = POP_STR();
- js_printf(jp, "\twhile (%s) {\n", rval);
- jp->indent += 4;
- tail = js_GetSrcNoteOffset(sn, 0);
- DECOMPILE_CODE(pc + oplen, tail - oplen);
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
- todo = -2;
- break;
-
- case SRC_COND:
- xval = JS_strdup(cx, POP_STR());
- if (!xval)
- return JS_FALSE;
- len = js_GetSrcNoteOffset(sn, 0);
- DECOMPILE_CODE(pc + oplen, len - oplen);
- lval = JS_strdup(cx, POP_STR());
- if (!lval) {
- JS_free(cx, (void *)xval);
- return JS_FALSE;
- }
- pc += len;
- LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
- oplen = js_CodeSpec[*pc].length;
- len = GetJumpOffset(pc, pc);
- DECOMPILE_CODE(pc + oplen, len - oplen);
- rval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s ? %s : %s",
- xval, lval, rval);
- JS_free(cx, (void *)xval);
- JS_free(cx, (void *)lval);
- break;
-
- default:
- break;
- }
- break;
-
- case JSOP_IFNE:
- case JSOP_IFNEX:
-#if JS_HAS_DO_WHILE_LOOP
- /* Currently, this must be a do-while loop's upward branch. */
- jp->indent -= 4;
- js_printf(jp, "\t} while (%s);\n", POP_STR());
- todo = -2;
-#else
- JS_ASSERT(0);
-#endif /* JS_HAS_DO_WHILE_LOOP */
- break;
-
- case JSOP_OR:
- case JSOP_ORX:
- xval = "||";
-
- do_logical_connective:
- /* Top of stack is the first clause in a disjunction (||). */
- lval = JS_strdup(cx, POP_STR());
- if (!lval)
- return JS_FALSE;
- done = pc + GetJumpOffset(pc, pc);
- pc += len;
- len = PTRDIFF(done, pc, jsbytecode);
- DECOMPILE_CODE(pc, len);
- rval = POP_STR();
- if (jp->pretty &&
- jp->indent + 4 + strlen(lval) + 4 + strlen(rval) > 75) {
- rval = JS_strdup(cx, rval);
- if (!rval) {
- tail = -1;
- } else {
- todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);
- tail = Sprint(&ss->sprinter, "%*s%s",
- jp->indent + 4, "", rval);
- JS_free(cx, (char *)rval);
- }
- if (tail < 0)
- todo = -1;
- } else {
- todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);
- }
- JS_free(cx, (char *)lval);
- break;
-
- case JSOP_AND:
- case JSOP_ANDX:
- xval = "&&";
- goto do_logical_connective;
-
- case JSOP_FORARG:
- atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
- LOCAL_ASSERT(atom);
- goto do_fornameinloop;
-
- case JSOP_FORVAR:
- atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
- LOCAL_ASSERT(atom);
- goto do_fornameinloop;
-
- case JSOP_FORNAME:
- atom = GET_ATOM(cx, jp->script, pc);
-
- do_fornameinloop:
- sn = js_GetSrcNote(jp->script, pc);
- xval = NULL;
- lval = "";
- goto do_forinloop;
-
- case JSOP_FORPROP:
- xval = NULL;
- atom = GET_ATOM(cx, jp->script, pc);
- if (ATOM_KEYWORD(atom)) {
- xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
- (jschar)'\'');
- if (!xval)
- return JS_FALSE;
- atom = NULL;
- }
- lval = POP_STR();
- sn = NULL;
-
- do_forinloop:
- pc += oplen;
- LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
- oplen = js_CodeSpec[*pc].length;
- len = GetJumpOffset(pc, pc);
- sn2 = js_GetSrcNote(jp->script, pc);
- tail = js_GetSrcNoteOffset(sn2, 0);
-
- do_forinbody:
- js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval);
- if (atom) {
- xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!xval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, xval);
- js_printf(jp, *lval ? ".%s" : "%s", xval);
- } else if (xval) {
- js_printf(jp, "[%s]", xval);
- }
- rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
- js_printf(jp, " in %s) {\n", rval);
- jp->indent += 4;
- DECOMPILE_CODE(pc + oplen, tail - oplen);
- jp->indent -= 4;
- js_printf(jp, "\t}\n");
- todo = -2;
- break;
-
- case JSOP_FORELEM:
- pc++;
- LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
- len = js_CodeSpec[*pc].length;
-
- /*
- * Arrange for the JSOP_ENUMELEM case to set tail for use by
- * do_forinbody: code that uses on it to find the loop-closing
- * jump (whatever its format, normal or extended), in order to
- * bound the recursively decompiled loop body.
- */
- sn = js_GetSrcNote(jp->script, pc);
- JS_ASSERT(!forelem_tail);
- forelem_tail = pc + js_GetSrcNoteOffset(sn, 0);
-
- /*
- * This gets a little wacky. Only the length of the for loop
- * body PLUS the element-indexing expression is known here, so
- * we pass the after-loop pc to the JSOP_ENUMELEM case, which
- * is immediately below, to decompile that helper bytecode via
- * the 'forelem_done' local.
- *
- * Since a for..in loop can't nest in the head of another for
- * loop, we can use forelem_{tail,done} singletons to remember
- * state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto)
- * to label do_forinbody.
- */
- JS_ASSERT(!forelem_done);
- forelem_done = pc + GetJumpOffset(pc, pc);
- break;
-
- case JSOP_ENUMELEM:
- /*
- * The stack has the object under the (top) index expression.
- * The "rval" property id is underneath those two on the stack.
- * The for loop body net and gross lengths can now be adjusted
- * to account for the length of the indexing expression that
- * came after JSOP_FORELEM and before JSOP_ENUMELEM.
- */
- atom = NULL;
- xval = POP_STR();
- lval = POP_STR();
- rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
- JS_ASSERT(forelem_tail > pc);
- tail = forelem_tail - pc;
- forelem_tail = NULL;
- JS_ASSERT(forelem_done > pc);
- len = forelem_done - pc;
- forelem_done = NULL;
- goto do_forinbody;
-
- case JSOP_DUP2:
- rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);
- todo = SprintPut(&ss->sprinter, rval, strlen(rval));
- if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2]))
- return JS_FALSE;
- /* FALL THROUGH */
-
- case JSOP_DUP:
- rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
- op = ss->opcodes[ss->top-1];
- todo = SprintPut(&ss->sprinter, rval, strlen(rval));
- break;
-
- case JSOP_SETARG:
- atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
- LOCAL_ASSERT(atom);
- goto do_setname;
-
- case JSOP_SETVAR:
- atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
- LOCAL_ASSERT(atom);
- goto do_setname;
-
- case JSOP_SETCONST:
- case JSOP_SETNAME:
- atom = GET_ATOM(cx, jp->script, pc);
- do_setname:
- lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!lval)
- return JS_FALSE;
- rval = POP_STR();
- if (op == JSOP_SETNAME)
- (void) PopOff(ss, op);
- do_setlval:
- sn = js_GetSrcNote(jp->script, pc - 1);
- if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
- todo = Sprint(&ss->sprinter, "%s %s= %s",
- lval, js_CodeSpec[lastop].token, rval);
- } else {
- sn = js_GetSrcNote(jp->script, pc);
- todo = Sprint(&ss->sprinter, "%s%s = %s",
- VarPrefix(sn), lval, rval);
- }
- break;
-
- case JSOP_NEW:
- case JSOP_CALL:
- case JSOP_EVAL:
-#if JS_HAS_LVALUE_RETURN
- case JSOP_SETCALL:
-#endif
- saveop = op;
- op = JSOP_NOP; /* turn off parens */
- argc = GET_ARGC(pc);
- argv = (char **)
- JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);
- if (!argv)
- return JS_FALSE;
-
- ok = JS_TRUE;
- for (i = argc; i > 0; i--) {
- argv[i] = JS_strdup(cx, POP_STR());
- if (!argv[i]) {
- ok = JS_FALSE;
- break;
- }
- }
-
- /* Skip the JSOP_PUSHOBJ-created empty string. */
- LOCAL_ASSERT(ss->top >= 2);
- (void) PopOff(ss, op);
-
- /* Get the callee's decompiled image in argv[0]. */
- argv[0] = JS_strdup(cx, POP_STR());
- if (!argv[i])
- ok = JS_FALSE;
-
- lval = "(", rval = ")";
- if (saveop == JSOP_NEW) {
- todo = Sprint(&ss->sprinter, "%s %s%s",
- js_new_str, argv[0], lval);
- } else {
- todo = Sprint(&ss->sprinter, "%s%s",
- argv[0], lval);
- }
- if (todo < 0)
- ok = JS_FALSE;
-
- for (i = 1; i <= argc; i++) {
- if (!argv[i] ||
- Sprint(&ss->sprinter, "%s%s",
- argv[i], (i < argc) ? ", " : "") < 0) {
- ok = JS_FALSE;
- break;
- }
- }
- if (Sprint(&ss->sprinter, rval) < 0)
- ok = JS_FALSE;
-
- for (i = 0; i <= argc; i++) {
- if (argv[i])
- JS_free(cx, argv[i]);
- }
- JS_free(cx, argv);
- if (!ok)
- return JS_FALSE;
- op = saveop;
-#if JS_HAS_LVALUE_RETURN
- if (op == JSOP_SETCALL) {
- if (!PushOff(ss, todo, op))
- return JS_FALSE;
- todo = Sprint(&ss->sprinter, "");
- }
-#endif
- break;
-
- case JSOP_DELNAME:
- atom = GET_ATOM(cx, jp->script, pc);
- lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!lval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, lval);
- todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
- break;
-
- case JSOP_DELPROP:
- GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval);
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval);
- break;
-
- case JSOP_DELELEM:
- xval = POP_STR();
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s %s[%s]",
- js_delete_str, lval, xval);
- break;
-
- case JSOP_TYPEOF:
- case JSOP_VOID:
- rval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);
- break;
-
- case JSOP_INCARG:
- case JSOP_DECARG:
- atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
- LOCAL_ASSERT(atom);
- goto do_incatom;
-
- case JSOP_INCVAR:
- case JSOP_DECVAR:
- atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
- LOCAL_ASSERT(atom);
- goto do_incatom;
-
- case JSOP_INCNAME:
- case JSOP_DECNAME:
- atom = GET_ATOM(cx, jp->script, pc);
- do_incatom:
- lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!lval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, lval);
- todo = Sprint(&ss->sprinter, "%s%s",
- js_incop_str[!(cs->format & JOF_INC)], lval);
- break;
-
- case JSOP_INCPROP:
- case JSOP_DECPROP:
- GET_ATOM_QUOTE_AND_FMT("%s%s[%s]", "%s%s.%s", rval);
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, fmt,
- js_incop_str[!(cs->format & JOF_INC)],
- lval, rval);
- break;
-
- case JSOP_INCELEM:
- case JSOP_DECELEM:
- xval = POP_STR();
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s%s[%s]",
- js_incop_str[!(cs->format & JOF_INC)],
- lval, xval);
- break;
-
- case JSOP_ARGINC:
- case JSOP_ARGDEC:
- atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
- LOCAL_ASSERT(atom);
- goto do_atominc;
-
- case JSOP_VARINC:
- case JSOP_VARDEC:
- atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
- LOCAL_ASSERT(atom);
- goto do_atominc;
-
- case JSOP_NAMEINC:
- case JSOP_NAMEDEC:
- atom = GET_ATOM(cx, jp->script, pc);
- do_atominc:
- lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!lval)
- return JS_FALSE;
- todo = STR2OFF(&ss->sprinter, lval);
- SprintPut(&ss->sprinter,
- js_incop_str[!(cs->format & JOF_INC)],
- 2);
- break;
-
- case JSOP_PROPINC:
- case JSOP_PROPDEC:
- GET_ATOM_QUOTE_AND_FMT("%s[%s]%s", "%s.%s%s", rval);
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, fmt, lval, rval,
- js_incop_str[!(cs->format & JOF_INC)]);
- break;
-
- case JSOP_ELEMINC:
- case JSOP_ELEMDEC:
- xval = POP_STR();
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s[%s]%s",
- lval, xval,
- js_incop_str[!(cs->format & JOF_INC)]);
- break;
-
- case JSOP_GETPROP2:
- op = JSOP_GETPROP;
- (void) PopOff(ss, lastop);
- /* FALL THROUGH */
-
- case JSOP_GETPROP:
- GET_ATOM_QUOTE_AND_FMT("%s[%s]", "%s.%s", rval);
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, fmt, lval, rval);
- break;
-
- case JSOP_SETPROP:
- GET_ATOM_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
- rval = POP_STR();
- lval = POP_STR();
- sn = js_GetSrcNote(jp->script, pc - 1);
- todo = Sprint(&ss->sprinter, fmt, lval, xval,
- (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
- ? js_CodeSpec[lastop].token
- : "",
- rval);
- break;
-
- case JSOP_GETELEM2:
- op = JSOP_GETELEM;
- (void) PopOff(ss, lastop);
- /* FALL THROUGH */
-
- case JSOP_GETELEM:
- op = JSOP_NOP; /* turn off parens */
- xval = POP_STR();
- op = JSOP_GETELEM;
- lval = POP_STR();
- if (*xval == '\0')
- todo = Sprint(&ss->sprinter, "%s", lval);
- else
- todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);
- break;
-
- case JSOP_SETELEM:
- op = JSOP_NOP; /* turn off parens */
- rval = POP_STR();
- xval = POP_STR();
- op = JSOP_SETELEM;
- lval = POP_STR();
- if (*xval == '\0')
- goto do_setlval;
- sn = js_GetSrcNote(jp->script, pc - 1);
- todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",
- lval, xval,
- (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
- ? js_CodeSpec[lastop].token
- : "",
- rval);
- break;
-
- case JSOP_ARGSUB:
- i = (jsint) GET_ATOM_INDEX(pc);
- todo = Sprint(&ss->sprinter, "%s[%d]",
- js_arguments_str, (int) i);
- break;
-
- case JSOP_ARGCNT:
- todo = Sprint(&ss->sprinter, "%s.%s",
- js_arguments_str, js_length_str);
- break;
-
- case JSOP_GETARG:
- atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
- LOCAL_ASSERT(atom);
- goto do_name;
-
- case JSOP_GETVAR:
- atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
- LOCAL_ASSERT(atom);
- goto do_name;
-
- case JSOP_NAME:
- atom = GET_ATOM(cx, jp->script, pc);
- do_name:
- sn = js_GetSrcNote(jp->script, pc);
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval);
- break;
-
- case JSOP_UINT16:
- i = (jsint) GET_ATOM_INDEX(pc);
- todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
- break;
-
- case JSOP_NUMBER:
- atom = GET_ATOM(cx, jp->script, pc);
- val = ATOM_KEY(atom);
- if (JSVAL_IS_INT(val)) {
- long ival = (long)JSVAL_TO_INT(val);
- todo = Sprint(&ss->sprinter, "%ld", ival);
- } else {
- char buf[DTOSTR_STANDARD_BUFFER_SIZE];
- char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,
- 0, *JSVAL_TO_DOUBLE(val));
- if (!numStr) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- todo = Sprint(&ss->sprinter, numStr);
- }
- break;
-
- case JSOP_STRING:
- atom = GET_ATOM(cx, jp->script, pc);
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
- (jschar)'"');
- if (!rval)
- return JS_FALSE;
- todo = STR2OFF(&ss->sprinter, rval);
- break;
-
- case JSOP_OBJECT:
- case JSOP_ANONFUNOBJ:
- case JSOP_NAMEDFUNOBJ:
- atom = GET_ATOM(cx, jp->script, pc);
- if (op == JSOP_OBJECT) {
- str = js_ValueToSource(cx, ATOM_KEY(atom));
- if (!str)
- return JS_FALSE;
- } else {
- if (!js_fun_toString(cx, ATOM_TO_OBJECT(atom),
- JS_DONT_PRETTY_PRINT, 0, NULL,
- &val)) {
- return JS_FALSE;
- }
- str = JSVAL_TO_STRING(val);
- }
- todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str),
- JSSTRING_LENGTH(str));
- break;
-
-#if JS_HAS_SWITCH_STATEMENT
- case JSOP_TABLESWITCH:
- case JSOP_TABLESWITCHX:
- {
- jsbytecode *pc2;
- ptrdiff_t off, off2;
- jsint j, n, low, high;
- TableEntry *table;
-
- sn = js_GetSrcNote(jp->script, pc);
- JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
- len = js_GetSrcNoteOffset(sn, 0);
- pc2 = pc;
- off = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- low = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- high = GetJumpOffset(pc, pc2);
-
- n = high - low + 1;
- if (n == 0) {
- table = NULL;
- j = 0;
- } else {
- table = (TableEntry *)
- JS_malloc(cx, (size_t)n * sizeof *table);
- if (!table)
- return JS_FALSE;
- for (i = j = 0; i < n; i++) {
- pc2 += JUMP_OFFSET_LEN;
- off2 = GetJumpOffset(pc, pc2);
- if (off2) {
- table[j].key = INT_TO_JSVAL(low + i);
- table[j++].offset = off2;
- }
- }
- js_HeapSort(table, (size_t) j, sizeof *table,
- CompareOffsets, NULL);
- }
-
- ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
- JS_FALSE);
- JS_free(cx, table);
- if (!ok)
- return ok;
- todo = -2;
- break;
- }
-
- case JSOP_LOOKUPSWITCH:
- case JSOP_LOOKUPSWITCHX:
- {
- jsbytecode *pc2;
- ptrdiff_t off, off2;
- jsint npairs;
- TableEntry *table;
-
- sn = js_GetSrcNote(jp->script, pc);
- JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
- len = js_GetSrcNoteOffset(sn, 0);
- pc2 = pc;
- off = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- npairs = (jsint) GET_ATOM_INDEX(pc2);
- pc2 += ATOM_INDEX_LEN;
-
- table = (TableEntry *)
- JS_malloc(cx, (size_t)npairs * sizeof *table);
- if (!table)
- return JS_FALSE;
- for (i = 0; i < npairs; i++) {
- atom = GET_ATOM(cx, jp->script, pc2);
- pc2 += ATOM_INDEX_LEN;
- off2 = GetJumpOffset(pc, pc2);
- pc2 += JUMP_OFFSET_LEN;
- table[i].key = ATOM_KEY(atom);
- table[i].offset = off2;
- }
-
- ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
- JS_FALSE);
- JS_free(cx, table);
- if (!ok)
- return ok;
- todo = -2;
- break;
- }
-
- case JSOP_CONDSWITCH:
- {
- jsbytecode *pc2;
- ptrdiff_t off, off2, caseOff;
- jsint ncases;
- TableEntry *table;
-
- sn = js_GetSrcNote(jp->script, pc);
- JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
- len = js_GetSrcNoteOffset(sn, 0);
- off = js_GetSrcNoteOffset(sn, 1);
-
- /*
- * Count the cases using offsets from switch to first case,
- * and case to case, stored in srcnote immediates.
- */
- pc2 = pc;
- off2 = off;
- for (ncases = 0; off2 != 0; ncases++) {
- pc2 += off2;
- JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
- *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
- if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
- /* End of cases, but count default as a case. */
- off2 = 0;
- } else {
- sn = js_GetSrcNote(jp->script, pc2);
- JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
- off2 = js_GetSrcNoteOffset(sn, 0);
- }
- }
-
- /*
- * Allocate table and rescan the cases using their srcnotes,
- * stashing each case's delta from switch top in table[i].key,
- * and the distance to its statements in table[i].offset.
- */
- table = (TableEntry *)
- JS_malloc(cx, (size_t)ncases * sizeof *table);
- if (!table)
- return JS_FALSE;
- pc2 = pc;
- off2 = off;
- for (i = 0; i < ncases; i++) {
- pc2 += off2;
- JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
- *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
- caseOff = pc2 - pc;
- table[i].key = INT_TO_JSVAL((jsint) caseOff);
- table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
- if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
- sn = js_GetSrcNote(jp->script, pc2);
- JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
- off2 = js_GetSrcNoteOffset(sn, 0);
- }
- }
-
- /*
- * Find offset of default code by fetching the default offset
- * from the end of table. JSOP_CONDSWITCH always has a default
- * case at the end.
- */
- off = JSVAL_TO_INT(table[ncases-1].key);
- pc2 = pc + off;
- off += GetJumpOffset(pc2, pc2);
-
- ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
- JS_TRUE);
- JS_free(cx, table);
- if (!ok)
- return ok;
- todo = -2;
- break;
- }
-
- case JSOP_CASE:
- case JSOP_CASEX:
- {
- lval = POP_STR();
- if (!lval)
- return JS_FALSE;
- js_printf(jp, "\tcase %s:\n", lval);
- todo = -2;
- break;
- }
-
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
-#if !JS_BUG_FALLIBLE_EQOPS
- case JSOP_NEW_EQ:
- case JSOP_NEW_NE:
- rval = POP_STR();
- lval = POP_STR();
- todo = Sprint(&ss->sprinter, "%s %c%s %s",
- lval,
- (op == JSOP_NEW_EQ) ? '=' : '!',
-#if JS_HAS_TRIPLE_EQOPS
- JSVERSION_IS_ECMA(cx->version) ? "==" :
-#endif
- "=",
- rval);
- break;
-#endif /* !JS_BUG_FALLIBLE_EQOPS */
-
-#if JS_HAS_LEXICAL_CLOSURE
- case JSOP_CLOSURE:
- atom = GET_ATOM(cx, jp->script, pc);
- JS_ASSERT(ATOM_IS_OBJECT(atom));
- goto do_function;
-#endif /* JS_HAS_LEXICAL_CLOSURE */
-
-#if JS_HAS_EXPORT_IMPORT
- case JSOP_EXPORTALL:
- js_printf(jp, "\texport *\n");
- todo = -2;
- break;
-
- case JSOP_EXPORTNAME:
- atom = GET_ATOM(cx, jp->script, pc);
- rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
- if (!rval)
- return JS_FALSE;
- RETRACT(&ss->sprinter, rval);
- js_printf(jp, "\texport %s\n", rval);
- todo = -2;
- break;
-
- case JSOP_IMPORTALL:
- lval = POP_STR();
- js_printf(jp, "\timport %s.*\n", lval);
- todo = -2;
- break;
-
- case JSOP_IMPORTPROP:
- GET_ATOM_QUOTE_AND_FMT("\timport %s[%s]\n", "\timport %s.%s\n",
- rval);
- lval = POP_STR();
- js_printf(jp, fmt, lval, rval);
- todo = -2;
- break;
-
- case JSOP_IMPORTELEM:
- xval = POP_STR();
- op = JSOP_GETELEM;
- lval = POP_STR();
- js_printf(jp, "\timport %s[%s]\n", lval, xval);
- todo = -2;
- break;
-#endif /* JS_HAS_EXPORT_IMPORT */
-
- case JSOP_TRAP:
- op = JS_GetTrapOpcode(cx, jp->script, pc);
- if (op == JSOP_LIMIT)
- return JS_FALSE;
- *pc = op;
- cs = &js_CodeSpec[op];
- len = cs->length;
- DECOMPILE_CODE(pc, len);
- *pc = JSOP_TRAP;
- todo = -2;
- break;
-
-#if JS_HAS_INITIALIZERS
- case JSOP_NEWINIT:
- LOCAL_ASSERT(ss->top >= 2);
- (void) PopOff(ss, op);
- lval = POP_STR();
-#if JS_HAS_SHARP_VARS
- op = (JSOp)pc[len];
- if (op == JSOP_DEFSHARP) {
- pc += len;
- cs = &js_CodeSpec[op];
- len = cs->length;
- i = (jsint) GET_ATOM_INDEX(pc);
- todo = Sprint(&ss->sprinter, "#%u=%c",
- (unsigned) i,
- (*lval == 'O') ? '{' : '[');
- } else
-#endif /* JS_HAS_SHARP_VARS */
- {
- todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "[");
- }
- break;
-
- case JSOP_ENDINIT:
- rval = POP_STR();
- sn = js_GetSrcNote(jp->script, pc);
- todo = Sprint(&ss->sprinter, "%s%s%c",
- rval,
- (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
- (*rval == '{') ? '}' : ']');
- break;
-
- case JSOP_INITPROP:
- case JSOP_INITCATCHVAR:
- atom = GET_ATOM(cx, jp->script, pc);
- xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
- ATOM_KEYWORD(atom) ? '\'' : 0);
- if (!xval)
- return JS_FALSE;
- rval = POP_STR();
- lval = POP_STR();
- do_initprop:
-#ifdef OLD_GETTER_SETTER
- todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
- lval,
- (lval[1] != '\0') ? ", " : "",
- xval,
- (lastop == JSOP_GETTER || lastop == JSOP_SETTER)
- ? " " : "",
- (lastop == JSOP_GETTER) ? js_getter_str :
- (lastop == JSOP_SETTER) ? js_setter_str :
- "",
- rval);
-#else
- if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
- todo = Sprint(&ss->sprinter, "%s%s%s %s%s",
- lval,
- (lval[1] != '\0') ? ", " : "",
- (lastop == JSOP_GETTER)
- ? js_get_str : js_set_str,
- xval,
- rval + strlen(js_function_str) + 1);
- } else {
- todo = Sprint(&ss->sprinter, "%s%s%s:%s",
- lval,
- (lval[1] != '\0') ? ", " : "",
- xval,
- rval);
- }
-#endif
- break;
-
- case JSOP_INITELEM:
- rval = POP_STR();
- xval = POP_STR();
- lval = POP_STR();
- sn = js_GetSrcNote(jp->script, pc);
- if (sn && SN_TYPE(sn) == SRC_LABEL)
- goto do_initprop;
- todo = Sprint(&ss->sprinter, "%s%s%s",
- lval,
- (lval[1] != '\0' || *xval != '0') ? ", " : "",
- rval);
- break;
-
-#if JS_HAS_SHARP_VARS
- case JSOP_DEFSHARP:
- i = (jsint) GET_ATOM_INDEX(pc);
- rval = POP_STR();
- todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
- break;
-
- case JSOP_USESHARP:
- i = (jsint) GET_ATOM_INDEX(pc);
- todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
- break;
-#endif /* JS_HAS_SHARP_VARS */
-#endif /* JS_HAS_INITIALIZERS */
-
-#if JS_HAS_DEBUGGER_KEYWORD
- case JSOP_DEBUGGER:
- js_printf(jp, "\tdebugger;\n");
- todo = -2;
- break;
-#endif /* JS_HAS_DEBUGGER_KEYWORD */
-
- default:
- todo = -2;
- break;
- }
- }
-
- if (todo < 0) {
- /* -2 means "don't push", -1 means reported error. */
- if (todo == -1)
- return JS_FALSE;
- } else {
- if (!PushOff(ss, todo, op))
- return JS_FALSE;
- }
- pc += len;
- }
-
-/*
- * Undefine local macros.
- */
-#undef DECOMPILE_CODE
-#undef POP_STR
-#undef LOCAL_ASSERT
-#undef GET_ATOM_QUOTE_AND_FMT
-
- return JS_TRUE;
-}
-
-
-JSBool
-js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len)
-{
- SprintStack ss;
- JSContext *cx;
- void *mark, *space;
- size_t offsetsz, opcodesz;
- JSBool ok;
- JSScript *oldscript;
- char *last;
-
- /* Initialize a sprinter for use with the offset stack. */
- ss.printer = jp;
- cx = jp->sprinter.context;
- mark = JS_ARENA_MARK(&cx->tempPool);
- INIT_SPRINTER(cx, &ss.sprinter, &cx->tempPool, PAREN_SLOP);
-
- /* Allocate the parallel (to avoid padding) offset and opcode stacks. */
- offsetsz = script->depth * sizeof(ptrdiff_t);
- opcodesz = script->depth * sizeof(jsbytecode);
- JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
- if (!space) {
- ok = JS_FALSE;
- goto out;
- }
- ss.offsets = (ptrdiff_t *) space;
- ss.opcodes = (jsbytecode *) ((char *)space + offsetsz);
- ss.top = 0;
-
- /* Call recursive subroutine to do the hard work. */
- oldscript = jp->script;
- jp->script = script;
- ok = Decompile(&ss, pc, len);
- jp->script = oldscript;
-
- /* If the given code didn't empty the stack, do it now. */
- if (ss.top) {
- do {
- last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_NOP));
- } while (ss.top);
- js_printf(jp, "%s", last);
- }
-
-out:
- /* Free all temporary stuff allocated under this call. */
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return ok;
-}
-
-JSBool
-js_DecompileScript(JSPrinter *jp, JSScript *script)
-{
- return js_DecompileCode(jp, script, script->code, (uintN)script->length);
-}
-
-static const char native_code_str[] = "\t[native code]\n";
-
-JSBool
-js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun)
-{
- JSScript *script;
- JSScope *scope, *save;
- JSBool ok;
-
- script = fun->script;
- if (!script) {
- js_printf(jp, native_code_str);
- return JS_TRUE;
- }
- scope = fun->object ? OBJ_SCOPE(fun->object) : NULL;
- save = jp->scope;
- jp->scope = scope;
- ok = js_DecompileCode(jp, script, script->code, (uintN)script->length);
- jp->scope = save;
- return ok;
-}
-
-JSBool
-js_DecompileFunction(JSPrinter *jp, JSFunction *fun)
-{
- JSContext *cx;
- uintN i, nargs, indent;
- void *mark;
- JSAtom **params;
- JSScope *scope, *oldscope;
- JSScopeProperty *sprop;
- JSBool ok;
-
- /*
- * If pretty, conform to ECMA-262 Edition 3, 15.3.4.2, by decompiling a
- * FunctionDeclaration. Otherwise, check the JSFUN_LAMBDA flag and force
- * an expression by parenthesizing.
- */
- if (jp->pretty) {
- js_puts(jp, "\n");
- js_printf(jp, "\t");
- } else {
- if (fun->flags & JSFUN_LAMBDA)
- js_puts(jp, "(");
- }
- if (fun->flags & JSFUN_GETTER)
- js_printf(jp, "%s ", js_getter_str);
- else if (fun->flags & JSFUN_SETTER)
- js_printf(jp, "%s ", js_setter_str);
-
- js_printf(jp, "%s ", js_function_str);
- if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0))
- return JS_FALSE;
- js_puts(jp, "(");
-
- if (fun->script && fun->object) {
- /*
- * Print the parameters.
- *
- * This code is complicated by the need to handle duplicate parameter
- * names, as required by ECMA (bah!). A duplicate parameter is stored
- * as another node with the same id (the parameter name) but different
- * shortid (the argument index) along the property tree ancestor line
- * starting at SCOPE_LAST_PROP(scope). Only the last duplicate param
- * is mapped by the scope's hash table.
- */
- cx = jp->sprinter.context;
- nargs = fun->nargs;
- mark = JS_ARENA_MARK(&cx->tempPool);
- JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool,
- nargs * sizeof(JSAtom *));
- if (!params) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- scope = OBJ_SCOPE(fun->object);
- for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
- if (sprop->getter != js_GetArgument)
- continue;
- JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
- JS_ASSERT((uintN) sprop->shortid < nargs);
- JS_ASSERT(!JSVAL_IS_INT(sprop->id));
- params[(uintN) sprop->shortid] = (JSAtom *) sprop->id;
- }
- for (i = 0; i < nargs; i++) {
- if (i > 0)
- js_puts(jp, ", ");
- if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(params[i]), 0))
- return JS_FALSE;
- }
- JS_ARENA_RELEASE(&cx->tempPool, mark);
-#ifdef __GNUC__
- } else {
- scope = NULL;
-#endif
- }
-
- js_printf(jp, ") {\n");
- indent = jp->indent;
- jp->indent += 4;
- if (fun->script && fun->object) {
- oldscope = jp->scope;
- jp->scope = scope;
- ok = js_DecompileScript(jp, fun->script);
- jp->scope = oldscope;
- if (!ok) {
- jp->indent = indent;
- return JS_FALSE;
- }
- } else {
- js_printf(jp, native_code_str);
- }
- jp->indent -= 4;
- js_printf(jp, "\t}");
-
- if (jp->pretty) {
- js_puts(jp, "\n");
- } else {
- if (fun->flags & JSFUN_LAMBDA)
- js_puts(jp, ")");
- }
- return JS_TRUE;
-}
-
-JSString *
-js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
- JSString *fallback)
-{
- JSStackFrame *fp, *down;
- jsbytecode *pc, *begin, *end, *tmp;
- jsval *sp, *base, *limit;
- JSScript *script;
- JSOp op;
- const JSCodeSpec *cs;
- uint32 format, mode;
- intN depth;
- jssrcnote *sn;
- uintN len, off;
- JSPrinter *jp;
- JSString *name;
-
- fp = cx->fp;
- if (!fp)
- goto do_fallback;
-
- /* Try to find sp's generating pc depth slots under it on the stack. */
- pc = fp->pc;
- if (spindex == JSDVG_SEARCH_STACK) {
- if (!pc) {
- /*
- * Current frame is native: look under it for a scripted call
- * in which a decompilable bytecode string that generated the
- * value as an actual argument might exist.
- */
- JS_ASSERT(!fp->script && fp->fun && fp->fun->native);
- down = fp->down;
- if (!down)
- goto do_fallback;
- script = down->script;
- base = fp->argv;
- limit = base + fp->argc;
- } else {
- /*
- * This should be a script activation, either a top-level
- * script or a scripted function. But be paranoid about calls
- * to js_DecompileValueGenerator from code that hasn't fully
- * initialized a (default-all-zeroes) frame.
- */
- script = fp->script;
- base = fp->spbase;
- limit = fp->sp;
- }
-
- /*
- * Pure paranoia about default-zeroed frames being active while
- * js_DecompileValueGenerator is called. It can't hurt much now;
- * error reporting performance is not an issue.
- */
- if (!script || !base || !limit)
- goto do_fallback;
-
- /*
- * Try to find operand-generating pc depth slots below sp.
- *
- * In the native case, we know the arguments have generating pc's
- * under them, on account of fp->down->script being non-null: all
- * compiled scripts get depth slots for generating pc's allocated
- * upon activation, at the top of js_Interpret.
- *
- * In the script or scripted function case, the same reasoning
- * applies to fp rather than to fp->down.
- */
- for (sp = base; sp < limit; sp++) {
- if (*sp == v) {
- depth = (intN)script->depth;
- pc = (jsbytecode *) sp[-depth];
- break;
- }
- }
- } else {
- /*
- * At this point, pc may or may not be null, i.e., we could be in
- * a script activation, or we could be in a native frame that was
- * called by another native function. Check pc and script.
- */
- if (!pc)
- goto do_fallback;
- script = fp->script;
- if (!script)
- goto do_fallback;
-
- if (spindex != JSDVG_IGNORE_STACK) {
- JS_ASSERT(spindex < 0);
- depth = (intN)script->depth;
-#if !JS_HAS_NO_SUCH_METHOD
- JS_ASSERT(-depth <= spindex);
-#endif
- spindex -= depth;
-
- base = (jsval *) cx->stackPool.current->base;
- limit = (jsval *) cx->stackPool.current->avail;
- sp = fp->sp + spindex;
- if (JS_UPTRDIFF(sp, base) < JS_UPTRDIFF(limit, base))
- pc = (jsbytecode *) *sp;
- }
- }
-
- /*
- * Again, be paranoid, this time about possibly loading an invalid pc
- * from sp[-(1+depth)].
- */
- if (JS_UPTRDIFF(pc, script->code) >= (jsuword)script->length) {
- pc = fp->pc;
- if (!pc)
- goto do_fallback;
- }
- op = (JSOp) *pc;
- if (op == JSOP_TRAP)
- op = JS_GetTrapOpcode(cx, script, pc);
-
- /* XXX handle null as a special case, to avoid calling null "object" */
- if (op == JSOP_NULL)
- return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
-
- cs = &js_CodeSpec[op];
- format = cs->format;
- mode = (format & JOF_MODEMASK);
-
- /* NAME ops are self-contained, but others require left context. */
- if (mode == JOF_NAME) {
- begin = pc;
- } else {
- sn = js_GetSrcNote(script, pc);
- if (!sn || SN_TYPE(sn) != SRC_PCBASE)
- goto do_fallback;
- begin = pc - js_GetSrcNoteOffset(sn, 0);
- }
- end = pc + cs->length;
- len = PTRDIFF(end, begin, jsbytecode);
-
- if (format & (JOF_SET | JOF_DEL | JOF_INCDEC | JOF_IMPORT | JOF_FOR)) {
- tmp = (jsbytecode *) JS_malloc(cx, len * sizeof(jsbytecode));
- if (!tmp)
- return NULL;
- memcpy(tmp, begin, len * sizeof(jsbytecode));
- if (mode == JOF_NAME) {
- tmp[0] = JSOP_NAME;
- } else {
- /*
- * We must replace the faulting pc's bytecode with a corresponding
- * JSOP_GET* code. For JSOP_SET{PROP,ELEM}, we must use the "2nd"
- * form of JSOP_GET{PROP,ELEM}, to throw away the assignment op's
- * right-hand operand and decompile it as if it were a GET of its
- * left-hand operand.
- */
- off = len - cs->length;
- JS_ASSERT(off == (uintN) PTRDIFF(pc, begin, jsbytecode));
- if (mode == JOF_PROP) {
- tmp[off] = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP;
- } else if (mode == JOF_ELEM) {
- tmp[off] = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM;
- } else {
- /*
- * A zero mode means precisely that op is uncategorized for our
- * purposes, so we must write per-op special case code here.
- */
- switch (op) {
- case JSOP_ENUMELEM:
- tmp[off] = JSOP_GETELEM;
- break;
-#if JS_HAS_LVALUE_RETURN
- case JSOP_SETCALL:
- tmp[off] = JSOP_CALL;
- break;
-#endif
- default:
- JS_ASSERT(0);
- }
- }
- }
- begin = tmp;
- } else {
- /* No need to revise script bytecode. */
- tmp = NULL;
- }
-
- jp = js_NewPrinter(cx, "js_DecompileValueGenerator", 0, JS_FALSE);
- if (jp && js_DecompileCode(jp, script, begin, len))
- name = js_GetPrinterOutput(jp);
- else
- name = NULL;
- js_DestroyPrinter(jp);
- if (tmp)
- JS_free(cx, tmp);
- return name;
-
- do_fallback:
- return fallback ? fallback : js_ValueToString(cx, v);
-}
diff --git a/src/extension/script/js/jsopcode.h b/src/extension/script/js/jsopcode.h
deleted file mode 100644
index e24fb2bf8..000000000
--- a/src/extension/script/js/jsopcode.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsopcode_h___
-#define jsopcode_h___
-/*
- * JS bytecode definitions.
- */
-#include <stddef.h>
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * JS operation bytecodes.
- */
-typedef enum JSOp {
-#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
- op = val,
-#include "jsopcode.tbl"
-#undef OPDEF
- JSOP_LIMIT
-} JSOp;
-
-/*
- * JS bytecode formats.
- */
-#define JOF_BYTE 0 /* single bytecode, no immediates */
-#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */
-#define JOF_CONST 2 /* unsigned 16-bit constant pool index */
-#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */
-#define JOF_TABLESWITCH 4 /* table switch */
-#define JOF_LOOKUPSWITCH 5 /* lookup switch */
-#define JOF_QARG 6 /* quickened get/set function argument ops */
-#define JOF_QVAR 7 /* quickened get/set local variable ops */
-#define JOF_DEFLOCALVAR 8 /* define local var with initial value */
-#define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */
-#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */
-#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */
-#define JOF_TYPEMASK 0x000f /* mask for above immediate types */
-#define JOF_NAME 0x0010 /* name operation */
-#define JOF_PROP 0x0020 /* obj.prop operation */
-#define JOF_ELEM 0x0030 /* obj[index] operation */
-#define JOF_MODEMASK 0x0030 /* mask for above addressing modes */
-#define JOF_SET 0x0040 /* set (i.e., assignment) operation */
-#define JOF_DEL 0x0080 /* delete operation */
-#define JOF_DEC 0x0100 /* decrement (--, not ++) opcode */
-#define JOF_INC 0x0200 /* increment (++, not --) opcode */
-#define JOF_INCDEC 0x0300 /* increment or decrement opcode */
-#define JOF_POST 0x0400 /* postorder increment or decrement */
-#define JOF_IMPORT 0x0800 /* import property op */
-#define JOF_FOR 0x1000 /* for-in property op */
-#define JOF_ASSIGNING JOF_SET /* hint for JSClass.resolve, used for ops
- that do simplex assignment */
-#define JOF_BACKPATCH 0x4000 /* backpatch placeholder during codegen */
-#define JOF_LEFTASSOC 0x8000 /* left-associative operator */
-
-#define JOF_TYPE_IS_EXTENDED_JUMP(t) \
- ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX))
-
-/*
- * Immediate operand getters, setters, and bounds.
- */
-
-/* Short (2-byte signed offset) relative jump macros. */
-#define JUMP_OFFSET_LEN 2
-#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8))
-#define JUMP_OFFSET_LO(off) ((jsbytecode)(off))
-#define GET_JUMP_OFFSET(pc) ((int16)(((pc)[1] << 8) | (pc)[2]))
-#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \
- (pc)[2] = JUMP_OFFSET_LO(off))
-#define JUMP_OFFSET_MIN ((int16)0x8000)
-#define JUMP_OFFSET_MAX ((int16)0x7fff)
-
-/*
- * When a short jump won't hold a relative offset, its 2-byte immediate offset
- * operand is an unsigned index of a span-dependency record, maintained until
- * code generation finishes -- after which some (but we hope not nearly all)
- * span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c).
- *
- * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump
- * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be
- * found (via binary search) by its "before span-dependency optimization" pc
- * offset (from script main entry point).
- */
-#define GET_SPANDEP_INDEX(pc) ((uint16)(((pc)[1] << 8) | (pc)[2]))
-#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \
- (pc)[2] = JUMP_OFFSET_LO(i))
-#define SPANDEP_INDEX_MAX ((uint16)0xfffe)
-#define SPANDEP_INDEX_HUGE ((uint16)0xffff)
-
-/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */
-#define JUMPX_OFFSET_LEN 4
-#define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24))
-#define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16))
-#define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8))
-#define JUMPX_OFFSET_B0(off) ((jsbytecode)(off))
-#define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \
- | ((pc)[3] << 8) | (pc)[4]))
-#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \
- (pc)[2] = JUMPX_OFFSET_B2(off), \
- (pc)[3] = JUMPX_OFFSET_B1(off), \
- (pc)[4] = JUMPX_OFFSET_B0(off))
-#define JUMPX_OFFSET_MIN ((int32)0x80000000)
-#define JUMPX_OFFSET_MAX ((int32)0x7fffffff)
-
-/* A literal is indexed by a per-script atom map. */
-#define ATOM_INDEX_LEN 2
-#define ATOM_INDEX_HI(index) ((jsbytecode)((index) >> 8))
-#define ATOM_INDEX_LO(index) ((jsbytecode)(index))
-#define GET_ATOM_INDEX(pc) ((jsatomid)(((pc)[1] << 8) | (pc)[2]))
-#define SET_ATOM_INDEX(pc,index)((pc)[1] = ATOM_INDEX_HI(index), \
- (pc)[2] = ATOM_INDEX_LO(index))
-#define GET_ATOM(cx,script,pc) js_GetAtom((cx), &(script)->atomMap, \
- GET_ATOM_INDEX(pc))
-#define ATOM_INDEX_LIMIT_LOG2 16
-#define ATOM_INDEX_LIMIT ((uint32)1 << ATOM_INDEX_LIMIT_LOG2)
-
-/* Actual argument count operand format helpers. */
-#define ARGC_HI(argc) ((jsbytecode)((argc) >> 8))
-#define ARGC_LO(argc) ((jsbytecode)(argc))
-#define GET_ARGC(pc) ((uintN)(((pc)[1] << 8) | (pc)[2]))
-#define ARGC_LIMIT ((uint32)1 << 16)
-
-/* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */
-#define GET_ARGNO(pc) GET_ARGC(pc)
-#define SET_ARGNO(pc,argno) SET_JUMP_OFFSET(pc,argno)
-#define ARGNO_LEN JUMP_OFFSET_LEN
-#define GET_VARNO(pc) GET_ARGC(pc)
-#define SET_VARNO(pc,varno) SET_JUMP_OFFSET(pc,varno)
-#define VARNO_LEN JUMP_OFFSET_LEN
-
-struct JSCodeSpec {
- const char *name; /* JS bytecode name */
- const char *token; /* JS source literal or null */
- int8 length; /* length including opcode byte */
- int8 nuses; /* arity, -1 if variadic */
- int8 ndefs; /* number of stack results */
- uint8 prec; /* operator precedence */
- uint32 format; /* immediate operand format */
-};
-
-extern const char js_const_str[];
-extern const char js_var_str[];
-extern const char js_function_str[];
-extern const char js_in_str[];
-extern const char js_instanceof_str[];
-extern const char js_new_str[];
-extern const char js_delete_str[];
-extern const char js_typeof_str[];
-extern const char js_void_str[];
-extern const char js_null_str[];
-extern const char js_this_str[];
-extern const char js_false_str[];
-extern const char js_true_str[];
-extern const JSCodeSpec js_CodeSpec[];
-extern uintN js_NumCodeSpecs;
-extern const jschar js_EscapeMap[];
-
-/*
- * Return a GC'ed string containing the chars in str, with any non-printing
- * chars or quotes (' or " as specified by the quote argument) escaped, and
- * with the quote character at the beginning and end of the result string.
- */
-extern JSString *
-js_QuoteString(JSContext *cx, JSString *str, jschar quote);
-
-/*
- * JSPrinter operations, for printf style message formatting. The return
- * value from js_GetPrinterOutput() is the printer's cumulative output, in
- * a GC'ed string.
- */
-extern JSPrinter *
-js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty);
-
-extern void
-js_DestroyPrinter(JSPrinter *jp);
-
-extern JSString *
-js_GetPrinterOutput(JSPrinter *jp);
-
-extern int
-js_printf(JSPrinter *jp, const char *format, ...);
-
-extern JSBool
-js_puts(JSPrinter *jp, const char *s);
-
-#ifdef DEBUG
-/*
- * Disassemblers, for debugging only.
- */
-#include <stdio.h>
-
-extern JS_FRIEND_API(void)
-js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp);
-
-extern JS_FRIEND_API(uintN)
-js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
- JSBool lines, FILE *fp);
-#endif /* DEBUG */
-
-/*
- * Decompilers, for script, function, and expression pretty-printing.
- */
-extern JSBool
-js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len);
-
-extern JSBool
-js_DecompileScript(JSPrinter *jp, JSScript *script);
-
-extern JSBool
-js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun);
-
-extern JSBool
-js_DecompileFunction(JSPrinter *jp, JSFunction *fun);
-
-/*
- * Find the source expression that resulted in v, and return a new string
- * containing it. Fall back on v's string conversion (fallback) if we can't
- * find the bytecode that generated and pushed v on the operand stack.
- *
- * Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't
- * look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise,
- * spindex is the negative index of v, measured from cx->fp->sp, or from a
- * lower frame's sp if cx->fp is native.
- */
-extern JSString *
-js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
- JSString *fallback);
-
-#define JSDVG_IGNORE_STACK 0
-#define JSDVG_SEARCH_STACK 1
-
-JS_END_EXTERN_C
-
-#endif /* jsopcode_h___ */
diff --git a/src/extension/script/js/jsopcode.tbl b/src/extension/script/js/jsopcode.tbl
deleted file mode 100644
index d4bad0fd9..000000000
--- a/src/extension/script/js/jsopcode.tbl
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JavaScript operation bytecodes. If you need to allocate a bytecode, look
- * for a name of the form JSOP_UNUSED* and claim it. Otherwise, always add at
- * the end of the table.
- *
- * Includers must define an OPDEF macro of the following form:
- *
- * #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ...
- *
- * Selected arguments can be expanded in initializers. The op argument is
- * expanded followed by comma in the JSOp enum (jsopcode.h), e.g. The value
- * field must be dense for now, because jsopcode.c uses an OPDEF() expansion
- * inside the js_CodeSpec[] initializer.
- *
- * Field Description
- * op Bytecode name, which is the JSOp enumerator name
- * value Bytecode value, which is the JSOp enumerator value
- * name C string containing name for disassembler
- * image C string containing "image" for pretty-printer, null if ugly
- * length Number of bytes including any immediate operands
- * nuses Number of stack slots consumed by bytecode, -1 if variadic
- * ndefs Number of stack slots produced by bytecode
- * prec Operator precedence, zero if not an operator
- * format Bytecode plus immediate operand encoding format
- *
- * This file is best viewed with 116 columns:
-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
- */
-
-/* legend: op val name image len use def prec format */
-
-/* Longstanding JavaScript bytecodes. */
-OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_PUSH, 1, "push", NULL, 1, 0, 1, 0, JOF_BYTE)
-OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, 0, JOF_BYTE)
-OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, 0, JOF_BYTE)
-OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, 0, JOF_BYTE)
-OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, 0, JOF_BYTE)
-OPDEF(JSOP_GOTO, 6, "goto", NULL, 3, 0, 0, 0, JOF_JUMP)
-OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 3, 1, 0, 0, JOF_JUMP)
-OPDEF(JSOP_IFNE, 8, "ifne", NULL, 3, 1, 0, 0, JOF_JUMP)
-
-/* Get the arguments object for the current, lightweight function activation. */
-OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 12, JOF_BYTE)
-
-/* ECMA-compliant for-in loop with argument or local variable loop control. */
-OPDEF(JSOP_FORARG, 10, "forarg", NULL, 3, 0, 1, 0, JOF_QARG|JOF_NAME|JOF_FOR)
-OPDEF(JSOP_FORVAR, 11, "forvar", NULL, 3, 0, 1, 0, JOF_QVAR|JOF_NAME|JOF_FOR)
-
-/* More longstanding bytecodes. */
-OPDEF(JSOP_DUP, 12, "dup", NULL, 1, 1, 2, 0, JOF_BYTE)
-OPDEF(JSOP_DUP2, 13, "dup2", NULL, 1, 2, 4, 0, JOF_BYTE)
-OPDEF(JSOP_SETCONST, 14, "setconst", NULL, 3, 1, 1, 1, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
-OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 2, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 3, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 4, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_GE, 23, "ge", ">=", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_LSH, 24, "lsh", "<<", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_RSH, 25, "rsh", ">>", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_URSH, 26, "ursh", ">>>", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_ADD, 27, "add", "+", 1, 2, 1, 8, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_SUB, 28, "sub", "-", 1, 2, 1, 8, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_MUL, 29, "mul", "*", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_DIV, 30, "div", "/", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_MOD, 31, "mod", "%", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_NOT, 32, "not", "!", 1, 1, 1, 10, JOF_BYTE)
-OPDEF(JSOP_BITNOT, 33, "bitnot", "~", 1, 1, 1, 10, JOF_BYTE)
-OPDEF(JSOP_NEG, 34, "neg", "-", 1, 1, 1, 10, JOF_BYTE)
-OPDEF(JSOP_NEW, 35, js_new_str, NULL, 3, -1, 1, 10, JOF_UINT16)
-OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEL)
-OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEL)
-OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEL)
-OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE)
-OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 10, JOF_BYTE)
-OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC)
-OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC)
-OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC)
-OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC)
-OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC)
-OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC)
-OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
-OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC|JOF_POST)
-OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST)
-OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
-OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST)
-OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST)
-OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 3, 1, 1, 11, JOF_CONST|JOF_PROP)
-OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 1, JOF_CONST|JOF_PROP|JOF_SET|JOF_ASSIGNING)
-OPDEF(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, 11, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)
-OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_ASSIGNING)
-OPDEF(JSOP_PUSHOBJ, 57, "pushobj", NULL, 1, 0, 1, 0, JOF_BYTE)
-OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 11, JOF_UINT16)
-OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 12, JOF_CONST|JOF_NAME)
-OPDEF(JSOP_NUMBER, 60, "number", NULL, 3, 0, 1, 12, JOF_CONST)
-OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 12, JOF_CONST)
-OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 12, JOF_BYTE)
-OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 0, JOF_JUMP)
-OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 0, JOF_JUMP)
-
-/* The switch bytecodes have variable length. */
-OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH)
-OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH)
-
-/* New, infallible/transitive identity ops. */
-OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE)
-OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE)
-
-/* Lexical closure constructor. */
-OPDEF(JSOP_CLOSURE, 74, "closure", NULL, 3, 0, 0, 0, JOF_CONST)
-
-/* Export and import ops. */
-OPDEF(JSOP_EXPORTALL, 75, "exportall", NULL, 1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME)
-OPDEF(JSOP_IMPORTALL, 77, "importall", NULL, 1, 1, 0, 0, JOF_BYTE)
-OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP|JOF_IMPORT)
-OPDEF(JSOP_IMPORTELEM,79, "importelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM|JOF_IMPORT)
-
-/* Push object literal. */
-OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 12, JOF_CONST)
-
-/* Pop value and discard it. */
-OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 0, JOF_BYTE)
-
-/* Convert value to number, for unary +. */
-OPDEF(JSOP_POS, 82, "pos", "+", 1, 1, 1, 10, JOF_BYTE)
-
-/* Trap into debugger for breakpoint, etc. */
-OPDEF(JSOP_TRAP, 83, "trap", NULL, 1, 0, 0, 0, JOF_BYTE)
-
-/* Fast get/set ops for function arguments and local variables. */
-OPDEF(JSOP_GETARG, 84, "getarg", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME)
-OPDEF(JSOP_SETARG, 85, "setarg", NULL, 3, 1, 1, 1, JOF_QARG |JOF_NAME|JOF_SET|JOF_ASSIGNING)
-OPDEF(JSOP_GETVAR, 86, "getvar", NULL, 3, 0, 1, 12, JOF_QVAR |JOF_NAME)
-OPDEF(JSOP_SETVAR, 87, "setvar", NULL, 3, 1, 1, 1, JOF_QVAR |JOF_NAME|JOF_SET|JOF_ASSIGNING)
-
-/* Push unsigned 16-bit int constant. */
-OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 12, JOF_UINT16)
-
-/* Object and array literal support. */
-OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 1, 2, 1, 10, JOF_BYTE)
-OPDEF(JSOP_ENDINIT, 90, "endinit", NULL, 1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_INITPROP, 91, "initprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP)
-OPDEF(JSOP_INITELEM, 92, "initelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM)
-OPDEF(JSOP_DEFSHARP, 93, "defsharp", NULL, 3, 0, 0, 0, JOF_UINT16)
-OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 3, 0, 1, 0, JOF_UINT16)
-
-/* Fast inc/dec ops for args and local vars. */
-OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC)
-OPDEF(JSOP_INCVAR, 96, "incvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC)
-OPDEF(JSOP_DECARG, 97, "decarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC)
-OPDEF(JSOP_DECVAR, 98, "decvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC)
-OPDEF(JSOP_ARGINC, 99, "arginc", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
-OPDEF(JSOP_VARINC, 100,"varinc", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
-OPDEF(JSOP_ARGDEC, 101,"argdec", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
-OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
-
-/* ECMA-compliant for/in ops. */
-OPDEF(JSOP_TOOBJECT, 103,"toobject", NULL, 1, 1, 1, 0, JOF_BYTE)
-OPDEF(JSOP_FORNAME, 104,"forname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_FOR)
-OPDEF(JSOP_FORPROP, 105,"forprop", NULL, 3, 1, 1, 0, JOF_CONST|JOF_PROP|JOF_FOR)
-OPDEF(JSOP_FORELEM, 106,"forelem", NULL, 1, 2, 4, 0, JOF_BYTE |JOF_ELEM|JOF_FOR)
-OPDEF(JSOP_POP2, 107,"pop2", NULL, 1, 2, 0, 0, JOF_BYTE)
-
-/* ECMA-compliant assignment ops. */
-OPDEF(JSOP_BINDNAME, 108,"bindname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
-OPDEF(JSOP_SETNAME, 109,"setname", NULL, 3, 2, 1, 1, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
-
-/* Exception handling ops. */
-OPDEF(JSOP_THROW, 110,"throw", NULL, 1, 1, 0, 0, JOF_BYTE)
-
-/* 'in' and 'instanceof' ops. */
-OPDEF(JSOP_IN, 111,js_in_str, js_in_str, 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
-OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE|JOF_LEFTASSOC)
-
-/* debugger op */
-OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE)
-
-/* gosub/retsub for finally handling */
-OPDEF(JSOP_GOSUB, 114,"gosub", NULL, 3, 0, 1, 0, JOF_JUMP)
-OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE)
-
-/* More exception handling ops. */
-OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE)
-OPDEF(JSOP_SETSP, 117,"setsp", NULL, 3, 0, 0, 0, JOF_UINT16)
-
-/*
- * ECMA-compliant switch statement ops.
- * CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push
- * lval if false; and DEFAULT is POP lval and GOTO.
- */
-OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL, 1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_CASE, 119,"case", NULL, 3, 1, 0, 0, JOF_JUMP)
-OPDEF(JSOP_DEFAULT, 120,"default", NULL, 3, 1, 0, 0, JOF_JUMP)
-
-/*
- * ECMA-compliant call to eval op
- */
-OPDEF(JSOP_EVAL, 121,"eval", NULL, 3, -1, 1, 11, JOF_UINT16)
-
-/*
- * ECMA-compliant helper for 'for (x[i] in o)' loops.
- */
-OPDEF(JSOP_ENUMELEM, 122,"enumelem", NULL, 1, 3, 0, 1, JOF_BYTE |JOF_SET|JOF_ASSIGNING)
-
-/*
- * Getter and setter prefix bytecodes. These modify the next bytecode, either
- * an assignment or a property initializer code, which then defines a property
- * getter or setter.
- */
-OPDEF(JSOP_GETTER, 123,js_getter_str,js_getter_str,1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_SETTER, 124,js_setter_str,js_setter_str,1, 0, 0, 0, JOF_BYTE)
-
-/*
- * Prolog bytecodes for defining function, var, and const names.
- */
-OPDEF(JSOP_DEFFUN, 125,"deffun", NULL, 3, 0, 0, 0, JOF_CONST)
-OPDEF(JSOP_DEFCONST, 126,"defconst", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME)
-OPDEF(JSOP_DEFVAR, 127,"defvar", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME)
-
-/* Auto-clone (if needed due to re-parenting) and push an anonymous function. */
-OPDEF(JSOP_ANONFUNOBJ, 128, "anonfunobj", NULL, 3, 0, 1, 12, JOF_CONST)
-
-/* ECMA ed. 3 named function expression. */
-OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL, 3, 0, 1, 12, JOF_CONST)
-
-/* Like JSOP_INITPROP, but specialized to make a DontDelete property for ECMA ed. 3 catch variables. */
-OPDEF(JSOP_INITCATCHVAR,130, "initcatchvar",NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP)
-
-/* ECMA-mandated parenthesization opcode, which nulls the reference base register, obj; see jsinterp.c. */
-OPDEF(JSOP_GROUP, 131, "group", NULL, 1, 0, 0, 0, JOF_BYTE)
-
-/* Host object extension: given 'o.item(i) = j', the left-hand side compiles JSOP_SETCALL, rather than JSOP_CALL. */
-OPDEF(JSOP_SETCALL, 132, "setcall", NULL, 3, -1, 2, 11, JOF_UINT16|JOF_SET|JOF_ASSIGNING)
-
-/*
- * Exception handling no-ops, for more economical byte-coding than SRC_TRYFIN
- * srcnote-annotated JSOP_NOPs.
- */
-OPDEF(JSOP_TRY, 133,"try", NULL, 1, 0, 0, 0, JOF_BYTE)
-OPDEF(JSOP_FINALLY, 134,"finally", NULL, 1, 0, 0, 0, JOF_BYTE)
-
-/*
- * Swap the top two stack elements.
- * N.B. JSOP_SWAP doesn't swap the corresponding pc stack generating pcs, as
- * they're not needed for the current use of preserving the top-of-stack return
- * value when popping scopes while returning from catch blocks.
- */
-OPDEF(JSOP_SWAP, 135,"swap", NULL, 1, 2, 2, 0, JOF_BYTE)
-
-/*
- * Bytecodes that avoid making an arguments object in most cases:
- * JSOP_ARGSUB gets arguments[i] from fp->argv, iff i is in [0, fp->argc-1].
- * JSOP_ARGCNT returns fp->argc.
- */
-OPDEF(JSOP_ARGSUB, 136,"argsub", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME)
-OPDEF(JSOP_ARGCNT, 137,"argcnt", NULL, 1, 0, 1, 12, JOF_BYTE)
-
-/*
- * Define a local function object as a local variable.
- * The local variable's slot number is the first immediate two-byte operand.
- * The function object's atom index is the second immediate operand.
- */
-OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 5, 0, 0, 0, JOF_DEFLOCALVAR)
-
-/* Extended jumps. */
-OPDEF(JSOP_GOTOX, 139,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_IFEQX, 140,"ifeqx", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_IFNEX, 141,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_ORX, 142,"orx", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_ANDX, 143,"andx", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_GOSUBX, 144,"gosubx", NULL, 5, 0, 1, 0, JOF_JUMPX)
-OPDEF(JSOP_CASEX, 145,"casex", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_DEFAULTX, 146,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX)
-OPDEF(JSOP_TABLESWITCHX, 147,"tableswitchx",NULL, -1, 1, 0, 0, JOF_TABLESWITCHX)
-OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCHX)
-
-/* Placeholders for a real jump opcode set during backpatch chain fixup. */
-OPDEF(JSOP_BACKPATCH, 149,"backpatch",NULL, 3, 0, 0, 0, JOF_JUMP|JOF_BACKPATCH)
-OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL, 3, 1, 0, 0, JOF_JUMP|JOF_BACKPATCH)
-OPDEF(JSOP_BACKPATCH_PUSH,151,"backpatch_push",NULL, 3, 0, 1, 0, JOF_JUMP|JOF_BACKPATCH)
-
-/* Set and get return value pseudo-register in stack frame. */
-OPDEF(JSOP_SETRVAL, 152,"setrval", NULL, 1, 1, 0, 0, JOF_BYTE)
-OPDEF(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE)
diff --git a/src/extension/script/js/jsosdep.h b/src/extension/script/js/jsosdep.h
deleted file mode 100644
index c93eee2f1..000000000
--- a/src/extension/script/js/jsosdep.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsosdep_h___
-#define jsosdep_h___
-/*
- * OS (and machine, and compiler XXX) dependent information.
- */
-
-#if defined(XP_WIN) || defined(XP_OS2)
-
-#if defined(_WIN32) || defined (XP_OS2)
-#define JS_HAVE_LONG_LONG
-#else
-#undef JS_HAVE_LONG_LONG
-#endif
-#endif /* XP_WIN || XP_OS2 */
-
-#ifdef XP_MAC
-#define JS_HAVE_LONG_LONG
-
-JS_BEGIN_EXTERN_C
-
-#include <stddef.h>
-
-extern void* reallocSmaller(void* block, size_t newSize);
-
-extern char* strdup(const char* str);
-
-JS_END_EXTERN_C
-
-#endif /* XP_MAC */
-
-#ifdef XP_BEOS
-#define JS_HAVE_LONG_LONG
-#endif
-
-
-#ifdef XP_UNIX
-
-/*
- * Get OS specific header information.
- */
-#if defined(AIXV3) || defined(AIX)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(BSDI)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(HPUX)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(IRIX)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(linux)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(OSF1)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(_SCO_DS)
-#undef JS_HAVE_LONG_LONG
-
-#elif defined(SOLARIS)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(FREEBSD)
-#define JS_HAVE_LONG_LONG
-
-#elif defined(SUNOS4)
-#undef JS_HAVE_LONG_LONG
-
-/*
-** Missing function prototypes
-*/
-
-extern void *sbrk(int);
-
-#elif defined(UNIXWARE)
-#undef JS_HAVE_LONG_LONG
-
-#elif defined(VMS) && defined(__ALPHA)
-#define JS_HAVE_LONG_LONG
-
-#endif
-
-#endif /* XP_UNIX */
-
-#endif /* jsosdep_h___ */
-
diff --git a/src/extension/script/js/jsotypes.h b/src/extension/script/js/jsotypes.h
deleted file mode 100644
index ad8b5203e..000000000
--- a/src/extension/script/js/jsotypes.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * This section typedefs the old 'native' types to the new PR<type>s.
- * These definitions are scheduled to be eliminated at the earliest
- * possible time. The NSPR API is implemented and documented using
- * the new definitions.
- */
-
-/*
- * Note that we test for PROTYPES_H, not JSOTYPES_H. This is to avoid
- * double-definitions of scalar types such as uint32, if NSPR's
- * protypes.h is also included.
- */
-#ifndef PROTYPES_H
-#define PROTYPES_H
-
-#ifdef XP_BEOS
-/* BeOS defines most int types in SupportDefs.h (int8, uint8, int16,
- * uint16, int32, uint32, int64, uint64), so in the interest of
- * not conflicting with other definitions elsewhere we have to skip the
- * #ifdef jungle below, duplicate some definitions, and do our stuff.
- */
-#include <SupportDefs.h>
-
-typedef JSUintn uintn;
-#ifndef _XP_Core_
-typedef JSIntn intn;
-#endif
-
-#else
-
-/* SVR4 typedef of uint is commonly found on UNIX machines. */
-#ifdef XP_UNIX
-#include <sys/types.h>
-#else
-typedef JSUintn uint;
-#endif
-
-typedef JSUintn uintn;
-typedef JSUint64 uint64;
-#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
-typedef JSUint32 uint32;
-#else
-typedef unsigned long uint32;
-#endif
-typedef JSUint16 uint16;
-typedef JSUint8 uint8;
-
-#ifndef _XP_Core_
-typedef JSIntn intn;
-#endif
-
-/*
- * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very
- * common header file) defines the types int8, int16, int32, and int64.
- * So we don't define these four types here to avoid conflicts in case
- * the code also includes sys/types.h.
- */
-#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H)
-#include <sys/inttypes.h>
-#else
-typedef JSInt64 int64;
-
-/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
-#ifdef HPUX
-#include <model.h>
-#else
-#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
-typedef JSInt32 int32;
-#else
-typedef long int32;
-#endif
-typedef JSInt16 int16;
-typedef JSInt8 int8;
-#endif /* HPUX */
-#endif /* AIX && HAVE_SYS_INTTYPES_H */
-
-#endif /* XP_BEOS */
-
-typedef JSFloat64 float64;
-
-/* Re: jsbit.h */
-#define TEST_BIT JS_TEST_BIT
-#define SET_BIT JS_SET_BIT
-#define CLEAR_BIT JS_CLEAR_BIT
-
-/* Re: prarena.h->plarena.h */
-#define PRArena PLArena
-#define PRArenaPool PLArenaPool
-#define PRArenaStats PLArenaStats
-#define PR_ARENA_ALIGN PL_ARENA_ALIGN
-#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL
-#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE
-#define PR_ARENA_GROW PL_ARENA_GROW
-#define PR_ARENA_MARK PL_ARENA_MARK
-#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED
-#define PR_CLEAR_ARENA PL_CLEAR_ARENA
-#define PR_ARENA_RELEASE PL_ARENA_RELEASE
-#define PR_COUNT_ARENA PL_COUNT_ARENA
-#define PR_ARENA_DESTROY PL_ARENA_DESTROY
-#define PR_InitArenaPool PL_InitArenaPool
-#define PR_FreeArenaPool PL_FreeArenaPool
-#define PR_FinishArenaPool PL_FinishArenaPool
-#define PR_CompactArenaPool PL_CompactArenaPool
-#define PR_ArenaFinish PL_ArenaFinish
-#define PR_ArenaAllocate PL_ArenaAllocate
-#define PR_ArenaGrow PL_ArenaGrow
-#define PR_ArenaRelease PL_ArenaRelease
-#define PR_ArenaCountAllocation PL_ArenaCountAllocation
-#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth
-#define PR_ArenaCountGrowth PL_ArenaCountGrowth
-#define PR_ArenaCountRelease PL_ArenaCountRelease
-#define PR_ArenaCountRetract PL_ArenaCountRetract
-
-/* Re: prevent.h->plevent.h */
-#define PREvent PLEvent
-#define PREventQueue PLEventQueue
-#define PR_CreateEventQueue PL_CreateEventQueue
-#define PR_DestroyEventQueue PL_DestroyEventQueue
-#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor
-#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR
-#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR
-#define PR_PostEvent PL_PostEvent
-#define PR_PostSynchronousEvent PL_PostSynchronousEvent
-#define PR_GetEvent PL_GetEvent
-#define PR_EventAvailable PL_EventAvailable
-#define PREventFunProc PLEventFunProc
-#define PR_MapEvents PL_MapEvents
-#define PR_RevokeEvents PL_RevokeEvents
-#define PR_ProcessPendingEvents PL_ProcessPendingEvents
-#define PR_WaitForEvent PL_WaitForEvent
-#define PR_EventLoop PL_EventLoop
-#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD
-#define PRHandleEventProc PLHandleEventProc
-#define PRDestroyEventProc PLDestroyEventProc
-#define PR_InitEvent PL_InitEvent
-#define PR_GetEventOwner PL_GetEventOwner
-#define PR_HandleEvent PL_HandleEvent
-#define PR_DestroyEvent PL_DestroyEvent
-#define PR_DequeueEvent PL_DequeueEvent
-#define PR_GetMainEventQueue PL_GetMainEventQueue
-
-/* Re: prhash.h->plhash.h */
-#define PRHashEntry PLHashEntry
-#define PRHashTable PLHashTable
-#define PRHashNumber PLHashNumber
-#define PRHashFunction PLHashFunction
-#define PRHashComparator PLHashComparator
-#define PRHashEnumerator PLHashEnumerator
-#define PRHashAllocOps PLHashAllocOps
-#define PR_NewHashTable PL_NewHashTable
-#define PR_HashTableDestroy PL_HashTableDestroy
-#define PR_HashTableRawLookup PL_HashTableRawLookup
-#define PR_HashTableRawAdd PL_HashTableRawAdd
-#define PR_HashTableRawRemove PL_HashTableRawRemove
-#define PR_HashTableAdd PL_HashTableAdd
-#define PR_HashTableRemove PL_HashTableRemove
-#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries
-#define PR_HashTableLookup PL_HashTableLookup
-#define PR_HashTableDump PL_HashTableDump
-#define PR_HashString PL_HashString
-#define PR_CompareStrings PL_CompareStrings
-#define PR_CompareValues PL_CompareValues
-
-#ifdef XP_MAC
-#ifndef TRUE /* Mac standard is lower case true */
- #define TRUE 1
-#endif
-#ifndef FALSE /* Mac standard is lower case false */
- #define FALSE 0
-#endif
-#endif
-
-#endif /* !defined(PROTYPES_H) */
diff --git a/src/extension/script/js/jsparse.c b/src/extension/script/js/jsparse.c
deleted file mode 100644
index 7cf18d454..000000000
--- a/src/extension/script/js/jsparse.c
+++ /dev/null
@@ -1,3547 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS parser.
- *
- * This is a recursive-descent parser for the JavaScript language specified by
- * "The JavaScript 1.5 Language Specification". It uses lexical and semantic
- * feedback to disambiguate non-LL(1) structures. It generates trees of nodes
- * induced by the recursive parsing (not precise syntax trees, see jsparse.h).
- * After tree construction, it rewrites trees to fold constants and evaluate
- * compile-time expressions. Finally, it calls js_EmitTree (see jsemit.h) to
- * generate bytecode.
- *
- * This parser attempts no error recovery. The dense JSTokenType enumeration
- * was designed with error recovery built on 64-bit first and follow bitsets
- * in mind, however.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsparse.h"
-#include "jsscan.h"
-#include "jsscope.h"
-#include "jsscript.h"
-#include "jsstr.h"
-
-/*
- * JS parsers, from lowest to highest precedence.
- *
- * Each parser takes a context and a token stream, and emits bytecode using
- * a code generator.
- */
-
-typedef JSParseNode *
-JSParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc);
-
-typedef JSParseNode *
-JSMemberParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
- JSBool allowCallSyntax);
-
-static JSParser FunctionStmt;
-#if JS_HAS_LEXICAL_CLOSURE
-static JSParser FunctionExpr;
-#endif
-static JSParser Statements;
-static JSParser Statement;
-static JSParser Variables;
-static JSParser Expr;
-static JSParser AssignExpr;
-static JSParser CondExpr;
-static JSParser OrExpr;
-static JSParser AndExpr;
-static JSParser BitOrExpr;
-static JSParser BitXorExpr;
-static JSParser BitAndExpr;
-static JSParser EqExpr;
-static JSParser RelExpr;
-static JSParser ShiftExpr;
-static JSParser AddExpr;
-static JSParser MulExpr;
-static JSParser UnaryExpr;
-static JSMemberParser MemberExpr;
-static JSParser PrimaryExpr;
-
-/*
- * Insist that the next token be of type tt, or report errno and return null.
- * NB: this macro uses cx and ts from its lexical environment.
- */
-#define MUST_MATCH_TOKEN(tt, errno) \
- JS_BEGIN_MACRO \
- if (js_GetToken(cx, ts) != tt) { \
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, errno); \
- return NULL; \
- } \
- JS_END_MACRO
-
-#define CHECK_RECURSION() \
- JS_BEGIN_MACRO \
- int stackDummy; \
- if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { \
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, \
- JSMSG_OVER_RECURSED); \
- return NULL; \
- } \
- JS_END_MACRO
-
-#ifdef METER_PARSENODES
-static uint32 parsenodes = 0;
-static uint32 maxparsenodes = 0;
-static uint32 recyclednodes = 0;
-#endif
-
-static void
-RecycleTree(JSParseNode *pn, JSTreeContext *tc)
-{
- if (!pn)
- return;
- JS_ASSERT(pn != tc->nodeList); /* catch back-to-back dup recycles */
- pn->pn_next = tc->nodeList;
- tc->nodeList = pn;
-#ifdef METER_PARSENODES
- recyclednodes++;
-#endif
-}
-
-static JSParseNode *
-NewOrRecycledNode(JSContext *cx, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = tc->nodeList;
- if (!pn) {
- JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool);
- if (!pn)
- JS_ReportOutOfMemory(cx);
- } else {
- tc->nodeList = pn->pn_next;
-
- /* Recycle immediate descendents only, to save work and working set. */
- switch (pn->pn_arity) {
- case PN_FUNC:
- RecycleTree(pn->pn_body, tc);
- break;
- case PN_LIST:
- if (pn->pn_head) {
- /* XXX check for dup recycles in the list */
- *pn->pn_tail = tc->nodeList;
- tc->nodeList = pn->pn_head;
-#ifdef METER_PARSENODES
- recyclednodes += pn->pn_count;
-#endif
- }
- break;
- case PN_TERNARY:
- RecycleTree(pn->pn_kid1, tc);
- RecycleTree(pn->pn_kid2, tc);
- RecycleTree(pn->pn_kid3, tc);
- break;
- case PN_BINARY:
- RecycleTree(pn->pn_left, tc);
- RecycleTree(pn->pn_right, tc);
- break;
- case PN_UNARY:
- RecycleTree(pn->pn_kid, tc);
- break;
- case PN_NAME:
- RecycleTree(pn->pn_expr, tc);
- break;
- case PN_NULLARY:
- break;
- }
- }
- return pn;
-}
-
-/*
- * Allocate a JSParseNode from cx's temporary arena.
- */
-static JSParseNode *
-NewParseNode(JSContext *cx, JSToken *tok, JSParseNodeArity arity,
- JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = NewOrRecycledNode(cx, tc);
- if (!pn)
- return NULL;
- pn->pn_type = tok->type;
- pn->pn_pos = tok->pos;
- pn->pn_op = JSOP_NOP;
- pn->pn_arity = arity;
- pn->pn_next = NULL;
-#ifdef METER_PARSENODES
- parsenodes++;
- if (parsenodes - recyclednodes > maxparsenodes)
- maxparsenodes = parsenodes - recyclednodes;
-#endif
- return pn;
-}
-
-static JSParseNode *
-NewBinary(JSContext *cx, JSTokenType tt,
- JSOp op, JSParseNode *left, JSParseNode *right,
- JSTreeContext *tc)
-{
- JSParseNode *pn, *pn1, *pn2;
-
- if (!left || !right)
- return NULL;
-
- /*
- * Flatten a left-associative (left-heavy) tree of a given operator into
- * a list, to reduce js_FoldConstants and js_EmitTree recursion.
- */
- if (left->pn_type == tt &&
- left->pn_op == op &&
- (js_CodeSpec[op].format & JOF_LEFTASSOC)) {
- if (left->pn_arity != PN_LIST) {
- pn1 = left->pn_left, pn2 = left->pn_right;
- left->pn_arity = PN_LIST;
- PN_INIT_LIST_1(left, pn1);
- PN_APPEND(left, pn2);
- left->pn_extra = 0;
- if (tt == TOK_PLUS) {
- if (pn1->pn_type == TOK_STRING)
- left->pn_extra |= PNX_STRCAT;
- else if (pn1->pn_type != TOK_NUMBER)
- left->pn_extra |= PNX_CANTFOLD;
- if (pn2->pn_type == TOK_STRING)
- left->pn_extra |= PNX_STRCAT;
- else if (pn2->pn_type != TOK_NUMBER)
- left->pn_extra |= PNX_CANTFOLD;
- }
- }
- PN_APPEND(left, right);
- left->pn_pos.end = right->pn_pos.end;
- if (tt == TOK_PLUS) {
- if (right->pn_type == TOK_STRING)
- left->pn_extra |= PNX_STRCAT;
- else if (right->pn_type != TOK_NUMBER)
- left->pn_extra |= PNX_CANTFOLD;
- }
- return left;
- }
-
- /*
- * Fold constant addition immediately, to conserve node space and, what's
- * more, so js_FoldConstants never sees mixed addition and concatenation
- * operations with more than one leading non-string operand in a PN_LIST
- * generated for expressions such as 1 + 2 + "pt" (which should evaluate
- * to "3pt", not "12pt").
- */
- if (tt == TOK_PLUS &&
- left->pn_type == TOK_NUMBER &&
- right->pn_type == TOK_NUMBER) {
- left->pn_dval += right->pn_dval;
- RecycleTree(right, tc);
- return left;
- }
-
- pn = NewOrRecycledNode(cx, tc);
- if (!pn)
- return NULL;
- pn->pn_type = tt;
- pn->pn_pos.begin = left->pn_pos.begin;
- pn->pn_pos.end = right->pn_pos.end;
- pn->pn_op = op;
- pn->pn_arity = PN_BINARY;
- pn->pn_left = left;
- pn->pn_right = right;
- pn->pn_next = NULL;
-#ifdef METER_PARSENODES
- parsenodes++;
- if (parsenodes - recyclednodes > maxparsenodes)
- maxparsenodes = parsenodes - recyclednodes;
-#endif
- return pn;
-}
-
-#if JS_HAS_GETTER_SETTER
-static JSTokenType
-CheckGetterOrSetter(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
-{
- JSAtom *atom;
- JSRuntime *rt;
- JSOp op;
- const char *name;
-
- JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_NAME);
- atom = CURRENT_TOKEN(ts).t_atom;
- rt = cx->runtime;
- if (atom == rt->atomState.getterAtom)
- op = JSOP_GETTER;
- else if (atom == rt->atomState.setterAtom)
- op = JSOP_SETTER;
- else
- return TOK_NAME;
- if (js_PeekTokenSameLine(cx, ts) != tt)
- return TOK_NAME;
- (void) js_GetToken(cx, ts);
- if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_GETTER_OR_SETTER,
- (op == JSOP_GETTER)
- ? js_getter_str
- : js_setter_str);
- return TOK_ERROR;
- }
- CURRENT_TOKEN(ts).t_op = op;
- name = js_AtomToPrintableString(cx, atom);
- if (!name ||
- !js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_DEPRECATED_USAGE,
- name)) {
- return TOK_ERROR;
- }
- return tt;
-}
-#endif
-
-/*
- * Parse a top-level JS script.
- */
-JS_FRIEND_API(JSParseNode *)
-js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts)
-{
- JSStackFrame *fp, frame;
- JSTreeContext tc;
- JSParseNode *pn;
-
- /*
- * Push a compiler frame if we have no frames, or if the top frame is a
- * lightweight function activation, or if its scope chain doesn't match
- * the one passed to us.
- */
- fp = cx->fp;
- if (!fp || !fp->varobj || fp->scopeChain != chain) {
- memset(&frame, 0, sizeof frame);
- frame.varobj = frame.scopeChain = chain;
- if (cx->options & JSOPTION_VAROBJFIX) {
- while ((chain = JS_GetParent(cx, chain)) != NULL)
- frame.varobj = chain;
- }
- frame.down = fp;
- cx->fp = &frame;
- }
-
- /*
- * Protect atoms from being collected by a GC activation, which might
- * - nest on this thread due to out of memory (the so-called "last ditch"
- * GC attempted within js_AllocGCThing), or
- * - run for any reason on another thread if this thread is suspended on
- * an object lock before it finishes generating bytecode into a script
- * protected from the GC by a root or a stack frame reference.
- */
- JS_KEEP_ATOMS(cx->runtime);
- TREE_CONTEXT_INIT(&tc);
- pn = Statements(cx, ts, &tc);
- if (pn) {
- if (!js_MatchToken(cx, ts, TOK_EOF)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_SYNTAX_ERROR);
- pn = NULL;
- } else {
- pn->pn_type = TOK_LC;
- if (!js_FoldConstants(cx, pn, &tc))
- pn = NULL;
- }
- }
-
- TREE_CONTEXT_FINISH(&tc);
- JS_UNKEEP_ATOMS(cx->runtime);
- cx->fp = fp;
- return pn;
-}
-
-/*
- * Compile a top-level script.
- */
-JS_FRIEND_API(JSBool)
-js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
- JSCodeGenerator *cg)
-{
- JSStackFrame *fp, frame;
- JSParseNode *pn;
- JSBool ok;
-#ifdef METER_PARSENODES
- void *sbrk(ptrdiff_t), *before = sbrk(0);
-#endif
-
- /*
- * Push a compiler frame if we have no frames, or if the top frame is a
- * lightweight function activation, or if its scope chain doesn't match
- * the one passed to us.
- */
- fp = cx->fp;
- if (!fp || !fp->varobj || fp->scopeChain != chain) {
- memset(&frame, 0, sizeof frame);
- frame.varobj = frame.scopeChain = chain;
- if (cx->options & JSOPTION_VAROBJFIX) {
- while ((chain = JS_GetParent(cx, chain)) != NULL)
- frame.varobj = chain;
- }
- frame.down = fp;
- cx->fp = &frame;
- }
-
- /* Prevent GC activation while compiling. */
- JS_KEEP_ATOMS(cx->runtime);
-
- pn = Statements(cx, ts, &cg->treeContext);
- if (!pn) {
- ok = JS_FALSE;
- } else if (!js_MatchToken(cx, ts, TOK_EOF)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_SYNTAX_ERROR);
- ok = JS_FALSE;
- } else {
-#ifdef METER_PARSENODES
- printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n",
- (char *)sbrk(0) - (char *)before,
- parsenodes,
- maxparsenodes,
- parsenodes - recyclednodes);
- before = sbrk(0);
-#endif
-
- /*
- * No need to emit code here -- Statements already has, for each
- * statement in turn. Search for TCF_COMPILING in Statements, below.
- * That flag is set for every tc == &cg->treeContext, and it implies
- * that the tc can be downcast to a cg and used to emit code during
- * parsing, rather than at the end of the parse phase.
- */
- JS_ASSERT(cg->treeContext.flags & TCF_COMPILING);
- ok = JS_TRUE;
- }
-
-#ifdef METER_PARSENODES
- printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n",
- (char *)sbrk(0) - (char *)before, CG_OFFSET(cg), cg->noteCount);
-#endif
-#ifdef JS_ARENAMETER
- JS_DumpArenaStats(stdout);
-#endif
- JS_UNKEEP_ATOMS(cx->runtime);
- cx->fp = fp;
- return ok;
-}
-
-/*
- * Insist on a final return before control flows out of pn, but don't be too
- * smart about loops (do {...; return e2;} while(0) at the end of a function
- * that contains an early return e1 will get a strict-option-only warning).
- */
-static JSBool
-HasFinalReturn(JSParseNode *pn)
-{
- JSBool ok, hasDefault;
- JSParseNode *pn2, *pn3;
-
- switch (pn->pn_type) {
- case TOK_LC:
- if (!pn->pn_head)
- return JS_FALSE;
- return HasFinalReturn(PN_LAST(pn));
-
- case TOK_IF:
- ok = HasFinalReturn(pn->pn_kid2);
- ok &= pn->pn_kid3 && HasFinalReturn(pn->pn_kid3);
- return ok;
-
-#if JS_HAS_SWITCH_STATEMENT
- case TOK_SWITCH:
- ok = JS_TRUE;
- hasDefault = JS_FALSE;
- 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;
- JS_ASSERT(pn3->pn_type == TOK_LC);
- if (pn3->pn_head)
- ok &= HasFinalReturn(PN_LAST(pn3));
- }
- /* If a final switch has no default case, we judge it harshly. */
- ok &= hasDefault;
- return ok;
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
- case TOK_WITH:
- return HasFinalReturn(pn->pn_right);
-
- case TOK_RETURN:
- return JS_TRUE;
-
-#if JS_HAS_EXCEPTIONS
- case TOK_THROW:
- return JS_TRUE;
-
- case TOK_TRY:
- /* If we have a finally block that returns, we are done. */
- if (pn->pn_kid3 && HasFinalReturn(pn->pn_kid3))
- return JS_TRUE;
-
- /* Else check the try block and any and all catch statements. */
- ok = HasFinalReturn(pn->pn_kid1);
- if (pn->pn_kid2)
- ok &= HasFinalReturn(pn->pn_kid2);
- return ok;
-
- case TOK_CATCH:
- /* Check this block's code and iterate over further catch blocks. */
- ok = HasFinalReturn(pn->pn_kid3);
- for (pn2 = pn->pn_kid2; pn2; pn2 = pn2->pn_kid2)
- ok &= HasFinalReturn(pn2->pn_kid3);
- return ok;
-#endif
-
- default:
- return JS_FALSE;
- }
-}
-
-static JSBool
-ReportNoReturnValue(JSContext *cx, JSTokenStream *ts)
-{
- JSFunction *fun;
- JSBool ok;
-
- fun = cx->fp->fun;
- if (fun->atom) {
- char *name = js_GetStringBytes(ATOM_TO_STRING(fun->atom));
- ok = js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_NO_RETURN_VALUE, name);
- } else {
- ok = js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_ANON_NO_RETURN_VALUE);
- }
- return ok;
-}
-
-static JSBool
-CheckFinalReturn(JSContext *cx, JSTokenStream *ts, JSParseNode *pn)
-{
- return HasFinalReturn(pn) || ReportNoReturnValue(cx, ts);
-}
-
-static JSParseNode *
-FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
- JSTreeContext *tc)
-{
- JSStackFrame *fp, frame;
- JSObject *funobj;
- uintN oldflags;
- JSParseNode *pn;
-
- fp = cx->fp;
- funobj = fun->object;
- if (!fp || fp->fun != fun || fp->varobj != funobj ||
- fp->scopeChain != funobj) {
- memset(&frame, 0, sizeof frame);
- frame.fun = fun;
- frame.varobj = frame.scopeChain = funobj;
- frame.down = fp;
- cx->fp = &frame;
- }
-
- oldflags = tc->flags;
- tc->flags &= ~(TCF_RETURN_EXPR | TCF_RETURN_VOID);
- tc->flags |= TCF_IN_FUNCTION;
- pn = Statements(cx, ts, tc);
-
- /* Check for falling off the end of a function that returns a value. */
- if (pn && JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR)) {
- if (!CheckFinalReturn(cx, ts, pn))
- pn = NULL;
- }
-
- cx->fp = fp;
- tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
- return pn;
-}
-
-/*
- * Compile a JS function body, which might appear as the value of an event
- * handler attribute in an HTML <INPUT> tag.
- */
-JSBool
-js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun)
-{
- JSArenaPool codePool, notePool;
- JSCodeGenerator funcg;
- JSStackFrame *fp, frame;
- JSObject *funobj;
- JSParseNode *pn;
- JSBool ok;
-
- JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
- JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
- if (!js_InitCodeGenerator(cx, &funcg, &codePool, &notePool,
- ts->filename, ts->lineno,
- ts->principals)) {
- return JS_FALSE;
- }
-
- /* Prevent GC activation while compiling. */
- JS_KEEP_ATOMS(cx->runtime);
-
- /* Push a JSStackFrame for use by FunctionBody and js_EmitFunctionBody. */
- fp = cx->fp;
- funobj = fun->object;
- JS_ASSERT(!fp || fp->fun != fun || fp->varobj != funobj ||
- fp->scopeChain != funobj);
- memset(&frame, 0, sizeof frame);
- frame.fun = fun;
- frame.varobj = frame.scopeChain = funobj;
- frame.down = fp;
- cx->fp = &frame;
-
- /* Ensure that the body looks like a block statement to js_EmitTree. */
- CURRENT_TOKEN(ts).type = TOK_LC;
- pn = FunctionBody(cx, ts, fun, &funcg.treeContext);
- if (!pn) {
- ok = JS_FALSE;
- } else {
- /*
- * No need to emit code here -- Statements (via FunctionBody) already
- * has. See similar comment in js_CompileTokenStream, and bug 108257.
- */
- fun->script = js_NewScriptFromCG(cx, &funcg, fun);
- if (!fun->script) {
- ok = JS_FALSE;
- } else {
- if (funcg.treeContext.flags & TCF_FUN_HEAVYWEIGHT)
- fun->flags |= JSFUN_HEAVYWEIGHT;
- ok = JS_TRUE;
- }
- }
-
- /* Restore saved state and release code generation arenas. */
- cx->fp = fp;
- JS_UNKEEP_ATOMS(cx->runtime);
- js_FinishCodeGenerator(cx, &funcg);
- JS_FinishArenaPool(&codePool);
- JS_FinishArenaPool(&notePool);
- return ok;
-}
-
-static JSParseNode *
-FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
- JSBool lambda)
-{
- JSParseNode *pn, *body;
- JSOp op, prevop;
- JSAtom *funAtom, *argAtom;
- JSFunction *fun;
- JSObject *parent;
- JSObject *pobj;
- JSScopeProperty *sprop;
- uintN dupflag;
- JSBool ok;
- JSTreeContext funtc;
- JSAtomListElement *ale;
-
- /* Make a TOK_FUNCTION node. */
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_FUNC, tc);
- if (!pn)
- return NULL;
-#if JS_HAS_GETTER_SETTER
- op = CURRENT_TOKEN(ts).t_op;
-#endif
-
- /* Scan the optional function name into funAtom. */
- if (js_MatchToken(cx, ts, TOK_NAME))
- funAtom = CURRENT_TOKEN(ts).t_atom;
- else
- funAtom = NULL;
-
- /* Find the nearest variable-declaring scope and use it as our parent. */
- parent = cx->fp->varobj;
- fun = js_NewFunction(cx, NULL, NULL, 0, lambda ? JSFUN_LAMBDA : 0, parent,
- funAtom);
- if (!fun)
- return NULL;
-
-#if JS_HAS_GETTER_SETTER
- if (op != JSOP_NOP)
- fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
-#endif
-
- /* Now parse formal argument list and compute fun->nargs. */
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
- if (!js_MatchToken(cx, ts, TOK_RP)) {
- do {
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_MISSING_FORMAL);
- argAtom = CURRENT_TOKEN(ts).t_atom;
- pobj = NULL;
- if (!js_LookupProperty(cx, fun->object, (jsid)argAtom, &pobj,
- (JSProperty **)&sprop)) {
- return NULL;
- }
- dupflag = 0;
- if (sprop) {
- ok = JS_TRUE;
- if (pobj == fun->object &&
- sprop->getter == js_GetArgument) {
- const char *name = js_AtomToPrintableString(cx, argAtom);
-
- /*
- * A duplicate parameter name. We force a duplicate node
- * on the SCOPE_LAST_PROP(scope) list with the same id,
- * distinguished by the SPROP_IS_DUPLICATE flag, and not
- * mapped by an entry in scope.
- */
- ok = name &&
- js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_DUPLICATE_FORMAL,
- name);
-
- dupflag = SPROP_IS_DUPLICATE;
- }
- OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
- if (!ok)
- return NULL;
- sprop = NULL;
- }
- if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom,
- js_GetArgument, js_SetArgument,
- SPROP_INVALID_SLOT,
- JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_SHARED,
- SPROP_HAS_SHORTID | dupflag,
- fun->nargs)) {
- return NULL;
- }
- fun->nargs++;
- } while (js_MatchToken(cx, ts, TOK_COMMA));
-
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL);
- }
-
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);
- pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin;
-
- TREE_CONTEXT_INIT(&funtc);
- body = FunctionBody(cx, ts, fun, &funtc);
- if (!body)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
-
-#if JS_HAS_LEXICAL_CLOSURE
- /*
- * If we collected flags that indicate nested heavyweight functions, or
- * this function contains heavyweight-making statements (references to
- * __parent__ or __proto__; use of with, eval, import, or export; and
- * assignment to arguments), flag the function as heavyweight (requiring
- * a call object per invocation).
- */
- if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {
- fun->flags |= JSFUN_HEAVYWEIGHT;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- } else {
- /*
- * If this function is a named statement function not at top-level
- * (i.e. a JSOP_CLOSURE), or if it refers to unqualified names that
- * are not local args or vars (TCF_FUN_USES_NONLOCALS), then our
- * enclosing function, if any, must be heavyweight.
- */
- if ((!lambda && funAtom && tc->topStmt) ||
- (funtc.flags & TCF_FUN_USES_NONLOCALS)) {
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- }
- }
-#endif
-
- /*
- * Record names for function statements in tc->decls so we know when to
- * avoid optimizing variable references that might name a function.
- */
- if (!lambda && funAtom) {
- ATOM_LIST_SEARCH(ale, &tc->decls, funAtom);
- if (ale) {
- prevop = ALE_JSOP(ale);
- if (JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) {
- const char *name = js_AtomToPrintableString(cx, funAtom);
- if (!name ||
- !js_ReportCompileErrorNumber(cx, ts, NULL,
- (prevop != JSOP_DEFCONST)
- ? JSREPORT_WARNING |
- JSREPORT_STRICT
- : JSREPORT_ERROR,
- JSMSG_REDECLARED_VAR,
- (prevop == JSOP_DEFFUN ||
- prevop == JSOP_CLOSURE)
- ? js_function_str
- : (prevop == JSOP_DEFCONST)
- ? js_const_str
- : js_var_str,
- name)) {
- return NULL;
- }
- }
- if (tc->topStmt && prevop == JSOP_DEFVAR)
- tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
- } else {
- ale = js_IndexAtom(cx, funAtom, &tc->decls);
- if (!ale)
- return NULL;
- }
- ALE_SET_JSOP(ale, tc->topStmt ? JSOP_CLOSURE : JSOP_DEFFUN);
-
-#if JS_HAS_LEXICAL_CLOSURE
- /*
- * A function nested at top level inside another's body needs only a
- * local variable to bind its name to its value, and not an activation
- * object property (it might also need the activation property, if the
- * outer function contains with statements, e.g., but the stack slot
- * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a
- * JSOP_GETVAR bytecode).
- */
- if (!tc->topStmt && (tc->flags & TCF_IN_FUNCTION)) {
- JSStackFrame *fp;
- JSObject *varobj;
-
- /*
- * Define a property on the outer function so that LookupArgOrVar
- * can properly optimize accesses.
- *
- * XXX Here and in Variables, we use the function object's scope,
- * XXX arguably polluting it, when we could use a compiler-private
- * XXX scope structure. Tradition!
- */
- fp = cx->fp;
- varobj = fp->varobj;
- JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass);
- JS_ASSERT(fp->fun == (JSFunction *) JS_GetPrivate(cx, varobj));
- if (!js_DefineNativeProperty(cx, varobj, (jsid)funAtom,
- OBJECT_TO_JSVAL(fun->object),
- js_GetLocalVariable,
- js_SetLocalVariable,
- JSPROP_ENUMERATE,
- SPROP_HAS_SHORTID, fp->fun->nvars,
- NULL)) {
- return NULL;
- }
- fp->fun->nvars++;
- }
-#endif
- }
-
-#if JS_HAS_LEXICAL_CLOSURE
- if (lambda || !funAtom) {
- /*
- * ECMA ed. 3 standard: function expression, possibly anonymous (even
- * if at top-level, an unnamed function is an expression statement, not
- * a function declaration).
- */
- op = fun->atom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ;
- } else if (tc->topStmt) {
- /*
- * ECMA ed. 3 extension: a function expression statement not at the
- * top level, e.g., in a compound statement such as the "then" part
- * of an "if" statement, binds a closure only if control reaches that
- * sub-statement.
- */
- op = JSOP_CLOSURE;
- } else
-#endif
- op = JSOP_NOP;
-
- /*
- * Pending a better automatic GC root management scheme (see Mozilla bug
- * 40757, http://bugzilla.mozilla.org/show_bug.cgi?id=40757), we need to
- * atomize here to protect against a GC activation.
- */
- pn->pn_funAtom = js_AtomizeObject(cx, fun->object, 0);
- if (!pn->pn_funAtom)
- return NULL;
-
- pn->pn_op = op;
- pn->pn_body = body;
- pn->pn_flags = funtc.flags & TCF_FUN_FLAGS;
- pn->pn_tryCount = funtc.tryCount;
- TREE_CONTEXT_FINISH(&funtc);
- return pn;
-}
-
-static JSParseNode *
-FunctionStmt(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- return FunctionDef(cx, ts, tc, JS_FALSE);
-}
-
-#if JS_HAS_LEXICAL_CLOSURE
-static JSParseNode *
-FunctionExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- return FunctionDef(cx, ts, tc, JS_TRUE);
-}
-#endif
-
-/*
- * Parse the statements in a block, creating a TOK_LC node that lists the
- * statements' trees. If called from block-parsing code, the caller must
- * match { before and } after.
- */
-static JSParseNode *
-Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2;
- JSTokenType tt;
-
- CHECK_RECURSION();
-
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- PN_INIT_LIST(pn);
-
- ts->flags |= TSF_REGEXP;
- while ((tt = js_PeekToken(cx, ts)) > TOK_EOF && tt != TOK_RC) {
- ts->flags &= ~TSF_REGEXP;
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- ts->flags |= TSF_REGEXP;
-
- /* If compiling top-level statements, emit as we go to save space. */
- if (!tc->topStmt && (tc->flags & TCF_COMPILING)) {
- if (cx->fp->fun &&
- JS_HAS_STRICT_OPTION(cx) &&
- (tc->flags & TCF_RETURN_EXPR)) {
- /*
- * Check pn2 for lack of a final return statement if it is the
- * last statement in the block.
- */
- tt = js_PeekToken(cx, ts);
- if ((tt == TOK_EOF || tt == TOK_RC) &&
- !CheckFinalReturn(cx, ts, pn2)) {
- tt = TOK_ERROR;
- break;
- }
-
- /*
- * Clear TCF_RETURN_EXPR so FunctionBody doesn't try to
- * CheckFinalReturn again.
- */
- tc->flags &= ~TCF_RETURN_EXPR;
- }
- if (!js_FoldConstants(cx, pn2, tc) ||
- !js_AllocTryNotes(cx, (JSCodeGenerator *)tc) ||
- !js_EmitTree(cx, (JSCodeGenerator *)tc, pn2)) {
- tt = TOK_ERROR;
- break;
- }
- RecycleTree(pn2, tc);
- } else {
- PN_APPEND(pn, pn2);
- }
- }
- ts->flags &= ~TSF_REGEXP;
- if (tt == TOK_ERROR)
- return NULL;
-
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- return pn;
-}
-
-static JSParseNode *
-Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2;
-
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);
- pn = Expr(cx, ts, tc);
- if (!pn)
- return NULL;
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);
-
- /*
- * Check for (a = b) and "correct" it to (a == b) iff b's operator has
- * greater precedence than ==.
- * XXX not ECMA, but documented in several books -- now a strict warning.
- */
- if (pn->pn_type == TOK_ASSIGN &&
- pn->pn_op == JSOP_NOP &&
- pn->pn_right->pn_type > TOK_EQOP)
- {
- JSBool rewrite = !JSVERSION_IS_ECMA(cx->version);
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING | JSREPORT_STRICT,
- JSMSG_EQUAL_AS_ASSIGN,
- rewrite
- ? "\nAssuming equality test"
- : "")) {
- return NULL;
- }
- if (rewrite) {
- pn->pn_type = TOK_EQOP;
- pn->pn_op = (JSOp)cx->jsop_eq;
- pn2 = pn->pn_left;
- switch (pn2->pn_op) {
- case JSOP_SETNAME:
- pn2->pn_op = JSOP_NAME;
- break;
- case JSOP_SETPROP:
- pn2->pn_op = JSOP_GETPROP;
- break;
- case JSOP_SETELEM:
- pn2->pn_op = JSOP_GETELEM;
- break;
- default:
- JS_ASSERT(0);
- }
- }
- }
- return pn;
-}
-
-static JSBool
-MatchLabel(JSContext *cx, JSTokenStream *ts, JSParseNode *pn)
-{
- JSAtom *label;
-#if JS_HAS_LABEL_STATEMENT
- JSTokenType tt;
-
- tt = js_PeekTokenSameLine(cx, ts);
- if (tt == TOK_ERROR)
- return JS_FALSE;
- if (tt == TOK_NAME) {
- (void) js_GetToken(cx, ts);
- label = CURRENT_TOKEN(ts).t_atom;
- } else {
- label = NULL;
- }
-#else
- label = NULL;
-#endif
- pn->pn_atom = label;
- return JS_TRUE;
-}
-
-#if JS_HAS_EXPORT_IMPORT
-static JSParseNode *
-ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2, *pn3;
- JSTokenType tt;
-
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn)
- return NULL;
- pn->pn_op = JSOP_NAME;
- pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
- pn->pn_expr = NULL;
- pn->pn_slot = -1;
- pn->pn_attrs = 0;
-
- ts->flags |= TSF_REGEXP;
- while ((tt = js_GetToken(cx, ts)) == TOK_DOT || tt == TOK_LB) {
- ts->flags &= ~TSF_REGEXP;
- if (pn->pn_op == JSOP_IMPORTALL)
- goto bad_import;
-
- if (tt == TOK_DOT) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn2)
- return NULL;
- if (js_MatchToken(cx, ts, TOK_STAR)) {
- pn2->pn_op = JSOP_IMPORTALL;
- pn2->pn_atom = NULL;
- } else {
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
- pn2->pn_op = JSOP_GETPROP;
- pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
- pn2->pn_slot = -1;
- pn2->pn_attrs = 0;
- }
- pn2->pn_expr = pn;
- pn2->pn_pos.begin = pn->pn_pos.begin;
- pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- } else {
- /* Make a TOK_LB node. */
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn2)
- return NULL;
- pn3 = Expr(cx, ts, tc);
- if (!pn3)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
- pn2->pn_pos.begin = pn->pn_pos.begin;
- pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
-
- pn2->pn_op = JSOP_GETELEM;
- pn2->pn_left = pn;
- pn2->pn_right = pn3;
- }
-
- pn = pn2;
- ts->flags |= TSF_REGEXP;
- }
- ts->flags &= ~TSF_REGEXP;
- if (tt == TOK_ERROR)
- return NULL;
- js_UngetToken(ts);
-
- switch (pn->pn_op) {
- case JSOP_GETPROP:
- pn->pn_op = JSOP_IMPORTPROP;
- break;
- case JSOP_GETELEM:
- pn->pn_op = JSOP_IMPORTELEM;
- break;
- case JSOP_IMPORTALL:
- break;
- default:
- goto bad_import;
- }
- return pn;
-
- bad_import:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, JSMSG_BAD_IMPORT);
- return NULL;
-}
-#endif /* JS_HAS_EXPORT_IMPORT */
-
-extern const char js_with_statement_str[];
-
-static JSParseNode *
-Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSTokenType tt;
- JSParseNode *pn, *pn1, *pn2, *pn3, *pn4;
- JSStmtInfo stmtInfo, *stmt, *stmt2;
- JSAtom *label;
-
- ts->flags |= TSF_REGEXP;
- tt = js_GetToken(cx, ts);
- ts->flags &= ~TSF_REGEXP;
-
-#if JS_HAS_GETTER_SETTER
- if (tt == TOK_NAME) {
- tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
- if (tt == TOK_ERROR)
- return NULL;
- }
-#endif
-
- switch (tt) {
-#if JS_HAS_EXPORT_IMPORT
- case TOK_EXPORT:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- PN_INIT_LIST(pn);
- if (js_MatchToken(cx, ts, TOK_STAR)) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn2)
- return NULL;
- PN_APPEND(pn, pn2);
- } else {
- do {
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn2)
- return NULL;
- pn2->pn_op = JSOP_NAME;
- pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
- pn2->pn_expr = NULL;
- pn2->pn_slot = -1;
- pn2->pn_attrs = 0;
- PN_APPEND(pn, pn2);
- } while (js_MatchToken(cx, ts, TOK_COMMA));
- }
- pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- break;
-
- case TOK_IMPORT:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- PN_INIT_LIST(pn);
- do {
- pn2 = ImportExpr(cx, ts, tc);
- if (!pn2)
- return NULL;
- PN_APPEND(pn, pn2);
- } while (js_MatchToken(cx, ts, TOK_COMMA));
- pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- break;
-#endif /* JS_HAS_EXPORT_IMPORT */
-
- case TOK_FUNCTION:
- return FunctionStmt(cx, ts, tc);
-
- case TOK_IF:
- /* An IF node has three kids: condition, then, and optional else. */
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
- if (!pn)
- return NULL;
- pn1 = Condition(cx, ts, tc);
- if (!pn1)
- return NULL;
- js_PushStatement(tc, &stmtInfo, STMT_IF, -1);
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- if (js_MatchToken(cx, ts, TOK_ELSE)) {
- stmtInfo.type = STMT_ELSE;
- pn3 = Statement(cx, ts, tc);
- if (!pn3)
- return NULL;
- pn->pn_pos.end = pn3->pn_pos.end;
- } else {
- pn3 = NULL;
- pn->pn_pos.end = pn2->pn_pos.end;
- }
- js_PopStatement(tc);
- pn->pn_kid1 = pn1;
- pn->pn_kid2 = pn2;
- pn->pn_kid3 = pn3;
- return pn;
-
-#if JS_HAS_SWITCH_STATEMENT
- case TOK_SWITCH:
- {
- JSParseNode *pn5;
- JSBool seenDefault = JS_FALSE;
-
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn)
- return NULL;
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
-
- /* pn1 points to the switch's discriminant. */
- pn1 = Expr(cx, ts, tc);
- if (!pn1)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
-
- /* pn2 is a list of case nodes. The default case has pn_left == NULL */
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn2)
- return NULL;
- PN_INIT_LIST(pn2);
-
- js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
-
- while ((tt = js_GetToken(cx, ts)) != TOK_RC) {
- switch (tt) {
- case TOK_DEFAULT:
- if (seenDefault) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_TOO_MANY_DEFAULTS);
- return NULL;
- }
- seenDefault = JS_TRUE;
- /* fall through */
-
- case TOK_CASE:
- pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn3)
- return NULL;
- if (tt == TOK_DEFAULT) {
- pn3->pn_left = NULL;
- } else {
- pn3->pn_left = Expr(cx, ts, tc);
- if (!pn3->pn_left)
- return NULL;
- }
- PN_APPEND(pn2, pn3);
- if (pn2->pn_count == JS_BIT(16)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_TOO_MANY_CASES);
- return NULL;
- }
- break;
-
- case TOK_ERROR:
- return NULL;
-
- default:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_SWITCH);
- return NULL;
- }
- MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
-
- pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn4)
- return NULL;
- pn4->pn_type = TOK_LC;
- PN_INIT_LIST(pn4);
- while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&
- tt != TOK_CASE && tt != TOK_DEFAULT) {
- if (tt == TOK_ERROR)
- return NULL;
- pn5 = Statement(cx, ts, tc);
- if (!pn5)
- return NULL;
- pn4->pn_pos.end = pn5->pn_pos.end;
- PN_APPEND(pn4, pn5);
- }
-
- /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */
- if (pn4->pn_head)
- pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin;
- pn3->pn_pos.end = pn4->pn_pos.end;
- pn3->pn_right = pn4;
- }
-
- js_PopStatement(tc);
-
- pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- pn->pn_kid1 = pn1;
- pn->pn_kid2 = pn2;
- return pn;
- }
-#endif /* JS_HAS_SWITCH_STATEMENT */
-
- case TOK_WHILE:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn)
- return NULL;
- js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
- pn2 = Condition(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_left = pn2;
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- js_PopStatement(tc);
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_right = pn2;
- return pn;
-
-#if JS_HAS_DO_WHILE_LOOP
- case TOK_DO:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn)
- return NULL;
- js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_left = pn2;
- MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
- pn2 = Condition(cx, ts, tc);
- if (!pn2)
- return NULL;
- js_PopStatement(tc);
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_right = pn2;
- break;
-#endif /* JS_HAS_DO_WHILE_LOOP */
-
- case TOK_FOR:
- /* A FOR node is binary, left is loop control and right is the body. */
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn)
- return NULL;
- js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
-
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
- tt = js_PeekToken(cx, ts);
- if (tt == TOK_SEMI) {
- /* No initializer -- set first kid of left sub-node to null. */
- pn1 = NULL;
- } else {
- /* Set pn1 to a var list or an initializing expression. */
-#if JS_HAS_IN_OPERATOR
- /*
- * Set the TCF_IN_FOR_INIT flag during parsing of the first clause
- * of the for statement. This flag will be used by the RelExpr
- * production; if it is set, then the 'in' keyword will not be
- * recognized as an operator, leaving it available to be parsed as
- * part of a for/in loop. A side effect of this restriction is
- * that (unparenthesized) expressions involving an 'in' operator
- * are illegal in the init clause of an ordinary for loop.
- */
- tc->flags |= TCF_IN_FOR_INIT;
-#endif /* JS_HAS_IN_OPERATOR */
- if (tt == TOK_VAR) {
- (void) js_GetToken(cx, ts);
- pn1 = Variables(cx, ts, tc);
- } else {
- pn1 = Expr(cx, ts, tc);
- }
-#if JS_HAS_IN_OPERATOR
- tc->flags &= ~TCF_IN_FOR_INIT;
-#endif /* JS_HAS_IN_OPERATOR */
- if (!pn1)
- return NULL;
- }
-
- /*
- * We can be sure that it's a for/in loop if there's still an 'in'
- * keyword here, even if JavaScript recognizes 'in' as an operator,
- * as we've excluded 'in' from being parsed in RelExpr by setting
- * the TCF_IN_FOR_INIT flag in our JSTreeContext.
- */
- if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
- stmtInfo.type = STMT_FOR_IN_LOOP;
-
- /* Check that the left side of the 'in' is valid. */
- if ((pn1->pn_type == TOK_VAR)
- ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST)
- : (pn1->pn_type != TOK_NAME &&
- pn1->pn_type != TOK_DOT &&
- pn1->pn_type != TOK_LB)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_FOR_LEFTSIDE);
- return NULL;
- }
-
- if (pn1->pn_type == TOK_VAR) {
- /* Tell js_EmitTree(TOK_VAR) to generate a final POP. */
- pn1->pn_extra = JS_TRUE;
- pn2 = pn1->pn_head;
- } else {
- pn2 = pn1;
- }
-
- /* Beware 'for (arguments in ...)' with or without a 'var'. */
- if (pn2->pn_type == TOK_NAME &&
- pn2->pn_atom == cx->runtime->atomState.argumentsAtom) {
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- }
-
- /* Parse the object expression as the right operand of 'in'. */
- pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc);
- if (!pn2)
- return NULL;
- pn->pn_left = pn2;
- } else {
- /* Parse the loop condition or null into pn2. */
- MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);
- if (js_PeekToken(cx, ts) == TOK_SEMI) {
- pn2 = NULL;
- } else {
- pn2 = Expr(cx, ts, tc);
- if (!pn2)
- return NULL;
- }
-
- /* Parse the update expression or null into pn3. */
- MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);
- if (js_PeekToken(cx, ts) == TOK_RP) {
- pn3 = NULL;
- } else {
- pn3 = Expr(cx, ts, tc);
- if (!pn3)
- return NULL;
- }
-
- /* Build the RESERVED node to use as the left kid of pn. */
- pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
- if (!pn4)
- return NULL;
- pn4->pn_type = TOK_RESERVED;
- pn4->pn_op = JSOP_NOP;
- pn4->pn_kid1 = pn1;
- pn4->pn_kid2 = pn2;
- pn4->pn_kid3 = pn3;
- pn->pn_left = pn4;
- }
-
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
-
- /* Parse the loop body into pn->pn_right. */
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_right = pn2;
- js_PopStatement(tc);
-
- /* Record the absolute line number for source note emission. */
- pn->pn_pos.end = pn2->pn_pos.end;
- return pn;
-
-#if JS_HAS_EXCEPTIONS
- case TOK_TRY: {
- JSParseNode *catchtail = NULL;
- /*
- * try nodes are ternary.
- * kid1 is the try Statement
- * kid2 is the catch node
- * kid3 is the finally Statement
- *
- * catch nodes are ternary.
- * kid1 is the discriminant
- * kid2 is the next catch node, or NULL
- * kid3 is the catch block (on kid3 so that we can always append a
- * new catch pn on catchtail->kid2)
- *
- * catch discriminant nodes are binary
- * atom is the receptacle
- * expr is the discriminant code
- *
- * finally nodes are unary (just the finally expression)
- */
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
- pn->pn_op = JSOP_NOP;
-
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
- js_PushStatement(tc, &stmtInfo, STMT_TRY, -1);
- pn->pn_kid1 = Statements(cx, ts, tc);
- if (!pn->pn_kid1)
- return NULL;
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
- js_PopStatement(tc);
-
- catchtail = pn;
- while (js_PeekToken(cx, ts) == TOK_CATCH) {
- /* check for another catch after unconditional catch */
- if (catchtail != pn && !catchtail->pn_kid1->pn_expr) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_CATCH_AFTER_GENERAL);
- return NULL;
- }
-
- /*
- * legal catch forms are:
- * catch (v)
- * catch (v if <boolean_expression>)
- * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
- */
- (void) js_GetToken(cx, ts); /* eat `catch' */
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
- if (!pn2)
- return NULL;
-
- /*
- * We use a PN_NAME for the discriminant (catchguard) node
- * with the actual discriminant code in the initializer spot
- */
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER);
- pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn3)
- return NULL;
-
- pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
- pn3->pn_expr = NULL;
-#if JS_HAS_CATCH_GUARD
- /*
- * We use `catch (x if x === 5)' (not `catch (x : x === 5)') to
- * avoid conflicting with the JS2/ECMA2 proposed catchguard syntax.
- */
- if (js_PeekToken(cx, ts) == TOK_IF) {
- (void)js_GetToken(cx, ts); /* eat `if' */
- pn3->pn_expr = Expr(cx, ts, tc);
- if (!pn3->pn_expr)
- return NULL;
- }
-#endif
- pn2->pn_kid1 = pn3;
-
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
-
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
- js_PushStatement(tc, &stmtInfo, STMT_CATCH, -1);
- stmtInfo.label = pn3->pn_atom;
- pn2->pn_kid3 = Statements(cx, ts, tc);
- if (!pn2->pn_kid3)
- return NULL;
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
- js_PopStatement(tc);
-
- catchtail = catchtail->pn_kid2 = pn2;
- }
- catchtail->pn_kid2 = NULL;
-
- if (js_MatchToken(cx, ts, TOK_FINALLY)) {
- tc->tryCount++;
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
- js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1);
- pn->pn_kid3 = Statements(cx, ts, tc);
- if (!pn->pn_kid3)
- return NULL;
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
- js_PopStatement(tc);
- } else {
- pn->pn_kid3 = NULL;
- }
- if (!pn->pn_kid2 && !pn->pn_kid3) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_CATCH_OR_FINALLY);
- return NULL;
- }
- tc->tryCount++;
- return pn;
- }
-
- case TOK_THROW:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn2 = Expr(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_op = JSOP_THROW;
- pn->pn_kid = pn2;
- break;
-
- /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
- case TOK_CATCH:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_CATCH_WITHOUT_TRY);
- return NULL;
-
- case TOK_FINALLY:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_FINALLY_WITHOUT_TRY);
- return NULL;
-
-#endif /* JS_HAS_EXCEPTIONS */
-
- case TOK_BREAK:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- if (!MatchLabel(cx, ts, pn))
- return NULL;
- stmt = tc->topStmt;
- label = pn->pn_atom;
- if (label) {
- for (; ; stmt = stmt->down) {
- if (!stmt) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_LABEL_NOT_FOUND);
- return NULL;
- }
- if (stmt->type == STMT_LABEL && stmt->label == label)
- break;
- }
- } else {
- for (; ; stmt = stmt->down) {
- if (!stmt) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_TOUGH_BREAK);
- return NULL;
- }
- if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)
- break;
- }
- }
- if (label)
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- break;
-
- case TOK_CONTINUE:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- if (!MatchLabel(cx, ts, pn))
- return NULL;
- stmt = tc->topStmt;
- label = pn->pn_atom;
- if (label) {
- for (stmt2 = NULL; ; stmt = stmt->down) {
- if (!stmt) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_LABEL_NOT_FOUND);
- return NULL;
- }
- if (stmt->type == STMT_LABEL) {
- if (stmt->label == label) {
- if (!stmt2 || !STMT_IS_LOOP(stmt2)) {
- js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_ERROR,
- JSMSG_BAD_CONTINUE);
- return NULL;
- }
- break;
- }
- } else {
- stmt2 = stmt;
- }
- }
- } else {
- for (; ; stmt = stmt->down) {
- if (!stmt) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_CONTINUE);
- return NULL;
- }
- if (STMT_IS_LOOP(stmt))
- break;
- }
- }
- if (label)
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- break;
-
- case TOK_WITH:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn)
- return NULL;
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
- pn2 = Expr(cx, ts, tc);
- if (!pn2)
- return NULL;
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
- pn->pn_left = pn2;
-
- js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);
- pn2 = Statement(cx, ts, tc);
- if (!pn2)
- return NULL;
- js_PopStatement(tc);
-
- /* Deprecate after parsing, in case of WERROR option. */
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING | JSREPORT_STRICT,
- JSMSG_DEPRECATED_USAGE,
- js_with_statement_str)) {
- return NULL;
- }
-
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_right = pn2;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- return pn;
-
- case TOK_VAR:
- pn = Variables(cx, ts, tc);
- if (!pn)
- return NULL;
-
- /* Tell js_EmitTree to generate a final POP. */
- pn->pn_extra = JS_TRUE;
- break;
-
- case TOK_RETURN:
- if (!(tc->flags & TCF_IN_FUNCTION)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_RETURN);
- return NULL;
- }
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
-
- /* This is ugly, but we don't want to require a semicolon. */
- ts->flags |= TSF_REGEXP;
- tt = js_PeekTokenSameLine(cx, ts);
- ts->flags &= ~TSF_REGEXP;
- if (tt == TOK_ERROR)
- return NULL;
-
- if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
- pn2 = Expr(cx, ts, tc);
- if (!pn2)
- return NULL;
- tc->flags |= TCF_RETURN_EXPR;
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_kid = pn2;
- } else {
- tc->flags |= TCF_RETURN_VOID;
- pn->pn_kid = NULL;
- }
-
- if (JS_HAS_STRICT_OPTION(cx) &&
- (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0) {
- /*
- * We must be in a frame with a non-native function, because
- * we're compiling one.
- */
- if (!ReportNoReturnValue(cx, ts))
- return NULL;
- }
- break;
-
- case TOK_LC:
- js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
- pn = Statements(cx, ts, tc);
- if (!pn)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
- js_PopStatement(tc);
- return pn;
-
- case TOK_EOL:
- case TOK_SEMI:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_SEMI;
- pn->pn_kid = NULL;
- return pn;
-
-#if JS_HAS_DEBUGGER_KEYWORD
- case TOK_DEBUGGER:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_DEBUGGER;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- break;
-#endif /* JS_HAS_DEBUGGER_KEYWORD */
-
- case TOK_ERROR:
- return NULL;
-
- default:
- js_UngetToken(ts);
- pn2 = Expr(cx, ts, tc);
- if (!pn2)
- return NULL;
-
- if (js_PeekToken(cx, ts) == TOK_COLON) {
- if (pn2->pn_type != TOK_NAME) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_LABEL);
- return NULL;
- }
- label = pn2->pn_atom;
- for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
- if (stmt->type == STMT_LABEL && stmt->label == label) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_DUPLICATE_LABEL);
- return NULL;
- }
- }
- (void) js_GetToken(cx, ts);
-
- /* Push a label struct and parse the statement. */
- js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1);
- stmtInfo.label = label;
- pn = Statement(cx, ts, tc);
- if (!pn)
- return NULL;
-
- /* Pop the label, set pn_expr, and return early. */
- js_PopStatement(tc);
- pn2->pn_type = TOK_COLON;
- pn2->pn_pos.end = pn->pn_pos.end;
- pn2->pn_expr = pn;
- return pn2;
- }
-
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_SEMI;
- pn->pn_pos = pn2->pn_pos;
- pn->pn_kid = pn2;
- break;
- }
-
- /* Check termination of this primitive statement. */
- if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
- tt = js_PeekTokenSameLine(cx, ts);
- if (tt == TOK_ERROR)
- return NULL;
- if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_SEMI_BEFORE_STMNT);
- return NULL;
- }
- }
-
- (void) js_MatchToken(cx, ts, TOK_SEMI);
- return pn;
-}
-
-static JSParseNode *
-Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2;
- JSObject *obj, *pobj;
- JSStackFrame *fp;
- JSFunction *fun;
- JSClass *clasp;
- JSPropertyOp getter, setter, currentGetter, currentSetter;
- JSAtom *atom;
- JSAtomListElement *ale;
- JSOp prevop;
- JSProperty *prop;
- JSScopeProperty *sprop;
- JSBool ok;
-
- /*
- * The tricky part of this code is to create special parsenode opcodes for
- * getting and setting variables (which will be stored as special slots in
- * the frame). The complex special case is an eval() inside a function.
- * If the evaluated string references variables in the enclosing function,
- * then we need to generate the special variable opcodes. We determine
- * this by looking up the variable id in the current variable scope.
- */
- JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_VAR);
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- pn->pn_op = CURRENT_TOKEN(ts).t_op;
- pn->pn_extra = JS_FALSE; /* assume no JSOP_POP needed */
- PN_INIT_LIST(pn);
-
- /*
- * Skip eval and debugger frames when looking for the function whose code
- * is being compiled. If we are called from FunctionBody, TCF_IN_FUNCTION
- * will be set in tc->flags, and we can be sure fp->fun is the function to
- * use. But if a function calls eval, the string argument is treated as a
- * Program (per ECMA), so TCF_IN_FUNCTION won't be set.
- *
- * What's more, when the following code is reached from eval, cx->fp->fun
- * is eval's JSFunction (a native function), so we need to skip its frame.
- * We should find the scripted caller's function frame just below it, but
- * we code a loop out of paranoia.
- */
- for (fp = cx->fp; (fp->flags & JSFRAME_SPECIAL) && fp->down; fp = fp->down)
- continue;
- obj = fp->varobj;
- fun = fp->fun;
- clasp = OBJ_GET_CLASS(cx, obj);
- if (fun && clasp == &js_FunctionClass) {
- /* We are compiling code inside a function */
- getter = js_GetLocalVariable;
- setter = js_SetLocalVariable;
- } else if (fun && clasp == &js_CallClass) {
- /* We are compiling code from an eval inside a function */
- getter = js_GetCallVariable;
- setter = js_SetCallVariable;
- } else {
- getter = clasp->getProperty;
- setter = clasp->setProperty;
- }
-
- ok = JS_TRUE;
- do {
- currentGetter = getter;
- currentSetter = setter;
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_VARIABLE_NAME);
- atom = CURRENT_TOKEN(ts).t_atom;
-
- ATOM_LIST_SEARCH(ale, &tc->decls, atom);
- if (ale) {
- prevop = ALE_JSOP(ale);
- if (JS_HAS_STRICT_OPTION(cx) ||
- pn->pn_op == JSOP_DEFCONST ||
- prevop == JSOP_DEFCONST) {
- const char *name = js_AtomToPrintableString(cx, atom);
- if (!name ||
- !js_ReportCompileErrorNumber(cx, ts, NULL,
- (pn->pn_op != JSOP_DEFCONST &&
- prevop != JSOP_DEFCONST)
- ? JSREPORT_WARNING |
- JSREPORT_STRICT
- : JSREPORT_ERROR,
- JSMSG_REDECLARED_VAR,
- (prevop == JSOP_DEFFUN ||
- prevop == JSOP_CLOSURE)
- ? js_function_str
- : (prevop == JSOP_DEFCONST)
- ? js_const_str
- : js_var_str,
- name)) {
- return NULL;
- }
- }
- if (pn->pn_op == JSOP_DEFVAR && prevop == JSOP_CLOSURE)
- tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
- } else {
- ale = js_IndexAtom(cx, atom, &tc->decls);
- if (!ale)
- return NULL;
- }
- ALE_SET_JSOP(ale, pn->pn_op);
-
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn2)
- return NULL;
- pn2->pn_op = JSOP_NAME;
- pn2->pn_atom = atom;
- pn2->pn_expr = NULL;
- pn2->pn_slot = -1;
- pn2->pn_attrs = (pn->pn_op == JSOP_DEFCONST)
- ? JSPROP_ENUMERATE | JSPROP_PERMANENT |
- JSPROP_READONLY
- : JSPROP_ENUMERATE | JSPROP_PERMANENT;
- PN_APPEND(pn, pn2);
-
- if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop))
- return NULL;
- if (pobj == obj &&
- OBJ_IS_NATIVE(pobj) &&
- (sprop = (JSScopeProperty *)prop) != NULL) {
- if (sprop->getter == js_GetArgument) {
- const char *name = js_AtomToPrintableString(cx, atom);
- if (!name) {
- ok = JS_FALSE;
- } else if (pn->pn_op == JSOP_DEFCONST) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_REDECLARED_PARAM,
- name);
- ok = JS_FALSE;
- } else {
- currentGetter = js_GetArgument;
- currentSetter = js_SetArgument;
- ok = js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_VAR_HIDES_ARG,
- name);
- }
- } else {
- if (fun) {
- /* Not an argument, must be a redeclared local var. */
- if (clasp == &js_FunctionClass) {
- JS_ASSERT(sprop->getter == js_GetLocalVariable);
- JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
- sprop->shortid < fun->nvars);
- } else if (clasp == &js_CallClass) {
- if (sprop->getter == js_GetCallVariable) {
- /*
- * Referencing a variable introduced by a var
- * statement in the enclosing function. Check
- * that the slot number we have is in range.
- */
- JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
- sprop->shortid < fun->nvars);
- } else {
- /*
- * A variable introduced through another eval:
- * don't use the special getters and setters
- * since we can't allocate a slot in the frame.
- */
- currentGetter = sprop->getter;
- currentSetter = sprop->setter;
- }
- }
-
- /* Override the old getter and setter, to handle eval. */
- sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
- 0, sprop->attrs,
- currentGetter,
- currentSetter);
- if (!sprop)
- ok = JS_FALSE;
- }
- }
- } else {
- /*
- * Property not found in current variable scope: we have not seen
- * this variable before. Define a new local variable by adding a
- * property to the function's scope, allocating one slot in the
- * function's frame. Global variables and any locals declared in
- * with statement bodies are handled at runtime, by script prolog
- * JSOP_DEFVAR bytecodes generated for slot-less vars.
- */
- sprop = NULL;
- if (prop) {
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- prop = NULL;
- }
- if (currentGetter == js_GetCallVariable) {
- /* Can't increase fun->nvars in an active frame! */
- currentGetter = clasp->getProperty;
- currentSetter = clasp->setProperty;
- }
- if (currentGetter == js_GetLocalVariable &&
- atom != cx->runtime->atomState.argumentsAtom &&
- fp->scopeChain == obj &&
- !js_InWithStatement(tc)) {
- if (!js_AddNativeProperty(cx, obj, (jsid)atom,
- currentGetter, currentSetter,
- SPROP_INVALID_SLOT,
- pn2->pn_attrs | JSPROP_SHARED,
- SPROP_HAS_SHORTID, fun->nvars)) {
- ok = JS_FALSE;
- }
- fun->nvars++;
- }
- }
-
- if (js_MatchToken(cx, ts, TOK_ASSIGN)) {
- if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_VAR_INIT);
- ok = JS_FALSE;
- } else {
- pn2->pn_expr = AssignExpr(cx, ts, tc);
- if (!pn2->pn_expr) {
- ok = JS_FALSE;
- } else {
- pn2->pn_op = (pn->pn_op == JSOP_DEFCONST)
- ? JSOP_SETCONST
- : JSOP_SETNAME;
- if (atom == cx->runtime->atomState.argumentsAtom)
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- }
- }
- }
-
- if (prop)
- OBJ_DROP_PROPERTY(cx, pobj, prop);
- if (!ok)
- return NULL;
- } while (js_MatchToken(cx, ts, TOK_COMMA));
-
- pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
- return pn;
-}
-
-static JSParseNode *
-Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2;
-
- pn = AssignExpr(cx, ts, tc);
- if (pn && js_MatchToken(cx, ts, TOK_COMMA)) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn2)
- return NULL;
- pn2->pn_pos.begin = pn->pn_pos.begin;
- PN_INIT_LIST_1(pn2, pn);
- pn = pn2;
- do {
- pn2 = AssignExpr(cx, ts, tc);
- if (!pn2)
- return NULL;
- PN_APPEND(pn, pn2);
- } while (js_MatchToken(cx, ts, TOK_COMMA));
- pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
- }
- return pn;
-}
-
-static JSParseNode *
-AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn2;
- JSTokenType tt;
- JSOp op;
-
- CHECK_RECURSION();
-
- pn = CondExpr(cx, ts, tc);
- if (!pn)
- return NULL;
-
- tt = js_GetToken(cx, ts);
-#if JS_HAS_GETTER_SETTER
- if (tt == TOK_NAME) {
- tt = CheckGetterOrSetter(cx, ts, TOK_ASSIGN);
- if (tt == TOK_ERROR)
- return NULL;
- }
-#endif
- if (tt != TOK_ASSIGN) {
- js_UngetToken(ts);
- return pn;
- }
-
- op = CURRENT_TOKEN(ts).t_op;
- for (pn2 = pn; pn2->pn_type == TOK_RP; pn2 = pn2->pn_kid)
- continue;
- switch (pn2->pn_type) {
- case TOK_NAME:
- pn2->pn_op = JSOP_SETNAME;
- if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom)
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- break;
- case TOK_DOT:
- pn2->pn_op = JSOP_SETPROP;
- break;
- case TOK_LB:
- pn2->pn_op = JSOP_SETELEM;
- break;
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
- pn2->pn_op = JSOP_SETCALL;
- break;
-#endif
- default:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_LEFTSIDE_OF_ASS);
- return NULL;
- }
- pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc), tc);
- return pn;
-}
-
-static JSParseNode *
-CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn, *pn1, *pn2, *pn3;
-#if JS_HAS_IN_OPERATOR
- uintN oldflags;
-#endif /* JS_HAS_IN_OPERATOR */
-
- pn = OrExpr(cx, ts, tc);
- if (pn && js_MatchToken(cx, ts, TOK_HOOK)) {
- pn1 = pn;
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
- if (!pn)
- return NULL;
-#if JS_HAS_IN_OPERATOR
- /*
- * Always accept the 'in' operator in the middle clause of a ternary,
- * where it's unambiguous, even if we might be parsing the init of a
- * for statement.
- */
- oldflags = tc->flags;
- tc->flags &= ~TCF_IN_FOR_INIT;
-#endif /* JS_HAS_IN_OPERATOR */
- pn2 = AssignExpr(cx, ts, tc);
-#if JS_HAS_IN_OPERATOR
- tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
-#endif /* JS_HAS_IN_OPERATOR */
-
- if (!pn2)
- return NULL;
- MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
- pn3 = AssignExpr(cx, ts, tc);
- if (!pn3)
- return NULL;
- pn->pn_pos.begin = pn1->pn_pos.begin;
- pn->pn_pos.end = pn3->pn_pos.end;
- pn->pn_kid1 = pn1;
- pn->pn_kid2 = pn2;
- pn->pn_kid3 = pn3;
- }
- return pn;
-}
-
-static JSParseNode *
-OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = AndExpr(cx, ts, tc);
- if (pn && js_MatchToken(cx, ts, TOK_OR))
- pn = NewBinary(cx, TOK_OR, JSOP_OR, pn, OrExpr(cx, ts, tc), tc);
- return pn;
-}
-
-static JSParseNode *
-AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = BitOrExpr(cx, ts, tc);
- if (pn && js_MatchToken(cx, ts, TOK_AND))
- pn = NewBinary(cx, TOK_AND, JSOP_AND, pn, AndExpr(cx, ts, tc), tc);
- return pn;
-}
-
-static JSParseNode *
-BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = BitXorExpr(cx, ts, tc);
- while (pn && js_MatchToken(cx, ts, TOK_BITOR)) {
- pn = NewBinary(cx, TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc),
- tc);
- }
- return pn;
-}
-
-static JSParseNode *
-BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = BitAndExpr(cx, ts, tc);
- while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) {
- pn = NewBinary(cx, TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
- tc);
- }
- return pn;
-}
-
-static JSParseNode *
-BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
-
- pn = EqExpr(cx, ts, tc);
- while (pn && js_MatchToken(cx, ts, TOK_BITAND))
- pn = NewBinary(cx, TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
- return pn;
-}
-
-static JSParseNode *
-EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
- JSOp op;
-
- pn = RelExpr(cx, ts, tc);
- while (pn && js_MatchToken(cx, ts, TOK_EQOP)) {
- op = CURRENT_TOKEN(ts).t_op;
- pn = NewBinary(cx, TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
- }
- return pn;
-}
-
-static JSParseNode *
-RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
- JSTokenType tt;
- JSOp op;
-#if JS_HAS_IN_OPERATOR
- uintN inForInitFlag = tc->flags & TCF_IN_FOR_INIT;
-
- /*
- * Uses of the in operator in ShiftExprs are always unambiguous,
- * so unset the flag that prohibits recognizing it.
- */
- tc->flags &= ~TCF_IN_FOR_INIT;
-#endif /* JS_HAS_IN_OPERATOR */
-
- pn = ShiftExpr(cx, ts, tc);
- while (pn &&
- (js_MatchToken(cx, ts, TOK_RELOP)
-#if JS_HAS_IN_OPERATOR
- /*
- * Recognize the 'in' token as an operator only if we're not
- * currently in the init expr of a for loop.
- */
- || (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN))
-#endif /* JS_HAS_IN_OPERATOR */
-#if JS_HAS_INSTANCEOF
- || js_MatchToken(cx, ts, TOK_INSTANCEOF)
-#endif /* JS_HAS_INSTANCEOF */
- )) {
- tt = CURRENT_TOKEN(ts).type;
- op = CURRENT_TOKEN(ts).t_op;
- pn = NewBinary(cx, tt, op, pn, ShiftExpr(cx, ts, tc), tc);
- }
-#if JS_HAS_IN_OPERATOR
- /* Restore previous state of inForInit flag. */
- tc->flags |= inForInitFlag;
-#endif /* JS_HAS_IN_OPERATOR */
-
- return pn;
-}
-
-static JSParseNode *
-ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
- JSOp op;
-
- pn = AddExpr(cx, ts, tc);
- while (pn && js_MatchToken(cx, ts, TOK_SHOP)) {
- op = CURRENT_TOKEN(ts).t_op;
- pn = NewBinary(cx, TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
- }
- return pn;
-}
-
-static JSParseNode *
-AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
- JSTokenType tt;
- JSOp op;
-
- pn = MulExpr(cx, ts, tc);
- while (pn &&
- (js_MatchToken(cx, ts, TOK_PLUS) ||
- js_MatchToken(cx, ts, TOK_MINUS))) {
- tt = CURRENT_TOKEN(ts).type;
- op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
- pn = NewBinary(cx, tt, op, pn, MulExpr(cx, ts, tc), tc);
- }
- return pn;
-}
-
-static JSParseNode *
-MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSParseNode *pn;
- JSTokenType tt;
- JSOp op;
-
- pn = UnaryExpr(cx, ts, tc);
- while (pn &&
- (js_MatchToken(cx, ts, TOK_STAR) ||
- js_MatchToken(cx, ts, TOK_DIVOP))) {
- tt = CURRENT_TOKEN(ts).type;
- op = CURRENT_TOKEN(ts).t_op;
- pn = NewBinary(cx, tt, op, pn, UnaryExpr(cx, ts, tc), tc);
- }
- return pn;
-}
-
-static JSParseNode *
-SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
- const char *name)
-{
- while (kid->pn_type == TOK_RP)
- kid = kid->pn_kid;
- if (kid->pn_type != TOK_NAME &&
- kid->pn_type != TOK_DOT &&
-#if JS_HAS_LVALUE_RETURN
- (kid->pn_type != TOK_LP || kid->pn_op != JSOP_CALL) &&
-#endif
- kid->pn_type != TOK_LB) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_OPERAND, name);
- return NULL;
- }
- pn->pn_kid = kid;
- return kid;
-}
-
-static const char *incop_name_str[] = {"increment", "decrement"};
-
-static JSBool
-SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
- JSParseNode *pn, JSParseNode *kid,
- JSTokenType tt, JSBool preorder)
-{
- JSOp op;
-
- kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]);
- if (!kid)
- return JS_FALSE;
- switch (kid->pn_type) {
- case TOK_NAME:
- op = (tt == TOK_INC)
- ? (preorder ? JSOP_INCNAME : JSOP_NAMEINC)
- : (preorder ? JSOP_DECNAME : JSOP_NAMEDEC);
- if (kid->pn_atom == cx->runtime->atomState.argumentsAtom)
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- break;
-
- case TOK_DOT:
- op = (tt == TOK_INC)
- ? (preorder ? JSOP_INCPROP : JSOP_PROPINC)
- : (preorder ? JSOP_DECPROP : JSOP_PROPDEC);
- break;
-
-#if JS_HAS_LVALUE_RETURN
- case TOK_LP:
- kid->pn_op = JSOP_SETCALL;
-#endif
- case TOK_LB:
- op = (tt == TOK_INC)
- ? (preorder ? JSOP_INCELEM : JSOP_ELEMINC)
- : (preorder ? JSOP_DECELEM : JSOP_ELEMDEC);
- break;
-
- default:
- JS_ASSERT(0);
- op = JSOP_NOP;
- }
- pn->pn_op = op;
- return JS_TRUE;
-}
-
-static JSParseNode *
-UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSTokenType tt;
- JSParseNode *pn, *pn2;
-
- ts->flags |= TSF_REGEXP;
- tt = js_GetToken(cx, ts);
- ts->flags &= ~TSF_REGEXP;
-
- switch (tt) {
- case TOK_UNARYOP:
- case TOK_PLUS:
- case TOK_MINUS:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_UNARYOP; /* PLUS and MINUS are binary */
- pn->pn_op = CURRENT_TOKEN(ts).t_op;
- pn2 = UnaryExpr(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_pos.end = pn2->pn_pos.end;
- pn->pn_kid = pn2;
- break;
-
- case TOK_INC:
- case TOK_DEC:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn2 = MemberExpr(cx, ts, tc, JS_TRUE);
- if (!pn2)
- return NULL;
- if (!SetIncOpKid(cx, ts, tc, pn, pn2, tt, JS_TRUE))
- return NULL;
- pn->pn_pos.end = pn2->pn_pos.end;
- break;
-
- case TOK_DELETE:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
- pn2 = UnaryExpr(cx, ts, tc);
- if (!pn2)
- return NULL;
- pn->pn_pos.end = pn2->pn_pos.end;
-
- /*
- * Under ECMA3, deleting any unary expression is valid -- it simply
- * returns true. Here we strip off any parentheses.
- */
- while (pn2->pn_type == TOK_RP)
- pn2 = pn2->pn_kid;
- pn->pn_kid = pn2;
- break;
-
- case TOK_ERROR:
- return NULL;
-
- default:
- js_UngetToken(ts);
- pn = MemberExpr(cx, ts, tc, JS_TRUE);
- if (!pn)
- return NULL;
-
- /* Don't look across a newline boundary for a postfix incop. */
- if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
- tt = js_PeekTokenSameLine(cx, ts);
- if (tt == TOK_INC || tt == TOK_DEC) {
- (void) js_GetToken(cx, ts);
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn2)
- return NULL;
- if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
- return NULL;
- pn2->pn_pos.begin = pn->pn_pos.begin;
- pn = pn2;
- }
- }
- break;
- }
- return pn;
-}
-
-static JSBool
-ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
- JSParseNode *listNode)
-{
- JSBool matched;
-
- ts->flags |= TSF_REGEXP;
- matched = js_MatchToken(cx, ts, TOK_RP);
- ts->flags &= ~TSF_REGEXP;
- if (!matched) {
- do {
- JSParseNode *argNode = AssignExpr(cx, ts, tc);
- if (!argNode)
- return JS_FALSE;
- PN_APPEND(listNode, argNode);
- } while (js_MatchToken(cx, ts, TOK_COMMA));
-
- if (js_GetToken(cx, ts) != TOK_RP) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_PAREN_AFTER_ARGS);
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-static JSParseNode *
-MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
- JSBool allowCallSyntax)
-{
- JSParseNode *pn, *pn2, *pn3;
- JSTokenType tt;
-
- CHECK_RECURSION();
-
- /* Check for new expression first. */
- ts->flags |= TSF_REGEXP;
- tt = js_PeekToken(cx, ts);
- ts->flags &= ~TSF_REGEXP;
- if (tt == TOK_NEW) {
- (void) js_GetToken(cx, ts);
-
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- pn2 = MemberExpr(cx, ts, tc, JS_FALSE);
- if (!pn2)
- return NULL;
- pn->pn_op = JSOP_NEW;
- PN_INIT_LIST_1(pn, pn2);
- pn->pn_pos.begin = pn2->pn_pos.begin;
-
- if (js_MatchToken(cx, ts, TOK_LP) && !ArgumentList(cx, ts, tc, pn))
- return NULL;
- if (pn->pn_count > ARGC_LIMIT) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_TOO_MANY_CON_ARGS);
- return NULL;
- }
- pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
- } else {
- pn = PrimaryExpr(cx, ts, tc);
- if (!pn)
- return NULL;
- }
-
- while ((tt = js_GetToken(cx, ts)) > TOK_EOF) {
- if (tt == TOK_DOT) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
- if (!pn2)
- return NULL;
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
- pn2->pn_pos.begin = pn->pn_pos.begin;
- pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- pn2->pn_op = JSOP_GETPROP;
- pn2->pn_expr = pn;
- pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
- } else if (tt == TOK_LB) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
- if (!pn2)
- return NULL;
- pn3 = Expr(cx, ts, tc);
- if (!pn3)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
- pn2->pn_pos.begin = pn->pn_pos.begin;
- pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
-
- /* Optimize o['p'] to o.p by rewriting pn2. */
- if (pn3->pn_type == TOK_STRING) {
- pn2->pn_type = TOK_DOT;
- pn2->pn_op = JSOP_GETPROP;
- pn2->pn_arity = PN_NAME;
- pn2->pn_expr = pn;
- pn2->pn_atom = pn3->pn_atom;
- } else {
- pn2->pn_op = JSOP_GETELEM;
- pn2->pn_left = pn;
- pn2->pn_right = pn3;
- }
- } else if (allowCallSyntax && tt == TOK_LP) {
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn2)
- return NULL;
-
- /* Pick JSOP_EVAL and flag tc as heavyweight if eval(...). */
- pn2->pn_op = JSOP_CALL;
- if (pn->pn_op == JSOP_NAME &&
- pn->pn_atom == cx->runtime->atomState.evalAtom) {
- pn2->pn_op = JSOP_EVAL;
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- }
-
- PN_INIT_LIST_1(pn2, pn);
- pn2->pn_pos.begin = pn->pn_pos.begin;
-
- if (!ArgumentList(cx, ts, tc, pn2))
- return NULL;
- if (pn2->pn_count > ARGC_LIMIT) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_TOO_MANY_FUN_ARGS);
- return NULL;
- }
- pn2->pn_pos.end = PN_LAST(pn2)->pn_pos.end;
- } else {
- js_UngetToken(ts);
- return pn;
- }
-
- pn = pn2;
- }
- if (tt == TOK_ERROR)
- return NULL;
- return pn;
-}
-
-static JSParseNode *
-PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
-{
- JSTokenType tt;
- JSParseNode *pn, *pn2, *pn3;
- char *badWord;
-#if JS_HAS_GETTER_SETTER
- JSAtom *atom;
- JSRuntime *rt;
-#endif
-
-#if JS_HAS_SHARP_VARS
- JSParseNode *defsharp;
- JSBool notsharp;
-
- defsharp = NULL;
- notsharp = JS_FALSE;
- again:
- /*
- * Control flows here after #n= is scanned. If the following primary is
- * not valid after such a "sharp variable" definition, the token type case
- * should set notsharp.
- */
-#endif
-
- CHECK_RECURSION();
-
- ts->flags |= TSF_REGEXP;
- tt = js_GetToken(cx, ts);
- ts->flags &= ~TSF_REGEXP;
-
-#if JS_HAS_GETTER_SETTER
- if (tt == TOK_NAME) {
- tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
- if (tt == TOK_ERROR)
- return NULL;
- }
-#endif
-
- switch (tt) {
-#if JS_HAS_LEXICAL_CLOSURE
- case TOK_FUNCTION:
- pn = FunctionExpr(cx, ts, tc);
- if (!pn)
- return NULL;
- break;
-#endif
-
-#if JS_HAS_INITIALIZERS
- case TOK_LB:
- {
- JSBool matched;
- jsuint atomIndex;
-
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_RB;
- pn->pn_extra = JS_FALSE;
-
-#if JS_HAS_SHARP_VARS
- if (defsharp) {
- PN_INIT_LIST_1(pn, defsharp);
- defsharp = NULL;
- } else
-#endif
- PN_INIT_LIST(pn);
-
- ts->flags |= TSF_REGEXP;
- matched = js_MatchToken(cx, ts, TOK_RB);
- ts->flags &= ~TSF_REGEXP;
- if (!matched) {
- for (atomIndex = 0; atomIndex < ATOM_INDEX_LIMIT; atomIndex++) {
- ts->flags |= TSF_REGEXP;
- tt = js_PeekToken(cx, ts);
- ts->flags &= ~TSF_REGEXP;
- if (tt == TOK_RB) {
- pn->pn_extra = JS_TRUE;
- break;
- }
-
- if (tt == TOK_COMMA) {
- /* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
- js_MatchToken(cx, ts, TOK_COMMA);
- pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- } else {
- pn2 = AssignExpr(cx, ts, tc);
- }
- if (!pn2)
- return NULL;
- PN_APPEND(pn, pn2);
-
- if (tt != TOK_COMMA) {
- /* If we didn't already match TOK_COMMA in above case. */
- if (!js_MatchToken(cx, ts, TOK_COMMA))
- break;
- }
- }
-
- MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
- }
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- return pn;
- }
-
- case TOK_LC:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
- if (!pn)
- return NULL;
- pn->pn_type = TOK_RC;
-
-#if JS_HAS_SHARP_VARS
- if (defsharp) {
- PN_INIT_LIST_1(pn, defsharp);
- defsharp = NULL;
- } else
-#endif
- PN_INIT_LIST(pn);
-
- if (!js_MatchToken(cx, ts, TOK_RC)) {
- do {
- JSOp op;
-
- tt = js_GetToken(cx, ts);
- switch (tt) {
- case TOK_NUMBER:
- pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (pn3)
- pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
- break;
- case TOK_NAME:
-#if JS_HAS_GETTER_SETTER
- atom = CURRENT_TOKEN(ts).t_atom;
- rt = cx->runtime;
- if (atom == rt->atomState.getAtom ||
- atom == rt->atomState.setAtom) {
- op = (atom == rt->atomState.getAtom)
- ? JSOP_GETTER
- : JSOP_SETTER;
- if (js_MatchToken(cx, ts, TOK_NAME)) {
- pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME,
- tc);
- if (!pn3)
- return NULL;
- pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
- pn3->pn_expr = NULL;
-
- /* We have to fake a 'function' token here. */
- CURRENT_TOKEN(ts).t_op = JSOP_NOP;
- CURRENT_TOKEN(ts).type = TOK_FUNCTION;
- pn2 = FunctionExpr(cx, ts, tc);
- pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc);
- goto skip;
- }
- }
- /* else fall thru ... */
-#endif
- case TOK_STRING:
- pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (pn3)
- pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
- break;
- case TOK_RC:
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_TRAILING_COMMA)) {
- return NULL;
- }
- goto end_obj_init;
- default:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_PROP_ID);
- return NULL;
- }
-
- tt = js_GetToken(cx, ts);
-#if JS_HAS_GETTER_SETTER
- if (tt == TOK_NAME) {
- tt = CheckGetterOrSetter(cx, ts, TOK_COLON);
- if (tt == TOK_ERROR)
- return NULL;
- }
-#endif
- if (tt != TOK_COLON) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_COLON_AFTER_ID);
- return NULL;
- }
- op = CURRENT_TOKEN(ts).t_op;
- pn2 = NewBinary(cx, TOK_COLON, op, pn3, AssignExpr(cx, ts, tc),
- tc);
-#if JS_HAS_GETTER_SETTER
- skip:
-#endif
- if (!pn2)
- return NULL;
- PN_APPEND(pn, pn2);
- } while (js_MatchToken(cx, ts, TOK_COMMA));
-
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
- }
- end_obj_init:
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- return pn;
-
-#if JS_HAS_SHARP_VARS
- case TOK_DEFSHARP:
- if (defsharp)
- goto badsharp;
- defsharp = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!defsharp)
- return NULL;
- defsharp->pn_kid = NULL;
- defsharp->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
- goto again;
-
- case TOK_USESHARP:
- /* Check for forward/dangling references at runtime, to allow eval. */
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- pn->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
- notsharp = JS_TRUE;
- break;
-#endif /* JS_HAS_SHARP_VARS */
-#endif /* JS_HAS_INITIALIZERS */
-
- case TOK_LP:
- {
-#if JS_HAS_IN_OPERATOR
- uintN oldflags;
-#endif
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
- if (!pn)
- return NULL;
-#if JS_HAS_IN_OPERATOR
- /*
- * Always accept the 'in' operator in a parenthesized expression,
- * where it's unambiguous, even if we might be parsing the init of a
- * for statement.
- */
- oldflags = tc->flags;
- tc->flags &= ~TCF_IN_FOR_INIT;
-#endif
- pn2 = Expr(cx, ts, tc);
-#if JS_HAS_IN_OPERATOR
- tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
-#endif
- if (!pn2)
- return NULL;
-
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
- pn->pn_type = TOK_RP;
- pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
- pn->pn_kid = pn2;
- break;
- }
-
- case TOK_STRING:
-#if JS_HAS_SHARP_VARS
- notsharp = JS_TRUE;
-#endif
- /* FALL THROUGH */
- case TOK_NAME:
- case TOK_OBJECT:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- pn->pn_op = CURRENT_TOKEN(ts).t_op;
- pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
- if (tt == TOK_NAME) {
- pn->pn_arity = PN_NAME;
- pn->pn_expr = NULL;
- pn->pn_slot = -1;
- pn->pn_attrs = 0;
-
- /* Unqualified __parent__ and __proto__ uses require activations. */
- if (pn->pn_atom == cx->runtime->atomState.parentAtom ||
- pn->pn_atom == cx->runtime->atomState.protoAtom) {
- tc->flags |= TCF_FUN_HEAVYWEIGHT;
- }
- }
- break;
-
- case TOK_NUMBER:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- pn->pn_dval = CURRENT_TOKEN(ts).t_dval;
-#if JS_HAS_SHARP_VARS
- notsharp = JS_TRUE;
-#endif
- break;
-
- case TOK_PRIMARY:
- pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
- if (!pn)
- return NULL;
- pn->pn_op = CURRENT_TOKEN(ts).t_op;
-#if JS_HAS_SHARP_VARS
- notsharp = JS_TRUE;
-#endif
- break;
-
-#if !JS_HAS_EXPORT_IMPORT
- case TOK_EXPORT:
- case TOK_IMPORT:
-#endif
- case TOK_RESERVED:
- badWord = js_DeflateString(cx, CURRENT_TOKEN(ts).ptr,
- (size_t) CURRENT_TOKEN(ts).pos.end.index
- - CURRENT_TOKEN(ts).pos.begin.index);
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_RESERVED_ID, badWord);
- JS_free(cx, badWord);
- return NULL;
-
- case TOK_ERROR:
- /* The scanner or one of its subroutines reported the error. */
- return NULL;
-
- default:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_SYNTAX_ERROR);
- return NULL;
- }
-
-#if JS_HAS_SHARP_VARS
- if (defsharp) {
- if (notsharp) {
- badsharp:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_SHARP_VAR_DEF);
- return NULL;
- }
- defsharp->pn_kid = pn;
- return defsharp;
- }
-#endif
- return pn;
-}
-
-static JSBool
-ContainsVarStmt(JSParseNode *pn)
-{
- JSParseNode *pn2;
-
- if (!pn)
- return JS_FALSE;
- switch (pn->pn_arity) {
- case PN_LIST:
- if (pn->pn_type == TOK_VAR)
- return JS_TRUE;
- for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
- if (ContainsVarStmt(pn2))
- return JS_TRUE;
- }
- break;
- case PN_TERNARY:
- return ContainsVarStmt(pn->pn_kid1) ||
- ContainsVarStmt(pn->pn_kid2) ||
- ContainsVarStmt(pn->pn_kid3);
- case PN_BINARY:
- /*
- * Limit recursion if pn is a binary expression, which can't contain a
- * var statement.
- */
- if (pn->pn_op != JSOP_NOP)
- return JS_FALSE;
- return ContainsVarStmt(pn->pn_left) || ContainsVarStmt(pn->pn_right);
- case PN_UNARY:
- if (pn->pn_op != JSOP_NOP)
- return JS_FALSE;
- return ContainsVarStmt(pn->pn_kid);
- default:;
- }
- return JS_FALSE;
-}
-
-/*
- * Fold from one constant type to another.
- * XXX handles only strings and numbers for now
- */
-static JSBool
-FoldType(JSContext *cx, JSParseNode *pn, JSTokenType type)
-{
- if (pn->pn_type != type) {
- switch (type) {
- case TOK_NUMBER:
- if (pn->pn_type == TOK_STRING) {
- jsdouble d;
- if (!js_ValueToNumber(cx, ATOM_KEY(pn->pn_atom), &d))
- return JS_FALSE;
- pn->pn_dval = d;
- pn->pn_type = TOK_NUMBER;
- pn->pn_op = JSOP_NUMBER;
- }
- break;
-
- case TOK_STRING:
- if (pn->pn_type == TOK_NUMBER) {
- JSString *str = js_NumberToString(cx, pn->pn_dval);
- if (!str)
- return JS_FALSE;
- pn->pn_atom = js_AtomizeString(cx, str, 0);
- if (!pn->pn_atom)
- return JS_FALSE;
- pn->pn_type = TOK_STRING;
- pn->pn_op = JSOP_STRING;
- }
- break;
-
- default:;
- }
- }
- return JS_TRUE;
-}
-
-/*
- * Fold two numeric constants. Beware that pn1 and pn2 are recycled, unless
- * one of them aliases pn, so you can't safely fetch pn2->pn_next, e.g., after
- * a successful call to this function.
- */
-static JSBool
-FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2,
- JSParseNode *pn, JSTreeContext *tc)
-{
- jsdouble d, d2;
- int32 i, j;
- uint32 u;
-
- JS_ASSERT(pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER);
- d = pn1->pn_dval;
- d2 = pn2->pn_dval;
- switch (op) {
- case JSOP_LSH:
- case JSOP_RSH:
- if (!js_DoubleToECMAInt32(cx, d, &i))
- return JS_FALSE;
- if (!js_DoubleToECMAInt32(cx, d2, &j))
- return JS_FALSE;
- j &= 31;
- d = (op == JSOP_LSH) ? i << j : i >> j;
- break;
-
- case JSOP_URSH:
- if (!js_DoubleToECMAUint32(cx, d, &u))
- return JS_FALSE;
- if (!js_DoubleToECMAInt32(cx, d2, &j))
- return JS_FALSE;
- j &= 31;
- d = u >> j;
- break;
-
- case JSOP_ADD:
- d += d2;
- break;
-
- case JSOP_SUB:
- d -= d2;
- break;
-
- case JSOP_MUL:
- d *= d2;
- break;
-
- case JSOP_DIV:
- if (d2 == 0) {
-#if defined(XP_WIN)
- /* XXX MSVC miscompiles such that (NaN == 0) */
- if (JSDOUBLE_IS_NaN(d2))
- d = *cx->runtime->jsNaN;
- else
-#endif
- if (d == 0 || JSDOUBLE_IS_NaN(d))
- d = *cx->runtime->jsNaN;
- else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
- d = *cx->runtime->jsNegativeInfinity;
- else
- d = *cx->runtime->jsPositiveInfinity;
- } else {
- d /= d2;
- }
- break;
-
- case JSOP_MOD:
- if (d2 == 0) {
- d = *cx->runtime->jsNaN;
- } else {
-#if defined(XP_WIN)
- /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
- if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
-#endif
- d = fmod(d, d2);
- }
- break;
-
- default:;
- }
-
- /* Take care to allow pn1 or pn2 to alias pn. */
- if (pn1 != pn)
- RecycleTree(pn1, tc);
- if (pn2 != pn)
- RecycleTree(pn2, tc);
- pn->pn_type = TOK_NUMBER;
- pn->pn_op = JSOP_NUMBER;
- pn->pn_arity = PN_NULLARY;
- pn->pn_dval = d;
- return JS_TRUE;
-}
-
-JSBool
-js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
-{
- JSParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
- int stackDummy;
-
- if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
- return JS_FALSE;
- }
-
- switch (pn->pn_arity) {
- case PN_FUNC:
- if (!js_FoldConstants(cx, pn->pn_body, tc))
- return JS_FALSE;
- break;
-
- case PN_LIST:
- /* Save the list head in pn1 for later use. */
- for (pn1 = pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
- if (!js_FoldConstants(cx, pn2, tc))
- return JS_FALSE;
- }
- break;
-
- case PN_TERNARY:
- /* Any kid may be null (e.g. for (;;)). */
- pn1 = pn->pn_kid1;
- pn2 = pn->pn_kid2;
- pn3 = pn->pn_kid3;
- if (pn1 && !js_FoldConstants(cx, pn1, tc))
- return JS_FALSE;
- if (pn2 && !js_FoldConstants(cx, pn2, tc))
- return JS_FALSE;
- if (pn3 && !js_FoldConstants(cx, pn3, tc))
- return JS_FALSE;
- break;
-
- case PN_BINARY:
- /* First kid may be null (for default case in switch). */
- pn1 = pn->pn_left;
- pn2 = pn->pn_right;
- if (pn1 && !js_FoldConstants(cx, pn1, tc))
- return JS_FALSE;
- if (!js_FoldConstants(cx, pn2, tc))
- return JS_FALSE;
- break;
-
- case PN_UNARY:
- /* Our kid may be null (e.g. return; vs. return e;). */
- pn1 = pn->pn_kid;
- if (pn1 && !js_FoldConstants(cx, pn1, tc))
- return JS_FALSE;
- break;
-
- case PN_NAME:
- /*
- * Skip pn1 down along a chain of dotted member expressions to avoid
- * excessive recursion. Our only goal here is to fold constants (if
- * any) in the primary expression operand to the left of the first
- * dot in the chain.
- */
- pn1 = pn->pn_expr;
- while (pn1 && pn1->pn_arity == PN_NAME)
- pn1 = pn1->pn_expr;
- if (pn1 && !js_FoldConstants(cx, pn1, tc))
- return JS_FALSE;
- break;
-
- case PN_NULLARY:
- break;
- }
-
- switch (pn->pn_type) {
- case TOK_IF:
- if (ContainsVarStmt(pn2) || ContainsVarStmt(pn3))
- break;
- /* FALL THROUGH */
-
- case TOK_HOOK:
- /* Reduce 'if (C) T; else E' into T for true C, E for false. */
- switch (pn1->pn_type) {
- case TOK_NUMBER:
- if (pn1->pn_dval == 0)
- pn2 = pn3;
- break;
- case TOK_STRING:
- if (JSSTRING_LENGTH(ATOM_TO_STRING(pn1->pn_atom)) == 0)
- pn2 = pn3;
- break;
- case TOK_PRIMARY:
- if (pn1->pn_op == JSOP_TRUE)
- break;
- if (pn1->pn_op == JSOP_FALSE || pn1->pn_op == JSOP_NULL) {
- pn2 = pn3;
- break;
- }
- /* FALL THROUGH */
- default:
- /* Early return to dodge common code that copies pn2 to pn. */
- return JS_TRUE;
- }
-
- if (pn2) {
- /* pn2 is the then- or else-statement subtree to compile. */
- PN_MOVE_NODE(pn, pn2);
- } else {
- /* False condition and no else: make pn an empty statement. */
- pn->pn_type = TOK_SEMI;
- pn->pn_arity = PN_UNARY;
- pn->pn_kid = NULL;
- }
- RecycleTree(pn2, tc);
- if (pn3 && pn3 != pn2)
- RecycleTree(pn3, tc);
- break;
-
- case TOK_PLUS:
- if (pn->pn_arity == PN_LIST) {
- size_t length, length2;
- jschar *chars;
- JSString *str, *str2;
-
- /*
- * Any string literal term with all others number or string means
- * this is a concatenation. If any term is not a string or number
- * literal, we can't fold.
- */
- JS_ASSERT(pn->pn_count > 2);
- if (pn->pn_extra & PNX_CANTFOLD)
- return JS_TRUE;
- if (pn->pn_extra != PNX_STRCAT)
- goto do_binary_op;
-
- /* Ok, we're concatenating: convert non-string constant operands. */
- length = 0;
- for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
- if (!FoldType(cx, pn2, TOK_STRING))
- return JS_FALSE;
- /* XXX fold only if all operands convert to string */
- if (pn2->pn_type != TOK_STRING)
- return JS_TRUE;
- length += ATOM_TO_STRING(pn2->pn_atom)->length;
- }
-
- /* Allocate a new buffer and string descriptor for the result. */
- chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!chars)
- return JS_FALSE;
- str = js_NewString(cx, chars, length, 0);
- if (!str) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
-
- /* Fill the buffer, advancing chars and recycling kids as we go. */
- for (pn2 = pn1; pn2; pn2 = pn3) {
- str2 = ATOM_TO_STRING(pn2->pn_atom);
- length2 = str2->length;
- js_strncpy(chars, str2->chars, length2);
- chars += length2;
- pn3 = pn2->pn_next;
- RecycleTree(pn2, tc);
- }
- *chars = 0;
-
- /* Atomize the result string and mutate pn to refer to it. */
- pn->pn_atom = js_AtomizeString(cx, str, 0);
- if (!pn->pn_atom)
- return JS_FALSE;
- pn->pn_type = TOK_STRING;
- pn->pn_op = JSOP_STRING;
- pn->pn_arity = PN_NULLARY;
- break;
- }
-
- /* Handle a binary string concatenation. */
- JS_ASSERT(pn->pn_arity == PN_BINARY);
- if (pn1->pn_type == TOK_STRING || pn2->pn_type == TOK_STRING) {
- JSString *left, *right, *str;
-
- if (!FoldType(cx, (pn1->pn_type != TOK_STRING) ? pn1 : pn2,
- TOK_STRING)) {
- return JS_FALSE;
- }
- if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING)
- return JS_TRUE;
- left = ATOM_TO_STRING(pn1->pn_atom);
- right = ATOM_TO_STRING(pn2->pn_atom);
- str = js_ConcatStrings(cx, left, right);
- if (!str)
- return JS_FALSE;
- pn->pn_atom = js_AtomizeString(cx, str, 0);
- if (!pn->pn_atom)
- return JS_FALSE;
- pn->pn_type = TOK_STRING;
- pn->pn_op = JSOP_STRING;
- pn->pn_arity = PN_NULLARY;
- RecycleTree(pn1, tc);
- RecycleTree(pn2, tc);
- break;
- }
-
- /* Can't concatenate string literals, let's try numbers. */
- goto do_binary_op;
-
- case TOK_STAR:
- /* The * in 'import *;' parses as a nullary star node. */
- if (pn->pn_arity == PN_NULLARY)
- break;
- /* FALL THROUGH */
-
- case TOK_SHOP:
- case TOK_MINUS:
- case TOK_DIVOP:
- do_binary_op:
- if (pn->pn_arity == PN_LIST) {
- JS_ASSERT(pn->pn_count > 2);
- for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
- if (!FoldType(cx, pn2, TOK_NUMBER))
- return JS_FALSE;
- /* XXX fold only if all operands convert to number */
- if (pn2->pn_type != TOK_NUMBER)
- break;
- }
- if (!pn2) {
- JSOp op = pn->pn_op;
-
- pn2 = pn1->pn_next;
- pn3 = pn2->pn_next;
- if (!FoldBinaryNumeric(cx, op, pn1, pn2, pn, tc))
- return JS_FALSE;
- while ((pn2 = pn3) != NULL) {
- pn3 = pn2->pn_next;
- if (!FoldBinaryNumeric(cx, op, pn, pn2, pn, tc))
- return JS_FALSE;
- }
- }
- } else {
- JS_ASSERT(pn->pn_arity == PN_BINARY);
- if (!FoldType(cx, pn1, TOK_NUMBER) ||
- !FoldType(cx, pn2, TOK_NUMBER)) {
- return JS_FALSE;
- }
- if (pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER) {
- if (!FoldBinaryNumeric(cx, pn->pn_op, pn1, pn2, pn, tc))
- return JS_FALSE;
- }
- }
- break;
-
- case TOK_UNARYOP:
- if (pn1->pn_type == TOK_NUMBER) {
- jsdouble d;
- int32 i;
-
- /* Operate on one numeric constant. */
- d = pn1->pn_dval;
- switch (pn->pn_op) {
- case JSOP_BITNOT:
- if (!js_DoubleToECMAInt32(cx, d, &i))
- return JS_FALSE;
- d = ~i;
- break;
-
- case JSOP_NEG:
-#ifdef HPUX
- /*
- * Negation of a zero doesn't produce a negative
- * zero on HPUX. Perform the operation by bit
- * twiddling.
- */
- JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;
-#else
- d = -d;
-#endif
- break;
-
- case JSOP_POS:
- break;
-
- case JSOP_NOT:
- pn->pn_type = TOK_PRIMARY;
- pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;
- pn->pn_arity = PN_NULLARY;
- /* FALL THROUGH */
-
- default:
- /* Return early to dodge the common TOK_NUMBER code. */
- return JS_TRUE;
- }
- pn->pn_type = TOK_NUMBER;
- pn->pn_op = JSOP_NUMBER;
- pn->pn_arity = PN_NULLARY;
- pn->pn_dval = d;
- RecycleTree(pn1, tc);
- }
- break;
-
- default:;
- }
-
- return JS_TRUE;
-}
diff --git a/src/extension/script/js/jsparse.h b/src/extension/script/js/jsparse.h
deleted file mode 100644
index 1c6ff893a..000000000
--- a/src/extension/script/js/jsparse.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsparse_h___
-#define jsparse_h___
-/*
- * JS parser definitions.
- */
-#include "jsprvtd.h"
-#include "jspubtd.h"
-#include "jsscan.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * Parsing builds a tree of nodes that directs code generation. This tree is
- * not a concrete syntax tree in all respects (for example, || and && are left
- * associative, but (A && B && C) translates into the right-associated tree
- * <A && <B && C>> so that code generation can emit a left-associative branch
- * around <B && C> when A is false). Nodes are labeled by token type, with a
- * JSOp secondary label when needed:
- *
- * Label Variant Members
- * ----- ------- -------
- * <Definitions>
- * TOK_FUNCTION func pn_funAtom: atom holding function object containing
- * arg and var properties. We create the function
- * object at parse (not emit) time to specialize arg
- * and var bytecodes early.
- * pn_body: TOK_LC node for function body statements
- * pn_flags: TCF_FUN_* flags (see jsemit.h) collected
- * while parsing the function's body
- * pn_tryCount: of try statements in function
- *
- * <Statements>
- * TOK_LC list pn_head: list of pn_count statements
- * TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_STAR
- * (which is not a multiply node)
- * TOK_IMPORT list pn_head: list of pn_count sub-trees of the form
- * a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a.
- * Each member is expressed with TOK_DOT or TOK_LB.
- * Each sub-tree's root node has a pn_op in the set
- * JSOP_IMPORT{ALL,PROP,ELEM}
- * TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null
- * TOK_SWITCH binary pn_left: discriminant
- * pn_right: list of TOK_CASE nodes, with at most one
- * TOK_DEFAULT node
- * TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT
- * TOK_DEFAULT pn_right: TOK_LC node for this case's statements
- * TOK_WHILE binary pn_left: cond, pn_right: body
- * TOK_DO binary pn_left: body, pn_right: cond
- * TOK_FOR binary pn_left: either
- * for/in loop: a binary TOK_IN node with
- * pn_left: TOK_VAR or TOK_NAME to left of 'in'
- * pn_right: object expr to right of 'in'
- * for(;;) loop: a ternary TOK_RESERVED node with
- * pn_kid1: init expr before first ';'
- * pn_kid2: cond expr before second ';'
- * pn_kid3: update expr after second ';'
- * any kid may be null
- * pn_right: body
- * TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception
- * TOK_TRY ternary pn_kid1: try block
- * pn_kid2: catch blocks or null
- * pn_kid3: finally block or null
- * TOK_CATCH ternary pn_kid1: PN_NAME node for catch var (with pn_expr
- * null or the catch guard expression)
- * pn_kid2: more catch blocks or null
- * pn_kid3: catch block statements
- * TOK_BREAK name pn_atom: label or null
- * TOK_CONTINUE name pn_atom: label or null
- * TOK_WITH binary pn_left: head expr, pn_right: body
- * TOK_VAR list pn_head: list of pn_count TOK_NAME nodes
- * each name node has
- * pn_atom: variable name
- * pn_expr: initializer or null
- * TOK_RETURN unary pn_kid: return expr or null
- * TOK_SEMI unary pn_kid: expr or null statement
- * TOK_COLON name pn_atom: label, pn_expr: labeled statement
- *
- * <Expressions>
- * All left-associated binary trees of the same type are optimized into lists
- * to avoid recursion when processing expression chains.
- * TOK_COMMA list pn_head: list of pn_count comma-separated exprs
- * TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue
- * pn_op: JSOP_ADD for +=, etc.
- * TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else
- * TOK_OR binary pn_left: first in || chain, pn_right: rest of chain
- * TOK_AND binary pn_left: first in && chain, pn_right: rest of chain
- * TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr
- * TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr
- * TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr
- * TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr
- * pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE
- * TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr
- * pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE
- * TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr
- * pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH
- * TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
- * pn_extra: if a left-associated binary TOK_PLUS
- * tree has been flattened into a list (see above
- * under <Expressions>), pn_extra will contain
- * PNX_STRCAT if at least one list element is a
- * string literal (TOK_STRING); if such a list has
- * any non-string, non-number term, pn_extra will
- * contain PNX_CANTFOLD.
- * pn_
- * TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB
- * TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
- * TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
- * TOK_UNARYOP unary pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS,
- * JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID
- * TOK_INC, unary pn_kid: MEMBER expr
- * TOK_DEC
- * TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN
- * pn_count: 1 + N (where N is number of args)
- * ctor is a MEMBER expr
- * TOK_DELETE unary pn_kid: MEMBER expr
- * TOK_DOT name pn_expr: MEMBER expr to left of .
- * pn_atom: name to right of .
- * TOK_LB binary pn_left: MEMBER expr to left of [
- * pn_right: expr between [ and ]
- * TOK_LP list pn_head: list of call, arg1, arg2, ... argN
- * pn_count: 1 + N (where N is number of args)
- * call is a MEMBER expr naming a callable object
- * TOK_RB list pn_head: list of pn_count array element exprs
- * [,,] holes are represented by TOK_COMMA nodes
- * #n=[...] produces TOK_DEFSHARP at head of list
- * pn_extra: true if extra comma at end
- * TOK_RC list pn_head: list of pn_count TOK_COLON nodes where
- * each has pn_left: property id, pn_right: value
- * #n={...} produces TOK_DEFSHARP at head of list
- * TOK_DEFSHARP unary pn_num: jsint value of n in #n=
- * pn_kid: null for #n=[...] and #n={...}, primary
- * if #n=primary for function, paren, name, object
- * literal expressions
- * TOK_USESHARP nullary pn_num: jsint value of n in #n#
- * TOK_RP unary pn_kid: parenthesized expression
- * TOK_NAME, name pn_atom: name, string, or object atom
- * TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT
- * TOK_OBJECT If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
- * with pn_slot >= 0 and pn_attrs telling const-ness
- * TOK_NUMBER dval pn_dval: double value of numeric literal
- * TOK_PRIMARY nullary pn_op: JSOp bytecode
- */
-typedef enum JSParseNodeArity {
- PN_FUNC = -3,
- PN_LIST = -2,
- PN_TERNARY = 3,
- PN_BINARY = 2,
- PN_UNARY = 1,
- PN_NAME = -1,
- PN_NULLARY = 0
-} JSParseNodeArity;
-
-struct JSParseNode {
- JSTokenType pn_type;
- JSTokenPos pn_pos;
- JSOp pn_op;
- ptrdiff_t pn_offset; /* first generated bytecode offset */
- JSParseNodeArity pn_arity;
- union {
- struct { /* TOK_FUNCTION node */
- JSAtom *funAtom; /* atomized function object */
- JSParseNode *body; /* TOK_LC list of statements */
- uint32 flags; /* accumulated tree context flags */
- uint32 tryCount; /* count of try statements in body */
- } func;
- struct { /* list of next-linked nodes */
- JSParseNode *head; /* first node in list */
- JSParseNode **tail; /* ptr to ptr to last node in list */
- uint32 count; /* number of nodes in list */
- uint32 extra; /* extra comma flag for [1,2,,] */
- } list;
- struct { /* ternary: if, for(;;), ?: */
- JSParseNode *kid1; /* condition, discriminant, etc. */
- JSParseNode *kid2; /* then-part, case list, etc. */
- JSParseNode *kid3; /* else-part, default case, etc. */
- } ternary;
- struct { /* two kids if binary */
- JSParseNode *left;
- JSParseNode *right;
- jsval val; /* switch case value */
- } binary;
- struct { /* one kid if unary */
- JSParseNode *kid;
- jsint num; /* -1 or sharp variable number */
- } unary;
- struct { /* name, labeled statement, etc. */
- JSAtom *atom; /* name or label atom, null if slot */
- JSParseNode *expr; /* object or initializer */
- jsint slot; /* -1 or arg or local var slot */
- uintN attrs; /* attributes if local var or const */
- } name;
- jsdouble dval; /* aligned numeric literal value */
- } pn_u;
- JSParseNode *pn_next; /* to align dval and pn_u on RISCs */
-};
-
-#define pn_funAtom pn_u.func.funAtom
-#define pn_body pn_u.func.body
-#define pn_flags pn_u.func.flags
-#define pn_tryCount pn_u.func.tryCount
-#define pn_head pn_u.list.head
-#define pn_tail pn_u.list.tail
-#define pn_count pn_u.list.count
-#define pn_extra pn_u.list.extra
-#define pn_kid1 pn_u.ternary.kid1
-#define pn_kid2 pn_u.ternary.kid2
-#define pn_kid3 pn_u.ternary.kid3
-#define pn_left pn_u.binary.left
-#define pn_right pn_u.binary.right
-#define pn_val pn_u.binary.val
-#define pn_kid pn_u.unary.kid
-#define pn_num pn_u.unary.num
-#define pn_atom pn_u.name.atom
-#define pn_expr pn_u.name.expr
-#define pn_slot pn_u.name.slot
-#define pn_attrs pn_u.name.attrs
-#define pn_dval pn_u.dval
-
-/* PN_LIST pn_extra flags. */
-#define PNX_STRCAT 0x1 /* TOK_PLUS list has string term */
-#define PNX_CANTFOLD 0x2 /* TOK_PLUS list has unfoldable term */
-
-/*
- * Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing off
- * any kids in pn2->pn_u, by clearing pn2.
- */
-#define PN_MOVE_NODE(pn, pn2) \
- JS_BEGIN_MACRO \
- (pn)->pn_type = (pn2)->pn_type; \
- (pn)->pn_op = (pn2)->pn_op; \
- (pn)->pn_arity = (pn2)->pn_arity; \
- (pn)->pn_u = (pn2)->pn_u; \
- PN_CLEAR_NODE(pn2); \
- JS_END_MACRO
-
-#define PN_CLEAR_NODE(pn) \
- JS_BEGIN_MACRO \
- (pn)->pn_type = TOK_EOF; \
- (pn)->pn_op = JSOP_NOP; \
- (pn)->pn_arity = PN_NULLARY; \
- JS_END_MACRO
-
-/* True if pn is a parsenode representing a literal constant. */
-#define PN_IS_CONSTANT(pn) \
- ((pn)->pn_type == TOK_NUMBER || \
- (pn)->pn_type == TOK_STRING || \
- ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS))
-
-/*
- * Compute a pointer to the last JSParseNode element in a singly-linked list.
- * NB: list must be non-empty for correct PN_LAST usage!
- */
-#define PN_LAST(list) \
- ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next)))
-
-#define PN_INIT_LIST(list) \
- JS_BEGIN_MACRO \
- (list)->pn_head = NULL; \
- (list)->pn_tail = &(list)->pn_head; \
- (list)->pn_count = 0; \
- JS_END_MACRO
-
-#define PN_INIT_LIST_1(list, pn) \
- JS_BEGIN_MACRO \
- (list)->pn_head = (pn); \
- (list)->pn_tail = &(pn)->pn_next; \
- (list)->pn_count = 1; \
- JS_END_MACRO
-
-#define PN_APPEND(list, pn) \
- JS_BEGIN_MACRO \
- *(list)->pn_tail = (pn); \
- (list)->pn_tail = &(pn)->pn_next; \
- (list)->pn_count++; \
- JS_END_MACRO
-
-/*
- * Parse a top-level JS script.
- *
- * The caller must prevent the GC from running while this function is active,
- * because atoms and function newborns are not rooted yet.
- */
-extern JS_FRIEND_API(JSParseNode *)
-js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts);
-
-extern JS_FRIEND_API(JSBool)
-js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
- JSCodeGenerator *cg);
-
-extern JSBool
-js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun);
-
-extern JSBool
-js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc);
-
-JS_END_EXTERN_C
-
-#endif /* jsparse_h___ */
diff --git a/src/extension/script/js/jsprf.c b/src/extension/script/js/jsprf.c
deleted file mode 100644
index 36bf92428..000000000
--- a/src/extension/script/js/jsprf.c
+++ /dev/null
@@ -1,1212 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-** Portable safe sprintf code.
-**
-** Author: Kipp E.B. Hickman
-*/
-#include "jsstddef.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "jsprf.h"
-#include "jslong.h"
-#include "jsutil.h" /* Added by JSIFY */
-
-/*
-** Note: on some platforms va_list is defined as an array,
-** and requires array notation.
-*/
-#ifdef HAVE_VA_COPY
-#define VARARGS_ASSIGN(foo, bar) VA_COPY(foo,bar)
-#elif defined(HAVE_VA_LIST_AS_ARRAY)
-#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
-#else
-#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
-#endif
-
-/*
-** WARNING: This code may *NOT* call JS_LOG (because JS_LOG calls it)
-*/
-
-/*
-** XXX This needs to be internationalized!
-*/
-
-typedef struct SprintfStateStr SprintfState;
-
-struct SprintfStateStr {
- int (*stuff)(SprintfState *ss, const char *sp, JSUint32 len);
-
- char *base;
- char *cur;
- JSUint32 maxlen;
-
- int (*func)(void *arg, const char *sp, JSUint32 len);
- void *arg;
-};
-
-/*
-** Numbered Arguement State
-*/
-struct NumArgState{
- int type; /* type of the current ap */
- va_list ap; /* point to the corresponding position on ap */
-};
-
-#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgumentState array */
-
-
-#define TYPE_INT16 0
-#define TYPE_UINT16 1
-#define TYPE_INTN 2
-#define TYPE_UINTN 3
-#define TYPE_INT32 4
-#define TYPE_UINT32 5
-#define TYPE_INT64 6
-#define TYPE_UINT64 7
-#define TYPE_STRING 8
-#define TYPE_DOUBLE 9
-#define TYPE_INTSTR 10
-#define TYPE_UNKNOWN 20
-
-#define FLAG_LEFT 0x1
-#define FLAG_SIGNED 0x2
-#define FLAG_SPACED 0x4
-#define FLAG_ZEROS 0x8
-#define FLAG_NEG 0x10
-
-/*
-** Fill into the buffer using the data in src
-*/
-static int fill2(SprintfState *ss, const char *src, int srclen, int width,
- int flags)
-{
- char space = ' ';
- int rv;
-
- width -= srclen;
- if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */
- if (flags & FLAG_ZEROS) {
- space = '0';
- }
- while (--width >= 0) {
- rv = (*ss->stuff)(ss, &space, 1);
- if (rv < 0) {
- return rv;
- }
- }
- }
-
- /* Copy out the source data */
- rv = (*ss->stuff)(ss, src, (JSUint32)srclen);
- if (rv < 0) {
- return rv;
- }
-
- if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */
- while (--width >= 0) {
- rv = (*ss->stuff)(ss, &space, 1);
- if (rv < 0) {
- return rv;
- }
- }
- }
- return 0;
-}
-
-/*
-** Fill a number. The order is: optional-sign zero-filling conversion-digits
-*/
-static int fill_n(SprintfState *ss, const char *src, int srclen, int width,
- int prec, int type, int flags)
-{
- int zerowidth = 0;
- int precwidth = 0;
- int signwidth = 0;
- int leftspaces = 0;
- int rightspaces = 0;
- int cvtwidth;
- int rv;
- char sign;
-
- if ((type & 1) == 0) {
- if (flags & FLAG_NEG) {
- sign = '-';
- signwidth = 1;
- } else if (flags & FLAG_SIGNED) {
- sign = '+';
- signwidth = 1;
- } else if (flags & FLAG_SPACED) {
- sign = ' ';
- signwidth = 1;
- }
- }
- cvtwidth = signwidth + srclen;
-
- if (prec > 0) {
- if (prec > srclen) {
- precwidth = prec - srclen; /* Need zero filling */
- cvtwidth += precwidth;
- }
- }
-
- if ((flags & FLAG_ZEROS) && (prec < 0)) {
- if (width > cvtwidth) {
- zerowidth = width - cvtwidth; /* Zero filling */
- cvtwidth += zerowidth;
- }
- }
-
- if (flags & FLAG_LEFT) {
- if (width > cvtwidth) {
- /* Space filling on the right (i.e. left adjusting) */
- rightspaces = width - cvtwidth;
- }
- } else {
- if (width > cvtwidth) {
- /* Space filling on the left (i.e. right adjusting) */
- leftspaces = width - cvtwidth;
- }
- }
- while (--leftspaces >= 0) {
- rv = (*ss->stuff)(ss, " ", 1);
- if (rv < 0) {
- return rv;
- }
- }
- if (signwidth) {
- rv = (*ss->stuff)(ss, &sign, 1);
- if (rv < 0) {
- return rv;
- }
- }
- while (--precwidth >= 0) {
- rv = (*ss->stuff)(ss, "0", 1);
- if (rv < 0) {
- return rv;
- }
- }
- while (--zerowidth >= 0) {
- rv = (*ss->stuff)(ss, "0", 1);
- if (rv < 0) {
- return rv;
- }
- }
- rv = (*ss->stuff)(ss, src, (JSUint32)srclen);
- if (rv < 0) {
- return rv;
- }
- while (--rightspaces >= 0) {
- rv = (*ss->stuff)(ss, " ", 1);
- if (rv < 0) {
- return rv;
- }
- }
- return 0;
-}
-
-/*
-** Convert a long into its printable form
-*/
-static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix,
- int type, int flags, const char *hexp)
-{
- char cvtbuf[100];
- char *cvt;
- int digits;
-
- /* according to the man page this needs to happen */
- if ((prec == 0) && (num == 0)) {
- return 0;
- }
-
- /*
- ** Converting decimal is a little tricky. In the unsigned case we
- ** need to stop when we hit 10 digits. In the signed case, we can
- ** stop when the number is zero.
- */
- cvt = cvtbuf + sizeof(cvtbuf);
- digits = 0;
- while (num) {
- int digit = (((unsigned long)num) % radix) & 0xF;
- *--cvt = hexp[digit];
- digits++;
- num = (long)(((unsigned long)num) / radix);
- }
- if (digits == 0) {
- *--cvt = '0';
- digits++;
- }
-
- /*
- ** Now that we have the number converted without its sign, deal with
- ** the sign and zero padding.
- */
- return fill_n(ss, cvt, digits, width, prec, type, flags);
-}
-
-/*
-** Convert a 64-bit integer into its printable form
-*/
-static int cvt_ll(SprintfState *ss, JSInt64 num, int width, int prec, int radix,
- int type, int flags, const char *hexp)
-{
- char cvtbuf[100];
- char *cvt;
- int digits;
- JSInt64 rad;
-
- /* according to the man page this needs to happen */
- if ((prec == 0) && (JSLL_IS_ZERO(num))) {
- return 0;
- }
-
- /*
- ** Converting decimal is a little tricky. In the unsigned case we
- ** need to stop when we hit 10 digits. In the signed case, we can
- ** stop when the number is zero.
- */
- JSLL_I2L(rad, radix);
- cvt = cvtbuf + sizeof(cvtbuf);
- digits = 0;
- while (!JSLL_IS_ZERO(num)) {
- JSInt32 digit;
- JSInt64 quot, rem;
- JSLL_UDIVMOD(&quot, &rem, num, rad);
- JSLL_L2I(digit, rem);
- *--cvt = hexp[digit & 0xf];
- digits++;
- num = quot;
- }
- if (digits == 0) {
- *--cvt = '0';
- digits++;
- }
-
- /*
- ** Now that we have the number converted without its sign, deal with
- ** the sign and zero padding.
- */
- return fill_n(ss, cvt, digits, width, prec, type, flags);
-}
-
-/*
-** Convert a double precision floating point number into its printable
-** form.
-**
-** XXX stop using sprintf to convert floating point
-*/
-static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1)
-{
- char fin[20];
- char fout[300];
- int amount = fmt1 - fmt0;
-
- JS_ASSERT((amount > 0) && (amount < (int)sizeof(fin)));
- if (amount >= (int)sizeof(fin)) {
- /* Totally bogus % command to sprintf. Just ignore it */
- return 0;
- }
- memcpy(fin, fmt0, (size_t)amount);
- fin[amount] = 0;
-
- /* Convert floating point using the native sprintf code */
-#ifdef DEBUG
- {
- const char *p = fin;
- while (*p) {
- JS_ASSERT(*p != 'L');
- p++;
- }
- }
-#endif
- sprintf(fout, fin, d);
-
- /*
- ** This assert will catch overflow's of fout, when building with
- ** debugging on. At least this way we can track down the evil piece
- ** of calling code and fix it!
- */
- JS_ASSERT(strlen(fout) < sizeof(fout));
-
- return (*ss->stuff)(ss, fout, strlen(fout));
-}
-
-/*
-** Convert a string into its printable form. "width" is the output
-** width. "prec" is the maximum number of characters of "s" to output,
-** where -1 means until NUL.
-*/
-static int cvt_s(SprintfState *ss, const char *s, int width, int prec,
- int flags)
-{
- int slen;
-
- if (prec == 0)
- return 0;
-
- /* Limit string length by precision value */
- slen = s ? strlen(s) : 6;
- if (prec > 0) {
- if (prec < slen) {
- slen = prec;
- }
- }
-
- /* and away we go */
- return fill2(ss, s ? s : "(null)", slen, width, flags);
-}
-
-/*
-** BiuldArgArray stands for Numbered Argument list Sprintf
-** for example,
-** fmp = "%4$i, %2$d, %3s, %1d";
-** the number must start from 1, and no gap among them
-*/
-
-static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArgState* nasArray )
-{
- int number = 0, cn = 0, i;
- const char* p;
- char c;
- struct NumArgState* nas;
-
-
- /*
- ** first pass:
- ** detemine how many legal % I have got, then allocate space
- */
-
- p = fmt;
- *rv = 0;
- i = 0;
- while( ( c = *p++ ) != 0 ){
- if( c != '%' )
- continue;
- if( ( c = *p++ ) == '%' ) /* skip %% case */
- continue;
-
- while( c != 0 ){
- if( c > '9' || c < '0' ){
- if( c == '$' ){ /* numbered argument csae */
- if( i > 0 ){
- *rv = -1;
- return NULL;
- }
- number++;
- } else { /* non-numbered argument case */
- if( number > 0 ){
- *rv = -1;
- return NULL;
- }
- i = 1;
- }
- break;
- }
-
- c = *p++;
- }
- }
-
- if( number == 0 ){
- return NULL;
- }
-
-
- if( number > NAS_DEFAULT_NUM ){
- nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) );
- if( !nas ){
- *rv = -1;
- return NULL;
- }
- } else {
- nas = nasArray;
- }
-
- for( i = 0; i < number; i++ ){
- nas[i].type = TYPE_UNKNOWN;
- }
-
-
- /*
- ** second pass:
- ** set nas[].type
- */
-
- p = fmt;
- while( ( c = *p++ ) != 0 ){
- if( c != '%' ) continue;
- c = *p++;
- if( c == '%' ) continue;
-
- cn = 0;
- while( c && c != '$' ){ /* should imporve error check later */
- cn = cn*10 + c - '0';
- c = *p++;
- }
-
- if( !c || cn < 1 || cn > number ){
- *rv = -1;
- break;
- }
-
- /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */
- cn--;
- if( nas[cn].type != TYPE_UNKNOWN )
- continue;
-
- c = *p++;
-
- /* width */
- if (c == '*') {
- /* not supported feature, for the argument is not numbered */
- *rv = -1;
- break;
- }
-
- while ((c >= '0') && (c <= '9')) {
- c = *p++;
- }
-
- /* precision */
- if (c == '.') {
- c = *p++;
- if (c == '*') {
- /* not supported feature, for the argument is not numbered */
- *rv = -1;
- break;
- }
-
- while ((c >= '0') && (c <= '9')) {
- c = *p++;
- }
- }
-
- /* size */
- nas[cn].type = TYPE_INTN;
- if (c == 'h') {
- nas[cn].type = TYPE_INT16;
- c = *p++;
- } else if (c == 'L') {
- /* XXX not quite sure here */
- nas[cn].type = TYPE_INT64;
- c = *p++;
- } else if (c == 'l') {
- nas[cn].type = TYPE_INT32;
- c = *p++;
- if (c == 'l') {
- nas[cn].type = TYPE_INT64;
- c = *p++;
- }
- }
-
- /* format */
- switch (c) {
- case 'd':
- case 'c':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- break;
-
- case 'e':
- case 'f':
- case 'g':
- nas[ cn ].type = TYPE_DOUBLE;
- break;
-
- case 'p':
- /* XXX should use cpp */
- if (sizeof(void *) == sizeof(JSInt32)) {
- nas[ cn ].type = TYPE_UINT32;
- } else if (sizeof(void *) == sizeof(JSInt64)) {
- nas[ cn ].type = TYPE_UINT64;
- } else if (sizeof(void *) == sizeof(JSIntn)) {
- nas[ cn ].type = TYPE_UINTN;
- } else {
- nas[ cn ].type = TYPE_UNKNOWN;
- }
- break;
-
- case 'C':
- case 'S':
- case 'E':
- case 'G':
- /* XXX not supported I suppose */
- JS_ASSERT(0);
- nas[ cn ].type = TYPE_UNKNOWN;
- break;
-
- case 's':
- nas[ cn ].type = TYPE_STRING;
- break;
-
- case 'n':
- nas[ cn ].type = TYPE_INTSTR;
- break;
-
- default:
- JS_ASSERT(0);
- nas[ cn ].type = TYPE_UNKNOWN;
- break;
- }
-
- /* get a legal para. */
- if( nas[ cn ].type == TYPE_UNKNOWN ){
- *rv = -1;
- break;
- }
- }
-
-
- /*
- ** third pass
- ** fill the nas[cn].ap
- */
-
- if( *rv < 0 ){
- if( nas != nasArray )
- JS_DELETE( nas );
- return NULL;
- }
-
- cn = 0;
- while( cn < number ){
- if( nas[cn].type == TYPE_UNKNOWN ){
- cn++;
- continue;
- }
-
- VARARGS_ASSIGN(nas[cn].ap, ap);
-
- switch( nas[cn].type ){
- case TYPE_INT16:
- case TYPE_UINT16:
- case TYPE_INTN:
- case TYPE_UINTN: (void)va_arg( ap, JSIntn ); break;
-
- case TYPE_INT32: (void)va_arg( ap, JSInt32 ); break;
-
- case TYPE_UINT32: (void)va_arg( ap, JSUint32 ); break;
-
- case TYPE_INT64: (void)va_arg( ap, JSInt64 ); break;
-
- case TYPE_UINT64: (void)va_arg( ap, JSUint64 ); break;
-
- case TYPE_STRING: (void)va_arg( ap, char* ); break;
-
- case TYPE_INTSTR: (void)va_arg( ap, JSIntn* ); break;
-
- case TYPE_DOUBLE: (void)va_arg( ap, double ); break;
-
- default:
- if( nas != nasArray )
- JS_DELETE( nas );
- *rv = -1;
- return NULL;
- }
-
- cn++;
- }
-
-
- return nas;
-}
-
-/*
-** The workhorse sprintf code.
-*/
-static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
-{
- char c;
- int flags, width, prec, radix, type;
- union {
- char ch;
- int i;
- long l;
- JSInt64 ll;
- double d;
- const char *s;
- int *ip;
- } u;
- const char *fmt0;
- static char *hex = "0123456789abcdef";
- static char *HEX = "0123456789ABCDEF";
- char *hexp;
- int rv, i;
- struct NumArgState* nas = NULL;
- struct NumArgState nasArray[ NAS_DEFAULT_NUM ];
- char pattern[20];
- const char* dolPt = NULL; /* in "%4$.2f", dolPt will poiont to . */
-
-
- /*
- ** build an argument array, IF the fmt is numbered argument
- ** list style, to contain the Numbered Argument list pointers
- */
-
- nas = BuildArgArray( fmt, ap, &rv, nasArray );
- if( rv < 0 ){
- /* the fmt contains error Numbered Argument format, jliu@netscape.com */
- JS_ASSERT(0);
- return rv;
- }
-
- while ((c = *fmt++) != 0) {
- if (c != '%') {
- rv = (*ss->stuff)(ss, fmt - 1, 1);
- if (rv < 0) {
- return rv;
- }
- continue;
- }
- fmt0 = fmt - 1;
-
- /*
- ** Gobble up the % format string. Hopefully we have handled all
- ** of the strange cases!
- */
- flags = 0;
- c = *fmt++;
- if (c == '%') {
- /* quoting a % with %% */
- rv = (*ss->stuff)(ss, fmt - 1, 1);
- if (rv < 0) {
- return rv;
- }
- continue;
- }
-
- if( nas != NULL ){
- /* the fmt contains the Numbered Arguments feature */
- i = 0;
- while( c && c != '$' ){ /* should imporve error check later */
- i = ( i * 10 ) + ( c - '0' );
- c = *fmt++;
- }
-
- if( nas[i-1].type == TYPE_UNKNOWN ){
- if( nas && ( nas != nasArray ) )
- JS_DELETE( nas );
- return -1;
- }
-
- ap = nas[i-1].ap;
- dolPt = fmt;
- c = *fmt++;
- }
-
- /*
- * Examine optional flags. Note that we do not implement the
- * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is
- * somewhat ambiguous and not ideal, which is perhaps why
- * the various sprintf() implementations are inconsistent
- * on this feature.
- */
- while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) {
- if (c == '-') flags |= FLAG_LEFT;
- if (c == '+') flags |= FLAG_SIGNED;
- if (c == ' ') flags |= FLAG_SPACED;
- if (c == '0') flags |= FLAG_ZEROS;
- c = *fmt++;
- }
- if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED;
- if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS;
-
- /* width */
- if (c == '*') {
- c = *fmt++;
- width = va_arg(ap, int);
- } else {
- width = 0;
- while ((c >= '0') && (c <= '9')) {
- width = (width * 10) + (c - '0');
- c = *fmt++;
- }
- }
-
- /* precision */
- prec = -1;
- if (c == '.') {
- c = *fmt++;
- if (c == '*') {
- c = *fmt++;
- prec = va_arg(ap, int);
- } else {
- prec = 0;
- while ((c >= '0') && (c <= '9')) {
- prec = (prec * 10) + (c - '0');
- c = *fmt++;
- }
- }
- }
-
- /* size */
- type = TYPE_INTN;
- if (c == 'h') {
- type = TYPE_INT16;
- c = *fmt++;
- } else if (c == 'L') {
- /* XXX not quite sure here */
- type = TYPE_INT64;
- c = *fmt++;
- } else if (c == 'l') {
- type = TYPE_INT32;
- c = *fmt++;
- if (c == 'l') {
- type = TYPE_INT64;
- c = *fmt++;
- }
- }
-
- /* format */
- hexp = hex;
- switch (c) {
- case 'd': case 'i': /* decimal/integer */
- radix = 10;
- goto fetch_and_convert;
-
- case 'o': /* octal */
- radix = 8;
- type |= 1;
- goto fetch_and_convert;
-
- case 'u': /* unsigned decimal */
- radix = 10;
- type |= 1;
- goto fetch_and_convert;
-
- case 'x': /* unsigned hex */
- radix = 16;
- type |= 1;
- goto fetch_and_convert;
-
- case 'X': /* unsigned HEX */
- radix = 16;
- hexp = HEX;
- type |= 1;
- goto fetch_and_convert;
-
- fetch_and_convert:
- switch (type) {
- case TYPE_INT16:
- u.l = va_arg(ap, int);
- if (u.l < 0) {
- u.l = -u.l;
- flags |= FLAG_NEG;
- }
- goto do_long;
- case TYPE_UINT16:
- u.l = va_arg(ap, int) & 0xffff;
- goto do_long;
- case TYPE_INTN:
- u.l = va_arg(ap, int);
- if (u.l < 0) {
- u.l = -u.l;
- flags |= FLAG_NEG;
- }
- goto do_long;
- case TYPE_UINTN:
- u.l = (long)va_arg(ap, unsigned int);
- goto do_long;
-
- case TYPE_INT32:
- u.l = va_arg(ap, JSInt32);
- if (u.l < 0) {
- u.l = -u.l;
- flags |= FLAG_NEG;
- }
- goto do_long;
- case TYPE_UINT32:
- u.l = (long)va_arg(ap, JSUint32);
- do_long:
- rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp);
- if (rv < 0) {
- return rv;
- }
- break;
-
- case TYPE_INT64:
- u.ll = va_arg(ap, JSInt64);
- if (!JSLL_GE_ZERO(u.ll)) {
- JSLL_NEG(u.ll, u.ll);
- flags |= FLAG_NEG;
- }
- goto do_longlong;
- case TYPE_UINT64:
- u.ll = va_arg(ap, JSUint64);
- do_longlong:
- rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp);
- if (rv < 0) {
- return rv;
- }
- break;
- }
- break;
-
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- u.d = va_arg(ap, double);
- if( nas != NULL ){
- i = fmt - dolPt;
- if( i < (int)sizeof( pattern ) ){
- pattern[0] = '%';
- memcpy( &pattern[1], dolPt, (size_t)i );
- rv = cvt_f(ss, u.d, pattern, &pattern[i+1] );
- }
- } else
- rv = cvt_f(ss, u.d, fmt0, fmt);
-
- if (rv < 0) {
- return rv;
- }
- break;
-
- case 'c':
- u.ch = va_arg(ap, int);
- if ((flags & FLAG_LEFT) == 0) {
- while (width-- > 1) {
- rv = (*ss->stuff)(ss, " ", 1);
- if (rv < 0) {
- return rv;
- }
- }
- }
- rv = (*ss->stuff)(ss, &u.ch, 1);
- if (rv < 0) {
- return rv;
- }
- if (flags & FLAG_LEFT) {
- while (width-- > 1) {
- rv = (*ss->stuff)(ss, " ", 1);
- if (rv < 0) {
- return rv;
- }
- }
- }
- break;
-
- case 'p':
- if (sizeof(void *) == sizeof(JSInt32)) {
- type = TYPE_UINT32;
- } else if (sizeof(void *) == sizeof(JSInt64)) {
- type = TYPE_UINT64;
- } else if (sizeof(void *) == sizeof(int)) {
- type = TYPE_UINTN;
- } else {
- JS_ASSERT(0);
- break;
- }
- radix = 16;
- goto fetch_and_convert;
-
-#if 0
- case 'C':
- case 'S':
- case 'E':
- case 'G':
- /* XXX not supported I suppose */
- JS_ASSERT(0);
- break;
-#endif
-
- case 's':
- u.s = va_arg(ap, const char*);
- rv = cvt_s(ss, u.s, width, prec, flags);
- if (rv < 0) {
- return rv;
- }
- break;
-
- case 'n':
- u.ip = va_arg(ap, int*);
- if (u.ip) {
- *u.ip = ss->cur - ss->base;
- }
- break;
-
- default:
- /* Not a % token after all... skip it */
-#if 0
- JS_ASSERT(0);
-#endif
- rv = (*ss->stuff)(ss, "%", 1);
- if (rv < 0) {
- return rv;
- }
- rv = (*ss->stuff)(ss, fmt - 1, 1);
- if (rv < 0) {
- return rv;
- }
- }
- }
-
- /* Stuff trailing NUL */
- rv = (*ss->stuff)(ss, "\0", 1);
-
- if( nas && ( nas != nasArray ) ){
- JS_DELETE( nas );
- }
-
- return rv;
-}
-
-/************************************************************************/
-
-static int FuncStuff(SprintfState *ss, const char *sp, JSUint32 len)
-{
- int rv;
-
- rv = (*ss->func)(ss->arg, sp, len);
- if (rv < 0) {
- return rv;
- }
- ss->maxlen += len;
- return 0;
-}
-
-JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc func, void *arg,
- const char *fmt, ...)
-{
- va_list ap;
- int rv;
-
- va_start(ap, fmt);
- rv = JS_vsxprintf(func, arg, fmt, ap);
- va_end(ap);
- return rv;
-}
-
-JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc func, void *arg,
- const char *fmt, va_list ap)
-{
- SprintfState ss;
- int rv;
-
- ss.stuff = FuncStuff;
- ss.func = func;
- ss.arg = arg;
- ss.maxlen = 0;
- rv = dosprintf(&ss, fmt, ap);
- return (rv < 0) ? (JSUint32)-1 : ss.maxlen;
-}
-
-/*
-** Stuff routine that automatically grows the malloc'd output buffer
-** before it overflows.
-*/
-static int GrowStuff(SprintfState *ss, const char *sp, JSUint32 len)
-{
- ptrdiff_t off;
- char *newbase;
- JSUint32 newlen;
-
- off = ss->cur - ss->base;
- if (off + len >= ss->maxlen) {
- /* Grow the buffer */
- newlen = ss->maxlen + ((len > 32) ? len : 32);
- if (ss->base) {
- newbase = (char*) realloc(ss->base, newlen);
- } else {
- newbase = (char*) malloc(newlen);
- }
- if (!newbase) {
- /* Ran out of memory */
- return -1;
- }
- ss->base = newbase;
- ss->maxlen = newlen;
- ss->cur = ss->base + off;
- }
-
- /* Copy data */
- while (len) {
- --len;
- *ss->cur++ = *sp++;
- }
- JS_ASSERT((JSUint32)(ss->cur - ss->base) <= ss->maxlen);
- return 0;
-}
-
-/*
-** sprintf into a malloc'd buffer
-*/
-JS_PUBLIC_API(char *) JS_smprintf(const char *fmt, ...)
-{
- va_list ap;
- char *rv;
-
- va_start(ap, fmt);
- rv = JS_vsmprintf(fmt, ap);
- va_end(ap);
- return rv;
-}
-
-/*
-** Free memory allocated, for the caller, by JS_smprintf
-*/
-JS_PUBLIC_API(void) JS_smprintf_free(char *mem)
-{
- JS_DELETE(mem);
-}
-
-JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap)
-{
- SprintfState ss;
- int rv;
-
- ss.stuff = GrowStuff;
- ss.base = 0;
- ss.cur = 0;
- ss.maxlen = 0;
- rv = dosprintf(&ss, fmt, ap);
- if (rv < 0) {
- if (ss.base) {
- JS_DELETE(ss.base);
- }
- return 0;
- }
- return ss.base;
-}
-
-/*
-** Stuff routine that discards overflow data
-*/
-static int LimitStuff(SprintfState *ss, const char *sp, JSUint32 len)
-{
- JSUint32 limit = ss->maxlen - (ss->cur - ss->base);
-
- if (len > limit) {
- len = limit;
- }
- while (len) {
- --len;
- *ss->cur++ = *sp++;
- }
- return 0;
-}
-
-/*
-** sprintf into a fixed size buffer. Make sure there is a NUL at the end
-** when finished.
-*/
-JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...)
-{
- va_list ap;
- int rv;
-
- JS_ASSERT((JSInt32)outlen > 0);
- if ((JSInt32)outlen <= 0) {
- return 0;
- }
-
- va_start(ap, fmt);
- rv = JS_vsnprintf(out, outlen, fmt, ap);
- va_end(ap);
- return rv;
-}
-
-JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen,const char *fmt,
- va_list ap)
-{
- SprintfState ss;
- JSUint32 n;
-
- JS_ASSERT((JSInt32)outlen > 0);
- if ((JSInt32)outlen <= 0) {
- return 0;
- }
-
- ss.stuff = LimitStuff;
- ss.base = out;
- ss.cur = out;
- ss.maxlen = outlen;
- (void) dosprintf(&ss, fmt, ap);
-
- /* If we added chars, and we didn't append a null, do it now. */
- if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') )
- *(--ss.cur) = '\0';
-
- n = ss.cur - ss.base;
- return n ? n - 1 : n;
-}
-
-JS_PUBLIC_API(char *) JS_sprintf_append(char *last, const char *fmt, ...)
-{
- va_list ap;
- char *rv;
-
- va_start(ap, fmt);
- rv = JS_vsprintf_append(last, fmt, ap);
- va_end(ap);
- return rv;
-}
-
-JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap)
-{
- SprintfState ss;
- int rv;
-
- ss.stuff = GrowStuff;
- if (last) {
- int lastlen = strlen(last);
- ss.base = last;
- ss.cur = last + lastlen;
- ss.maxlen = lastlen;
- } else {
- ss.base = 0;
- ss.cur = 0;
- ss.maxlen = 0;
- }
- rv = dosprintf(&ss, fmt, ap);
- if (rv < 0) {
- if (ss.base) {
- JS_DELETE(ss.base);
- }
- return 0;
- }
- return ss.base;
-}
-
diff --git a/src/extension/script/js/jsprf.h b/src/extension/script/js/jsprf.h
deleted file mode 100644
index e8cc46c0c..000000000
--- a/src/extension/script/js/jsprf.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsprf_h___
-#define jsprf_h___
-
-/*
-** API for PR printf like routines. Supports the following formats
-** %d - decimal
-** %u - unsigned decimal
-** %x - unsigned hex
-** %X - unsigned uppercase hex
-** %o - unsigned octal
-** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
-** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
-** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
-** %s - string
-** %c - character
-** %p - pointer (deals with machine dependent pointer size)
-** %f - float
-** %g - float
-*/
-#include "jstypes.h"
-#include <stdio.h>
-#include <stdarg.h>
-
-JS_BEGIN_EXTERN_C
-
-/*
-** sprintf into a fixed size buffer. Guarantees that a NUL is at the end
-** of the buffer. Returns the length of the written output, NOT including
-** the NUL, or (JSUint32)-1 if an error occurs.
-*/
-extern JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...);
-
-/*
-** sprintf into a malloc'd buffer. Return a pointer to the malloc'd
-** buffer on success, NULL on failure. Call "JS_smprintf_free" to release
-** the memory returned.
-*/
-extern JS_PUBLIC_API(char*) JS_smprintf(const char *fmt, ...);
-
-/*
-** Free the memory allocated, for the caller, by JS_smprintf
-*/
-extern JS_PUBLIC_API(void) JS_smprintf_free(char *mem);
-
-/*
-** "append" sprintf into a malloc'd buffer. "last" is the last value of
-** the malloc'd buffer. sprintf will append data to the end of last,
-** growing it as necessary using realloc. If last is NULL, JS_sprintf_append
-** will allocate the initial string. The return value is the new value of
-** last for subsequent calls, or NULL if there is a malloc failure.
-*/
-extern JS_PUBLIC_API(char*) JS_sprintf_append(char *last, const char *fmt, ...);
-
-/*
-** sprintf into a function. The function "f" is called with a string to
-** place into the output. "arg" is an opaque pointer used by the stuff
-** function to hold any state needed to do the storage of the output
-** data. The return value is a count of the number of characters fed to
-** the stuff function, or (JSUint32)-1 if an error occurs.
-*/
-typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen);
-
-extern JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...);
-
-/*
-** va_list forms of the above.
-*/
-extern JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap);
-extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap);
-extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap);
-extern JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap);
-
-/*
-***************************************************************************
-** FUNCTION: JS_sscanf
-** DESCRIPTION:
-** JS_sscanf() scans the input character string, performs data
-** conversions, and stores the converted values in the data objects
-** pointed to by its arguments according to the format control
-** string.
-**
-** JS_sscanf() behaves the same way as the sscanf() function in the
-** Standard C Library (stdio.h), with the following exceptions:
-** - JS_sscanf() handles the NSPR integer and floating point types,
-** such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas
-** sscanf() handles the standard C types like short, int, long,
-** and double.
-** - JS_sscanf() has no multibyte character support, while sscanf()
-** does.
-** INPUTS:
-** const char *buf
-** a character string holding the input to scan
-** const char *fmt
-** the format control string for the conversions
-** ...
-** variable number of arguments, each of them is a pointer to
-** a data object in which the converted value will be stored
-** OUTPUTS: none
-** RETURNS: JSInt32
-** The number of values converted and stored.
-** RESTRICTIONS:
-** Multibyte characters in 'buf' or 'fmt' are not allowed.
-***************************************************************************
-*/
-
-extern JS_PUBLIC_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...);
-
-JS_END_EXTERN_C
-
-#endif /* jsprf_h___ */
diff --git a/src/extension/script/js/jsprvtd.h b/src/extension/script/js/jsprvtd.h
deleted file mode 100644
index f5f1e77f6..000000000
--- a/src/extension/script/js/jsprvtd.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsprvtd_h___
-#define jsprvtd_h___
-/*
- * JS private typename definitions.
- *
- * This header is included only in other .h files, for convenience and for
- * simplicity of type naming. The alternative for structures is to use tags,
- * which are named the same as their typedef names (legal in C/C++, and less
- * noisy than suffixing the typedef name with "Struct" or "Str"). Instead,
- * all .h files that include this file may use the same typedef name, whether
- * declaring a pointer to struct type, or defining a member of struct type.
- *
- * A few fundamental scalar types are defined here too. Neither the scalar
- * nor the struct typedefs should change much, therefore the nearly-global
- * make dependency induced by this file should not prove painful.
- */
-
-#include "jspubtd.h"
-
-/* Scalar typedefs. */
-typedef uint8 jsbytecode;
-typedef uint8 jssrcnote;
-typedef uint32 jsatomid;
-
-/* Struct typedefs. */
-typedef struct JSArgumentFormatMap JSArgumentFormatMap;
-typedef struct JSCodeGenerator JSCodeGenerator;
-typedef struct JSDependentString JSDependentString;
-typedef struct JSGCLockHashEntry JSGCLockHashEntry;
-typedef struct JSGCRootHashEntry JSGCRootHashEntry;
-typedef struct JSGCThing JSGCThing;
-typedef struct JSParseNode JSParseNode;
-typedef struct JSSharpObjectMap JSSharpObjectMap;
-typedef struct JSToken JSToken;
-typedef struct JSTokenPos JSTokenPos;
-typedef struct JSTokenPtr JSTokenPtr;
-typedef struct JSTokenStream JSTokenStream;
-typedef struct JSTreeContext JSTreeContext;
-typedef struct JSTryNote JSTryNote;
-
-/* Friend "Advanced API" typedefs. */
-typedef struct JSAtom JSAtom;
-typedef struct JSAtomList JSAtomList;
-typedef struct JSAtomListElement JSAtomListElement;
-typedef struct JSAtomMap JSAtomMap;
-typedef struct JSAtomState JSAtomState;
-typedef struct JSCodeSpec JSCodeSpec;
-typedef struct JSPrinter JSPrinter;
-typedef struct JSRegExp JSRegExp;
-typedef struct JSRegExpStatics JSRegExpStatics;
-typedef struct JSScope JSScope;
-typedef struct JSScopeOps JSScopeOps;
-typedef struct JSScopeProperty JSScopeProperty;
-typedef struct JSStackFrame JSStackFrame;
-typedef struct JSStackHeader JSStackHeader;
-typedef struct JSSubString JSSubString;
-
-/* "Friend" types used by jscntxt.h and jsdbgapi.h. */
-typedef enum JSTrapStatus {
- JSTRAP_ERROR,
- JSTRAP_CONTINUE,
- JSTRAP_RETURN,
- JSTRAP_THROW,
- JSTRAP_LIMIT
-} JSTrapStatus;
-
-typedef JSTrapStatus
-(* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc,
- jsval *rval, void *closure);
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id,
- jsval old, jsval *newp, void *closure);
-
-/* called just after script creation */
-typedef void
-(* JS_DLL_CALLBACK JSNewScriptHook)(JSContext *cx,
- const char *filename, /* URL of script */
- uintN lineno, /* line script starts */
- JSScript *script,
- JSFunction *fun,
- void *callerdata);
-
-/* called just before script destruction */
-typedef void
-(* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx,
- JSScript *script,
- void *callerdata);
-
-typedef void
-(* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno,
- jschar *str, size_t length,
- void **listenerTSData, void *closure);
-
-/*
-* This hook captures high level script execution and function calls
-* (JS or native).
-* It is used by JS_SetExecuteHook to hook top level scripts and by
-* JS_SetCallHook to hook function calls.
-* It will get called twice per script or function call:
-* just before execution begins and just after it finishes. In both cases
-* the 'current' frame is that of the executing code.
-*
-* The 'before' param is JS_TRUE for the hook invocation before the execution
-* and JS_FALSE for the invocation after the code has run.
-*
-* The 'ok' param is significant only on the post execution invocation to
-* signify whether or not the code completed 'normally'.
-*
-* The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
-* for the 'before'invocation, but is whatever value is returned from that
-* invocation for the 'after' invocation. Thus, the hook implementor *could*
-* allocate a stucture in the 'before' invocation and return a pointer
-* to that structure. The pointer would then be handed to the hook for
-* the 'after' invocation. Alternately, the 'before' could just return the
-* same value as in 'closure' to cause the 'after' invocation to be called
-* with the same 'closure' value as the 'before'.
-*
-* Returning NULL in the 'before' hook will cause the 'after' hook to
-* NOT be called.
-*/
-
-typedef void *
-(* JS_DLL_CALLBACK JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before,
- JSBool *ok, void *closure);
-
-typedef void
-(* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew,
- void *closure);
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message,
- JSErrorReport *report, void *closure);
-
-#endif /* jsprvtd_h___ */
diff --git a/src/extension/script/js/jspubtd.h b/src/extension/script/js/jspubtd.h
deleted file mode 100644
index e3a1a38b5..000000000
--- a/src/extension/script/js/jspubtd.h
+++ /dev/null
@@ -1,564 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jspubtd_h___
-#define jspubtd_h___
-/*
- * JS public API typedefs.
- */
-#include "jstypes.h"
-#include "jscompat.h"
-
-JS_BEGIN_EXTERN_C
-
-/* Scalar typedefs. */
-typedef uint16 jschar;
-typedef int32 jsint;
-typedef uint32 jsuint;
-typedef float64 jsdouble;
-typedef jsword jsval;
-typedef jsword jsid;
-typedef int32 jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */
-
-/*
- * Run-time version enumeration. See jsconfig.h for compile-time counterparts
- * to these values that may be selected by the JS_VERSION macro, and tested by
- * #if expressions.
- */
-typedef enum JSVersion {
- JSVERSION_1_0 = 100,
- JSVERSION_1_1 = 110,
- JSVERSION_1_2 = 120,
- JSVERSION_1_3 = 130,
- JSVERSION_1_4 = 140,
- JSVERSION_ECMA_3 = 148,
- JSVERSION_1_5 = 150,
- JSVERSION_DEFAULT = 0,
- JSVERSION_UNKNOWN = -1
-} JSVersion;
-
-#define JSVERSION_IS_ECMA(version) \
- ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3)
-
-/* Result of typeof operator enumeration. */
-typedef enum JSType {
- JSTYPE_VOID, /* undefined */
- JSTYPE_OBJECT, /* object */
- JSTYPE_FUNCTION, /* function */
- JSTYPE_STRING, /* string */
- JSTYPE_NUMBER, /* number */
- JSTYPE_BOOLEAN, /* boolean */
- JSTYPE_LIMIT
-} JSType;
-
-/* JSObjectOps.checkAccess mode enumeration. */
-typedef enum JSAccessMode {
- JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */
- JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */
- JSACC_IMPORT = 2, /* import foo.bar */
- JSACC_WATCH = 3, /* a watchpoint on object foo for id 'bar' */
- JSACC_READ = 4, /* a "get" of foo.bar */
- JSACC_WRITE = 8, /* a "set" of foo.bar = baz */
- JSACC_LIMIT
-} JSAccessMode;
-
-#define JSACC_TYPEMASK (JSACC_WRITE - 1)
-
-/*
- * This enum type is used to control the behavior of a JSObject property
- * iterator function that has type JSNewEnumerate.
- */
-typedef enum JSIterateOp {
- JSENUMERATE_INIT, /* Create new iterator state */
- JSENUMERATE_NEXT, /* Iterate once */
- JSENUMERATE_DESTROY /* Destroy iterator state */
-} JSIterateOp;
-
-/* Struct typedefs. */
-typedef struct JSClass JSClass;
-typedef struct JSConstDoubleSpec JSConstDoubleSpec;
-typedef struct JSContext JSContext;
-typedef struct JSErrorReport JSErrorReport;
-typedef struct JSFunction JSFunction;
-typedef struct JSFunctionSpec JSFunctionSpec;
-typedef struct JSIdArray JSIdArray;
-typedef struct JSProperty JSProperty;
-typedef struct JSPropertySpec JSPropertySpec;
-typedef struct JSObject JSObject;
-typedef struct JSObjectMap JSObjectMap;
-typedef struct JSObjectOps JSObjectOps;
-typedef struct JSRuntime JSRuntime;
-typedef struct JSRuntime JSTaskState; /* XXX deprecated name */
-typedef struct JSScript JSScript;
-typedef struct JSString JSString;
-typedef struct JSXDRState JSXDRState;
-typedef struct JSExceptionState JSExceptionState;
-typedef struct JSLocaleCallbacks JSLocaleCallbacks;
-
-/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */
-
-/*
- * Add, delete, get or set a property named by id in obj. Note the jsval id
- * type -- id may be a string (Unicode property identifier) or an int (element
- * index). The *vp out parameter, on success, is the new property value after
- * an add, get, or set. After a successful delete, *vp is JSVAL_FALSE iff
- * obj[id] can't be deleted (because it's permanent).
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id,
- jsval *vp);
-
-/*
- * This function type is used for callbacks that enumerate the properties of
- * a JSObject. The behavior depends on the value of enum_op:
- *
- * JSENUMERATE_INIT
- * A new, opaque iterator state should be allocated and stored in *statep.
- * (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored).
- *
- * The number of properties that will be enumerated should be returned as
- * an integer jsval in *idp, if idp is non-null, and provided the number of
- * enumerable properties is known. If idp is non-null and the number of
- * enumerable properties can't be computed in advance, *idp should be set
- * to JSVAL_ZERO.
- *
- * JSENUMERATE_NEXT
- * A previously allocated opaque iterator state is passed in via statep.
- * Return the next jsid in the iteration using *idp. The opaque iterator
- * state pointed at by statep is destroyed and *statep is set to JSVAL_NULL
- * if there are no properties left to enumerate.
- *
- * JSENUMERATE_DESTROY
- * Destroy the opaque iterator state previously allocated in *statep by a
- * call to this function when enum_op was JSENUMERATE_INIT.
- *
- * The return value is used to indicate success, with a value of JS_FALSE
- * indicating failure.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSNewEnumerateOp)(JSContext *cx, JSObject *obj,
- JSIterateOp enum_op,
- jsval *statep, jsid *idp);
-
-/*
- * The old-style JSClass.enumerate op should define all lazy properties not
- * yet reflected in obj.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSEnumerateOp)(JSContext *cx, JSObject *obj);
-
-/*
- * Resolve a lazy property named by id in obj by defining it directly in obj.
- * Lazy properties are those reflected from some peer native property space
- * (e.g., the DOM attributes for a given node reflected as obj) on demand.
- *
- * JS looks for a property in an object, and if not found, tries to resolve
- * the given id. If resolve succeeds, the engine looks again in case resolve
- * defined obj[id]. If no such property exists directly in obj, the process
- * is repeated with obj's prototype, etc.
- *
- * NB: JSNewResolveOp provides a cheaper way to resolve lazy properties.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSResolveOp)(JSContext *cx, JSObject *obj, jsval id);
-
-/*
- * Like JSResolveOp, but flags provide contextual information as follows:
- *
- * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id
- * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment
- *
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
- *
- * This hook instead of JSResolveOp is called via the JSClass.resolve member
- * if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
- *
- * Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further
- * extends this hook by passing in the starting object on the prototype chain
- * via *objp. Thus a resolve hook implementation may define the property id
- * being resolved in the object in which the id was first sought, rather than
- * in a prototype object whose class led to the resolve hook being called.
- *
- * When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore
- * null *objp to signify "not resolved". With only JSCLASS_NEW_RESOLVE and no
- * JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry.
- * This is not good practice, but enough existing hook implementations count
- * on it that we can't break compatibility by passing the starting object in
- * *objp without a new JSClass flag.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSNewResolveOp)(JSContext *cx, JSObject *obj, jsval id,
- uintN flags, JSObject **objp);
-
-/*
- * Convert obj to the given type, returning true with the resulting value in
- * *vp on success, and returning false on error or exception.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSConvertOp)(JSContext *cx, JSObject *obj, JSType type,
- jsval *vp);
-
-/*
- * Finalize obj, which the garbage collector has determined to be unreachable
- * from other live objects or from GC roots. Obviously, finalizers must never
- * store a reference to obj.
- */
-typedef void
-(* JS_DLL_CALLBACK JSFinalizeOp)(JSContext *cx, JSObject *obj);
-
-/*
- * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer
- * to extend and reduce the set of string types finalized by the GC.
- */
-typedef void
-(* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str);
-
-/*
- * The signature for JSClass.getObjectOps, used by JS_NewObject's internals
- * to discover the set of high-level object operations to use for new objects
- * of the given class. All native objects have a JSClass, which is stored as
- * a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS]. In contrast,
- * all native and host objects have a JSObjectMap at obj->map, which may be
- * shared among a number of objects, and which contains the JSObjectOps *ops
- * pointer used to dispatch object operations from API calls.
- *
- * Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-level
- * interface to class-specific code and data, while JSObjectOps allows for a
- * higher level of operation, which does not use the object's class except to
- * find the class's JSObjectOps struct, by calling clasp->getObjectOps.
- *
- * If this seems backwards, that's because it is! API compatibility requires
- * a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do not
- * need to implement the larger JSObjectOps, and can share the common JSScope
- * code and data used by the native (js_ObjectOps, see jsobj.c) ops.
- */
-typedef JSObjectOps *
-(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, JSClass *clasp);
-
-/*
- * JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
- * returning false on error/exception, true on success with obj[id]'s last-got
- * value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id
- * is either a string or an int jsval.
- *
- * See JSCheckAccessIdOp, below, for the JSObjectOps counterpart, which takes
- * a jsid (a tagged int or aligned, unique identifier pointer) rather than a
- * jsval. The native js_ObjectOps.checkAccess simply forwards to the object's
- * clasp->checkAccess, so that both JSClass and JSObjectOps implementors may
- * specialize access checks.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsval id,
- JSAccessMode mode, jsval *vp);
-
-/*
- * Encode or decode an object, given an XDR state record representing external
- * data. See jsxdrapi.h.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp);
-
-/*
- * Check whether v is an instance of obj. Return false on error or exception,
- * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in
- * *bp otherwise.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v,
- JSBool *bp);
-
-/*
- * Function type for JSClass.mark and JSObjectOps.mark, called from the GC to
- * scan live GC-things reachable from obj's private data structure. For each
- * such thing, a mark implementation must call
- *
- * JS_MarkGCThing(cx, thing, name, arg);
- *
- * The trailing name and arg parameters are used for GC_MARK_DEBUG-mode heap
- * dumping and ref-path tracing. The mark function should pass a (typically
- * literal) string naming the private data member for name, and it must pass
- * the opaque arg parameter through from its caller.
- *
- * For the JSObjectOps.mark hook, the return value is the number of slots at
- * obj->slots to scan. For JSClass.mark, the return value is ignored.
- *
- * NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject
- * called from a mark function will fail silently, e.g.).
- */
-typedef uint32
-(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg);
-
-/* JSObjectOps function pointer typedefs. */
-
-/*
- * Create a new subclass of JSObjectMap (see jsobj.h), with the nrefs and ops
- * members initialized from the same-named parameters, and with the nslots and
- * freeslot members initialized according to ops and clasp. Return null on
- * error, non-null on success.
- *
- * JSObjectMaps are reference-counted by generic code in the engine. Usually,
- * the nrefs parameter to JSObjectOps.newObjectMap will be 1, to count the ref
- * returned to the caller on success. After a successful construction, some
- * number of js_HoldObjectMap and js_DropObjectMap calls ensue. When nrefs
- * reaches 0 due to a js_DropObjectMap call, JSObjectOps.destroyObjectMap will
- * be called to dispose of the map.
- */
-typedef JSObjectMap *
-(* JS_DLL_CALLBACK JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs,
- JSObjectOps *ops, JSClass *clasp,
- JSObject *obj);
-
-/*
- * Generic type for an infallible JSObjectMap operation, used currently by
- * JSObjectOps.destroyObjectMap.
- */
-typedef void
-(* JS_DLL_CALLBACK JSObjectMapOp)(JSContext *cx, JSObjectMap *map);
-
-/*
- * Look for id in obj and its prototype chain, returning false on error or
- * exception, true on success. On success, return null in *propp if id was
- * not found. If id was found, return the first object searching from obj
- * along its prototype chain in which id names a direct property in *objp, and
- * return a non-null, opaque property pointer in *propp.
- *
- * If JSLookupPropOp succeeds and returns with *propp non-null, that pointer
- * may be passed as the prop parameter to a JSAttributesOp, as a short-cut
- * that bypasses id re-lookup. In any case, a non-null *propp result after a
- * successful lookup must be dropped via JSObjectOps.dropProperty.
- *
- * NB: successful return with non-null *propp means the implementation may
- * have locked *objp and added a reference count associated with *propp, so
- * callers should not risk deadlock by nesting or interleaving other lookups
- * or any obj-bearing ops before dropping *propp.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id,
- JSObject **objp, JSProperty **propp
-#if defined JS_THREADSAFE && defined DEBUG
- , const char *file, uintN line
-#endif
- );
-
-/*
- * Define obj[id], a direct property of obj named id, having the given initial
- * value, with the specified getter, setter, and attributes. If the propp out
- * param is non-null, *propp on successful return contains an opaque property
- * pointer usable as a speedup hint with JSAttributesOp. But note that propp
- * may be null, indicating that the caller is not interested in recovering an
- * opaque pointer to the newly-defined property.
- *
- * If propp is non-null and JSDefinePropOp succeeds, its caller must be sure
- * to drop *propp using JSObjectOps.dropProperty in short order, just as with
- * JSLookupPropOp.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSDefinePropOp)(JSContext *cx, JSObject *obj,
- jsid id, jsval value,
- JSPropertyOp getter, JSPropertyOp setter,
- uintN attrs, JSProperty **propp);
-
-/*
- * Get, set, or delete obj[id], returning false on error or exception, true
- * on success. If getting or setting, the new value is returned in *vp on
- * success. If deleting without error, *vp will be JSVAL_FALSE if obj[id] is
- * permanent, and JSVAL_TRUE if id named a direct property of obj that was in
- * fact deleted, or if id names no direct property of obj (id could name a
- * prototype property, or no property in obj or its prototype chain).
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id,
- jsval *vp);
-
-/*
- * Get or set attributes of the property obj[id]. Return false on error or
- * exception, true with current attributes in *attrsp. If prop is non-null,
- * it must come from the *propp out parameter of a prior JSDefinePropOp or
- * JSLookupPropOp call.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id,
- JSProperty *prop, uintN *attrsp);
-
-/*
- * JSObjectOps.checkAccess type: check whether obj[id] may be accessed per
- * mode, returning false on error/exception, true on success with obj[id]'s
- * last-got value in *vp, and its attributes in *attrsp.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSCheckAccessIdOp)(JSContext *cx, JSObject *obj, jsid id,
- JSAccessMode mode, jsval *vp,
- uintN *attrsp);
-
-/*
- * A generic type for functions mapping an object to another object, or null
- * if an error or exception was thrown on cx. Used by JSObjectOps.thisObject
- * at present.
- */
-typedef JSObject *
-(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj);
-
-/*
- * A generic type for functions taking a context, object, and property, with
- * no return value. Used by JSObjectOps.dropProperty currently (see above,
- * JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in which
- * dropProperty participates).
- */
-typedef void
-(* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj,
- JSProperty *prop);
-
-/*
- * Function type for JSObjectOps.setProto and JSObjectOps.setParent. These
- * hooks must check for cycles without deadlocking, and otherwise take special
- * steps. See jsobj.c, js_SetProtoOrParent, for an example.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj,
- uint32 slot, JSObject *pobj);
-
-/*
- * Get and set a required slot, one that should already have been allocated.
- * These operations are infallible, so required slots must be pre-allocated,
- * or implementations must suppress out-of-memory errors. The native ops
- * (js_ObjectOps, see jsobj.c) access slots reserved by including a call to
- * the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer.
- *
- * NB: the slot parameter is a zero-based index into obj->slots[], unlike the
- * index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API entry
- * points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clasp)
- * reserved slots that come after the initial well-known slots: proto, parent,
- * class, and optionally, the private data slot.
- */
-typedef jsval
-(* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj,
- uint32 slot);
-
-typedef void
-(* JS_DLL_CALLBACK JSSetRequiredSlotOp)(JSContext *cx, JSObject *obj,
- uint32 slot, jsval v);
-
-/* Typedef for native functions called by the JS VM. */
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc,
- jsval *argv, jsval *rval);
-
-/* Callbacks and their arguments. */
-
-typedef enum JSGCStatus {
- JSGC_BEGIN,
- JSGC_END,
- JSGC_MARK_END,
- JSGC_FINALIZE_END
-} JSGCStatus;
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status);
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script);
-
-typedef void
-(* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message,
- JSErrorReport *report);
-
-typedef struct JSErrorFormatString {
- const char *format;
- uintN argCount;
-} JSErrorFormatString;
-
-typedef const JSErrorFormatString *
-(* JS_DLL_CALLBACK JSErrorCallback)(void *userRef, const char *locale,
- const uintN errorNumber);
-
-#ifdef va_start
-#define JS_ARGUMENT_FORMATTER_DEFINED 1
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSArgumentFormatter)(JSContext *cx, const char *format,
- JSBool fromJS, jsval **vpp,
- va_list *app);
-#endif
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSLocaleToUpperCase)(JSContext *cx, JSString *src,
- jsval *rval);
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSLocaleToLowerCase)(JSContext *cx, JSString *src,
- jsval *rval);
-
-typedef JSBool
-(* JS_DLL_CALLBACK JSLocaleCompare)(JSContext *cx,
- JSString *src1, JSString *src2,
- jsval *rval);
-
-/*
- * Security protocol types.
- */
-typedef struct JSPrincipals JSPrincipals;
-
-/*
- * XDR-encode or -decode a principals instance, based on whether xdr->mode is
- * JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE,
- * in which case implementations must return a held (via JSPRINCIPALS_HOLD),
- * non-null *principalsp out parameter. Return true on success, false on any
- * error, which the implementation must have reported.
- */
-typedef JSBool
-(* JS_DLL_CALLBACK JSPrincipalsTranscoder)(JSXDRState *xdr,
- JSPrincipals **principalsp);
-
-/*
- * Return a weak reference to the principals associated with obj, possibly via
- * the immutable parent chain leading from obj to a top-level container (e.g.,
- * a window object in the DOM level 0). If there are no principals associated
- * with obj, return null. Therefore null does not mean an error was reported;
- * in no event should an error be reported or an exception be thrown by this
- * callback's implementation.
- */
-typedef JSPrincipals *
-(* JS_DLL_CALLBACK JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj);
-
-JS_END_EXTERN_C
-
-#endif /* jspubtd_h___ */
diff --git a/src/extension/script/js/jsregexp.c b/src/extension/script/js/jsregexp.c
deleted file mode 100644
index 18ab92c35..000000000
--- a/src/extension/script/js/jsregexp.c
+++ /dev/null
@@ -1,3773 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS regular expressions, after Perl.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsfun.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsregexp.h"
-#include "jsscan.h"
-#include "jsstr.h"
-
-#ifdef XP_MAC
-#include <MacMemory.h>
-#endif
-
-#if JS_HAS_REGEXPS
-
-/* Note : contiguity of 'simple opcodes' is important for simpleMatch() */
-typedef enum REOp {
- REOP_EMPTY = 0, /* match rest of input against rest of r.e. */
- REOP_ALT = 1, /* alternative subexpressions in kid and next */
- REOP_SIMPLE_START = 2, /* start of 'simple opcodes' */
- REOP_BOL = 2, /* beginning of input (or line if multiline) */
- REOP_EOL = 3, /* end of input (or line if multiline) */
- REOP_WBDRY = 4, /* match "" at word boundary */
- REOP_WNONBDRY = 5, /* match "" at word non-boundary */
- REOP_DOT = 6, /* stands for any character */
- REOP_DIGIT = 7, /* match a digit char: [0-9] */
- REOP_NONDIGIT = 8, /* match a non-digit char: [^0-9] */
- REOP_ALNUM = 9, /* match an alphanumeric char: [0-9a-z_A-Z] */
- REOP_NONALNUM = 10, /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
- REOP_SPACE = 11, /* match a whitespace char */
- REOP_NONSPACE = 12, /* match a non-whitespace char */
- REOP_BACKREF = 13, /* back-reference (e.g., \1) to a parenthetical */
- REOP_FLAT = 14, /* match a flat string */
- REOP_FLAT1 = 15, /* match a single char */
- REOP_FLATi = 16, /* case-independent REOP_FLAT */
- REOP_FLAT1i = 17, /* case-independent REOP_FLAT1 */
- REOP_UCFLAT1 = 18, /* single Unicode char */
- REOP_UCFLAT1i = 19, /* case-independent REOP_UCFLAT1 */
- REOP_UCFLAT = 20, /* flat Unicode string; len immediate counts chars */
- REOP_UCFLATi = 21, /* case-independent REOP_UCFLAT */
- REOP_CLASS = 22, /* character class with index */
- REOP_NCLASS = 23, /* negated character class with index */
- REOP_SIMPLE_END = 23, /* end of 'simple opcodes' */
- REOP_QUANT = 25, /* quantified atom: atom{1,2} */
- REOP_STAR = 26, /* zero or more occurrences of kid */
- REOP_PLUS = 27, /* one or more occurrences of kid */
- REOP_OPT = 28, /* optional subexpression in kid */
- REOP_LPAREN = 29, /* left paren bytecode: kid is u.num'th sub-regexp */
- REOP_RPAREN = 30, /* right paren bytecode */
- REOP_JUMP = 31, /* for deoptimized closure loops */
- REOP_DOTSTAR = 32, /* optimize .* to use a single opcode */
- REOP_ANCHOR = 33, /* like .* but skips left context to unanchored r.e. */
- REOP_EOLONLY = 34, /* $ not preceded by any pattern */
- REOP_BACKREFi = 37, /* case-independent REOP_BACKREF */
- REOP_LPARENNON = 41, /* non-capturing version of REOP_LPAREN */
- REOP_ASSERT = 43, /* zero width positive lookahead assertion */
- REOP_ASSERT_NOT = 44, /* zero width negative lookahead assertion */
- REOP_ASSERTTEST = 45, /* sentinel at end of assertion child */
- REOP_ASSERTNOTTEST = 46, /* sentinel at end of !assertion child */
- REOP_MINIMALSTAR = 47, /* non-greedy version of * */
- REOP_MINIMALPLUS = 48, /* non-greedy version of + */
- REOP_MINIMALOPT = 49, /* non-greedy version of ? */
- REOP_MINIMALQUANT = 50, /* non-greedy version of {} */
- REOP_ENDCHILD = 51, /* sentinel at end of quantifier child */
- REOP_REPEAT = 52, /* directs execution of greedy quantifier */
- REOP_MINIMALREPEAT = 53, /* directs execution of non-greedy quantifier */
- REOP_ALTPREREQ = 54, /* prerequisite for ALT, either of two chars */
- REOP_ALTPREREQ2 = 55, /* prerequisite for ALT, a char or a class */
- REOP_ENDALT = 56, /* end of final alternate */
- REOP_CONCAT = 57, /* concatenation of terms (parse time only) */
-
- REOP_END
-} REOp;
-
-#define REOP_IS_SIMPLE(op) (((op) >= REOP_SIMPLE_START) && ((op) <= REOP_SIMPLE_END))
-
-struct RENode {
- REOp op; /* r.e. op bytecode */
- RENode *next; /* next in concatenation order */
- void *kid; /* first operand */
- union {
- void *kid2; /* second operand */
- jsint num; /* could be a number */
- jsint parenIndex; /* or a parenthesis index */
- struct { /* or a quantifier range */
- uint16 min;
- uint16 max;
- JSBool greedy;
- } range;
- struct { /* or a character class */
- uint16 startIndex;
- uint16 kidlen; /* length of string at kid, in jschars */
- uint16 bmsize; /* bitmap size, based on max char code */
- uint16 index; /* index into class list */
- JSBool sense;
- } ucclass;
- struct { /* or a literal sequence */
- jschar chr; /* of one character */
- uint16 length; /* or many (via the kid) */
- } flat;
- struct {
- RENode *kid2; /* second operand from ALT */
- jschar ch1; /* match char for ALTPREREQ */
- jschar ch2; /* ditto, or class index for ALTPREREQ2 */
- } altprereq;
- } u;
-};
-
-#define RE_IS_LETTER(c) ( ((c >= 'A') && (c <= 'Z')) || \
- ((c >= 'a') && (c <= 'z')) )
-#define RE_IS_LINE_TERM(c) ( (c == '\n') || (c == '\r') || \
- (c == LINE_SEPARATOR) || (c == PARA_SEPARATOR))
-
-#define CLASS_CACHE_SIZE (4)
-typedef struct CompilerState {
- JSContext *context;
- JSTokenStream *tokenStream; /* For reporting errors */
- const jschar *cpbegin;
- const jschar *cpend;
- const jschar *cp;
- uintN flags;
- uint16 parenCount;
- uint16 classCount; /* number of [] encountered */
- size_t progLength; /* estimated bytecode length */
- uintN treeDepth; /* maximum depth of parse tree */
- RENode *result;
- struct {
- const jschar *start; /* small cache of class strings */
- uint16 length; /* since they're often the same */
- uint16 index;
- } classCache[CLASS_CACHE_SIZE];
-} CompilerState;
-
-typedef struct RECapture {
- int32 index; /* start of contents, -1 for empty */
- uint16 length; /* length of capture */
-} RECapture;
-
-typedef struct REMatchState {
- const jschar *cp;
- RECapture parens[1]; /* first of 're->parenCount' captures,
- * allocated at end of this struct.
- */
-} REMatchState;
-
-struct REBackTrackData;
-
-typedef struct REProgState {
- jsbytecode *continue_pc; /* current continuation data */
- jsbytecode continue_op;
- uint16 index; /* progress in text */
- uintN parenSoFar; /* highest indexed paren started */
- union {
- struct {
- uint16 min; /* current quantifier limits */
- uint16 max;
- } quantifier;
- struct {
- size_t top; /* backtrack stack state */
- size_t sz;
- } assertion;
- } u;
-} REProgState;
-
-typedef struct REBackTrackData {
- size_t sz; /* size of previous stack entry */
- jsbytecode *backtrack_pc; /* where to backtrack to */
- jsbytecode backtrack_op;
- const jschar *cp; /* index in text of match at backtrack */
- intN parenIndex; /* start index of saved paren contents */
- uint16 parenCount; /* # of saved paren contents */
- uint16 precedingStateTop; /* number of parent states */
- /* saved parent states follow */
- /* saved paren contents follow */
-} REBackTrackData;
-
-#define INITIAL_STATESTACK (100)
-#define INITIAL_BACKTRACK (8000)
-
-typedef struct REGlobalData {
- JSContext *cx;
- JSRegExp *regexp; /* the RE in execution */
- JSBool ok; /* runtime error (out_of_memory only?) */
- size_t start; /* offset to start at */
- ptrdiff_t skipped; /* chars skipped anchoring this r.e. */
- const jschar *cpbegin, *cpend; /* text base address and limit */
-
- REProgState *stateStack; /* stack of state of current parents */
- uint16 stateStackTop;
- uint16 maxStateStack;
-
- REBackTrackData *backTrackStack;/* stack of matched-so-far positions */
- REBackTrackData *backTrackSP;
- size_t maxBackTrack;
- size_t cursz; /* size of current stack entry */
-
- JSArenaPool pool; /* I don't understand but it's faster to
- * use this than to malloc/free the three
- * items that are allocated from this pool
- */
-
-} REGlobalData;
-
-
-/*
- * 1. If IgnoreCase is false, return ch.
- * 2. Let u be ch converted to upper case as if by calling
- * String.prototype.toUpperCase on the one-character string ch.
- * 3. If u does not consist of a single character, return ch.
- * 4. Let cu be u's character.
- * 5. If ch's code point value is greater than or equal to decimal 128 and cu's
- * code point value is less than decimal 128, then return ch.
- * 6. Return cu.
- */
-static jschar
-upcase(jschar ch)
-{
- jschar cu = JS_TOUPPER(ch);
- if ((ch >= 128) && (cu < 128)) return ch;
- return cu;
-}
-
-static jschar
-downcase(jschar ch)
-{
- jschar cl = JS_TOLOWER(ch);
- if ((cl >= 128) && (ch < 128)) return ch;
- return cl;
-}
-
-/* Construct and initialize an RENode, returning NULL for out-of-memory */
-static RENode *
-NewRENode(CompilerState *state, REOp op)
-{
- JSContext *cx;
- RENode *ren;
-
- cx = state->context;
- JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren);
- if (!ren) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- ren->op = op;
- ren->next = NULL;
- ren->kid = NULL;
- return ren;
-}
-
-/*
- * Validates and converts hex ascii value.
- */
-static JSBool
-isASCIIHexDigit(jschar c, uintN *digit)
-{
- uintN cv = c;
-
- if (cv < '0')
- return JS_FALSE;
- if (cv <= '9') {
- *digit = cv - '0';
- return JS_TRUE;
- }
- cv |= 0x20;
- if (cv >= 'a' && cv <= 'f') {
- *digit = cv - 'a' + 10;
- return JS_TRUE;
- }
- return JS_FALSE;
-}
-
-
-typedef struct {
- REOp op;
- const jschar *errPos;
- uint16 parenIndex;
-} REOpData;
-
-
-/*
- * Process the op against the two top operands, reducing them to a single
- * operand in the penultimate slot. Update progLength and treeDepth.
- */
-static JSBool
-processOp(CompilerState *state, REOpData *opData, RENode **operandStack, intN operandSP)
-{
- RENode *result;
-
- switch (opData->op) {
- case REOP_ALT:
- result = NewRENode(state, REOP_ALT);
- if (!result)
- return JS_FALSE;
- result->kid = operandStack[operandSP - 2];
- result->u.kid2 = operandStack[operandSP - 1];
- operandStack[operandSP - 2] = result;
- /*
- * look at both alternates to see if there's a FLAT or a CLASS at
- * the start of each. If so, use a prerequisite match
- */
- ++state->treeDepth;
- if ((((RENode *)(result->kid))->op == REOP_FLAT)
- && (((RENode *)(result->u.kid2))->op == REOP_FLAT)
- && ((state->flags & JSREG_FOLD) == 0) ) {
- result->op = REOP_ALTPREREQ;
- result->u.altprereq.ch1
- = ((RENode *)(result->kid))->u.flat.chr;
- result->u.altprereq.ch2
- = ((RENode *)(result->u.kid2))->u.flat.chr;
- /* ALTPREREQ, <end>, uch1, uch2, <next>, ...,
- JUMP, <end> ... ENDALT */
- state->progLength += 13;
- }
- else
- if ((((RENode *)(result->kid))->op == REOP_CLASS)
- && (((RENode *)(result->kid))->u.ucclass.index < 256)
- && (((RENode *)(result->u.kid2))->op == REOP_FLAT)
- && ((state->flags & JSREG_FOLD) == 0) ) {
- result->op = REOP_ALTPREREQ2;
- result->u.altprereq.ch1
- = ((RENode *)(result->u.kid2))->u.flat.chr;
- result->u.altprereq.ch2
- = ((RENode *)(result->kid))->u.ucclass.index;
- /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
- JUMP, <end> ... ENDALT */
- state->progLength += 13;
- }
- else
- if ((((RENode *)(result->kid))->op == REOP_FLAT)
- && (((RENode *)(result->u.kid2))->op == REOP_CLASS)
- && (((RENode *)(result->u.kid2))->u.ucclass.index < 256)
- && ((state->flags & JSREG_FOLD) == 0) ) {
- result->op = REOP_ALTPREREQ2;
- result->u.altprereq.ch1
- = ((RENode *)(result->kid))->u.flat.chr;
- result->u.altprereq.ch2
- = ((RENode *)(result->u.kid2))->u.ucclass.index;
- /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
- JUMP, <end> ... ENDALT */
- state->progLength += 13;
- }
- else
- /* ALT, <next>, ..., JUMP, <end> ... ENDALT */
- state->progLength += 7;
- break;
- case REOP_CONCAT:
- result = operandStack[operandSP - 2];
- while (result->next)
- result = result->next;
- result->next = operandStack[operandSP - 1];
- break;
- case REOP_ASSERT:
- case REOP_ASSERT_NOT:
- case REOP_LPARENNON:
- case REOP_LPAREN:
- /* These should have been processed by a close paren. */
- js_ReportCompileErrorNumber(state->context, state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_MISSING_PAREN, opData->errPos);
- return JS_FALSE;
- default:;
- }
- return JS_TRUE;
-}
-
-/*
- * Parser forward declarations.
- */
-static JSBool parseTerm(CompilerState *state);
-static JSBool parseQuantifier(CompilerState *state);
-
-/*
- * Top-down regular expression grammar, based closely on Perl4.
- *
- * regexp: altern A regular expression is one or more
- * altern '|' regexp alternatives separated by vertical bar.
- */
-
-#define INITIAL_STACK_SIZE (128)
-static JSBool
-parseRegExp(CompilerState *state)
-{
- uint16 parenIndex;
- RENode *operand;
- REOpData *operatorStack;
- RENode **operandStack;
- REOp op;
- intN i;
- JSBool result = JS_FALSE;
-
- intN operatorSP = 0, operatorStackSize = INITIAL_STACK_SIZE;
- intN operandSP = 0, operandStackSize = INITIAL_STACK_SIZE;
-
- /* Watch out for empty regexp */
- if (state->cp == state->cpend) {
- state->result = NewRENode(state, REOP_EMPTY);
- return (state->result != NULL);
- }
-
- operatorStack = (REOpData *)JS_malloc(state->context,
- sizeof(REOpData) * operatorStackSize);
- if (!operatorStack)
- return JS_FALSE;
-
- operandStack = (RENode **)JS_malloc(state->context,
- sizeof(RENode *) * operandStackSize);
- if (!operandStack)
- goto out;
-
-
- while (JS_TRUE) {
- if (state->cp == state->cpend) {
- /*
- * If we are at the end of the regexp and we're short an operand,
- * the regexp must have the form /x|/ or some such.
- */
- if (operatorSP == operandSP) {
- operand = NewRENode(state, REOP_EMPTY);
- if (!operand)
- goto out;
- goto pushOperand;
- }
- } else {
- switch (*state->cp) {
- /* balance '(' */
- case '(': /* balance ')' */
- ++state->cp;
- if ((state->cp < state->cpend) && (*state->cp == '?')
- && ( (state->cp[1] == '=')
- || (state->cp[1] == '!')
- || (state->cp[1] == ':') )) {
- ++state->cp;
- if (state->cp == state->cpend) {
- js_ReportCompileErrorNumber(state->context,
- state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_MISSING_PAREN);
- goto out;
- }
- switch (*state->cp++) {
- case '=':
- op = REOP_ASSERT;
- /* ASSERT, <next>, ... ASSERTTEST */
- state->progLength += 4;
- break;
- case '!':
- op = REOP_ASSERT_NOT;
- /* ASSERTNOT, <next>, ... ASSERTNOTTEST */
- state->progLength += 4;
- break;
- case ':':
- op = REOP_LPARENNON;
- break;
- }
- parenIndex = state->parenCount;
- }
- else {
- op = REOP_LPAREN;
- /* LPAREN, <index>, ... RPAREN, <index> */
- state->progLength += 6;
- parenIndex = state->parenCount++;
- if (state->parenCount == 65535) {
- js_ReportCompileErrorNumber(state->context,
- state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_TOO_MANY_PARENS);
- goto out;
- }
- }
- goto pushOperator;
- case ')':
- /* If there's not a stacked open parenthesis, throw
- * a syntax error.
- */
- for (i = operatorSP - 1; i >= 0; i--)
- if ((operatorStack[i].op == REOP_ASSERT)
- || (operatorStack[i].op == REOP_ASSERT_NOT)
- || (operatorStack[i].op == REOP_LPARENNON)
- || (operatorStack[i].op == REOP_LPAREN))
- break;
- if (i == -1) {
- js_ReportCompileErrorNumber(state->context,
- state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_UNMATCHED_RIGHT_PAREN);
- goto out;
- }
- /* fall thru... */
- case '|':
- /* Expected an operand before these, so make an empty one */
- operand = NewRENode(state, REOP_EMPTY);
- if (!operand)
- goto out;
- goto pushOperand;
- default:
- if (!parseTerm(state))
- goto out;
- operand = state->result;
-pushOperand:
- if (operandSP == operandStackSize) {
- operandStackSize += operandStackSize;
- operandStack =
- (RENode **)JS_realloc(state->context, operandStack,
- sizeof(RENode *) * operandStackSize);
- if (!operandStack)
- goto out;
- }
- operandStack[operandSP++] = operand;
- break;
- }
- }
- /* At the end; process remaining operators */
-restartOperator:
- if (state->cp == state->cpend) {
- while (operatorSP) {
- --operatorSP;
- if (!processOp(state, &operatorStack[operatorSP],
- operandStack, operandSP))
- goto out;
- --operandSP;
- }
- JS_ASSERT(operandSP == 1);
- state->result = operandStack[0];
- result = JS_TRUE;
- goto out;
- }
- switch (*state->cp) {
- case '|':
- /* Process any stacked 'concat' operators */
- ++state->cp;
- while (operatorSP
- && (operatorStack[operatorSP - 1].op == REOP_CONCAT)) {
- --operatorSP;
- if (!processOp(state, &operatorStack[operatorSP],
- operandStack, operandSP))
- goto out;
- --operandSP;
- }
- op = REOP_ALT;
- goto pushOperator;
-
- case ')':
- /* If there's not a stacked open parenthesis,we
- * accept the close as a flat.
- */
- for (i = operatorSP - 1; i >= 0; i--)
- if ((operatorStack[i].op == REOP_ASSERT)
- || (operatorStack[i].op == REOP_ASSERT_NOT)
- || (operatorStack[i].op == REOP_LPARENNON)
- || (operatorStack[i].op == REOP_LPAREN))
- break;
- if (i == -1) {
- js_ReportCompileErrorNumber(state->context,
- state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_UNMATCHED_RIGHT_PAREN);
- goto out;
- }
- ++state->cp;
- /* process everything on the stack until the open */
- while (JS_TRUE) {
- JS_ASSERT(operatorSP);
- --operatorSP;
- switch (operatorStack[operatorSP].op) {
- case REOP_ASSERT:
- case REOP_ASSERT_NOT:
- case REOP_LPAREN:
- operand = NewRENode(state, operatorStack[operatorSP].op);
- if (!operand)
- goto out;
- operand->u.parenIndex
- = operatorStack[operatorSP].parenIndex;
- JS_ASSERT(operandSP);
- operand->kid = operandStack[operandSP - 1];
- operandStack[operandSP - 1] = operand;
- ++state->treeDepth;
- /* fall thru... */
- case REOP_LPARENNON:
- state->result = operandStack[operandSP - 1];
- if (!parseQuantifier(state))
- goto out;
- operandStack[operandSP - 1] = state->result;
- goto restartOperator;
- default:
- if (!processOp(state, &operatorStack[operatorSP],
- operandStack, operandSP))
- goto out;
- --operandSP;
- break;
- }
- }
- break;
- default:
- /* Anything else is the start of the next term */
- op = REOP_CONCAT;
-pushOperator:
- if (operatorSP == operatorStackSize) {
- operatorStackSize += operatorStackSize;
- operatorStack =
- (REOpData *)JS_realloc(state->context, operatorStack,
- sizeof(REOpData) * operatorStackSize);
- if (!operatorStack)
- goto out;
- }
- operatorStack[operatorSP].op = op;
- operatorStack[operatorSP].errPos = state->cp;
- operatorStack[operatorSP++].parenIndex = parenIndex;
- break;
- }
- }
-out:
- if (operatorStack)
- JS_free(state->context, operatorStack);
- if (operandStack)
- JS_free(state->context, operandStack);
- return result;
-}
-
-/*
- * Extract and return a decimal value at state->cp, the
- * initial character 'c' has already been read.
- */
-static intN
-getDecimalValue(jschar c, CompilerState *state)
-{
- intN value = JS7_UNDEC(c);
- while (state->cp < state->cpend) {
- c = *state->cp;
- if (!JS7_ISDEC(c))
- break;
- value = (10 * value) + JS7_UNDEC(c);
- ++state->cp;
- }
- return value;
-}
-
-/*
- * Calculate the total size of the bitmap required for a class expression.
- */
-static JSBool
-calculateBitmapSize(CompilerState *state, RENode *target, const jschar *src,
- const jschar *end)
-{
- jschar rangeStart, c;
- uintN n, digit, nDigits, i;
- uintN max = 0;
- JSBool inRange = JS_FALSE;
-
- target->u.ucclass.bmsize = 0;
- target->u.ucclass.sense = JS_TRUE;
-
- if (src == end)
- return JS_TRUE;
-
- if (*src == '^') {
- ++src;
- target->u.ucclass.sense = JS_FALSE;
- }
-
- while (src != end) {
- uintN localMax = 0;
- switch (*src) {
- case '\\':
- ++src;
- c = *src++;
- switch (c) {
- case 'b':
- localMax = 0x8;
- break;
- case 'f':
- localMax = 0xC;
- break;
- case 'n':
- localMax = 0xA;
- break;
- case 'r':
- localMax = 0xD;
- break;
- case 't':
- localMax = 0x9;
- break;
- case 'v':
- localMax = 0xB;
- break;
- case 'c':
- if (((src + 1) < end) && RE_IS_LETTER(src[1]))
- localMax = (jschar)(*src++ & 0x1F);
- else
- localMax = '\\';
- break;
- case 'x':
- nDigits = 2;
- goto lexHex;
- case 'u':
- nDigits = 4;
-lexHex:
- n = 0;
- for (i = 0; (i < nDigits) && (src < end); i++) {
- c = *src++;
- if (!isASCIIHexDigit(c, &digit)) {
- /*
- * Back off to accepting the original
- *'\' as a literal.
- */
- src -= (i + 1);
- n = '\\';
- break;
- }
- n = (n << 4) | digit;
- }
- localMax = n;
- break;
- case 'd':
- if (inRange) {
- JS_ReportErrorNumber(state->context,
- js_GetErrorMessage, NULL,
- JSMSG_BAD_CLASS_RANGE);
- return JS_FALSE;
- }
- localMax = '9';
- break;
- case 'D':
- case 's':
- case 'S':
- case 'w':
- case 'W':
- if (inRange) {
- JS_ReportErrorNumber(state->context,
- js_GetErrorMessage, NULL,
- JSMSG_BAD_CLASS_RANGE);
- return JS_FALSE;
- }
- target->u.ucclass.bmsize = 65535;
- return JS_TRUE;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /*
- * This is a non-ECMA extension - decimal escapes (in this
- * case, octal!) are supposed to be an error inside class
- * ranges, but supported here for backwards compatibility.
- *
- */
- n = JS7_UNDEC(c);
- c = *src;
- if ('0' <= c && c <= '7') {
- src++;
- n = 8 * n + JS7_UNDEC(c);
- c = *src;
- if ('0' <= c && c <= '7') {
- src++;
- i = 8 * n + JS7_UNDEC(c);
- if (i <= 0377)
- n = i;
- else
- src--;
- }
- }
- localMax = n;
- break;
-
- default:
- localMax = c;
- break;
- }
- break;
- default:
- localMax = *src++;
- break;
- }
- if (inRange) {
- if (rangeStart > localMax) {
- JS_ReportErrorNumber(state->context,
- js_GetErrorMessage, NULL,
- JSMSG_BAD_CLASS_RANGE);
- return JS_FALSE;
- }
- inRange = JS_FALSE;
- }
- else {
- if (src < (end - 1)) {
- if (*src == '-') {
- ++src;
- inRange = JS_TRUE;
- rangeStart = (jschar)localMax;
- continue;
- }
- }
- }
- if (state->flags & JSREG_FOLD) {
- c = JS_MAX(upcase((jschar)localMax), downcase((jschar)localMax));
- if (c > localMax)
- localMax = c;
- }
- if (localMax > max)
- max = localMax;
- }
- target->u.ucclass.bmsize = max;
- return JS_TRUE;
-}
-
-/*
- * item: assertion An item is either an assertion or
- * quantatom a quantified atom.
- *
- * assertion: '^' Assertions match beginning of string
- * (or line if the class static property
- * RegExp.multiline is true).
- * '$' End of string (or line if the class
- * static property RegExp.multiline is
- * true).
- * '\b' Word boundary (between \w and \W).
- * '\B' Word non-boundary.
- *
- * quantatom: atom An unquantified atom.
- * quantatom '{' n ',' m '}'
- * Atom must occur between n and m times.
- * quantatom '{' n ',' '}' Atom must occur at least n times.
- * quantatom '{' n '}' Atom must occur exactly n times.
- * quantatom '*' Zero or more times (same as {0,}).
- * quantatom '+' One or more times (same as {1,}).
- * quantatom '?' Zero or one time (same as {0,1}).
- *
- * any of which can be optionally followed by '?' for ungreedy
- *
- * atom: '(' regexp ')' A parenthesized regexp (what matched
- * can be addressed using a backreference,
- * see '\' n below).
- * '.' Matches any char except '\n'.
- * '[' classlist ']' A character class.
- * '[' '^' classlist ']' A negated character class.
- * '\f' Form Feed.
- * '\n' Newline (Line Feed).
- * '\r' Carriage Return.
- * '\t' Horizontal Tab.
- * '\v' Vertical Tab.
- * '\d' A digit (same as [0-9]).
- * '\D' A non-digit.
- * '\w' A word character, [0-9a-z_A-Z].
- * '\W' A non-word character.
- * '\s' A whitespace character, [ \b\f\n\r\t\v].
- * '\S' A non-whitespace character.
- * '\' n A backreference to the nth (n decimal
- * and positive) parenthesized expression.
- * '\' octal An octal escape sequence (octal must be
- * two or three digits long, unless it is
- * 0 for the null character).
- * '\x' hex A hex escape (hex must be two digits).
- * '\u' unicode A unicode escape (must be four digits).
- * '\c' ctrl A control character, ctrl is a letter.
- * '\' literalatomchar Any character except one of the above
- * that follow '\' in an atom.
- * otheratomchar Any character not first among the other
- * atom right-hand sides.
- */
-static JSBool
-parseTerm(CompilerState *state)
-{
- jschar c = *state->cp++;
- uintN nDigits;
- uintN num, tmp, n, i;
- const jschar *termStart;
- JSBool foundCachedCopy;
-
- switch (c) {
- /* assertions and atoms */
- case '^':
- state->result = NewRENode(state, REOP_BOL);
- if (!state->result)
- return JS_FALSE;
- state->progLength++;
- return JS_TRUE;
- case '$':
- state->result = NewRENode(state, REOP_EOL);
- if (!state->result)
- return JS_FALSE;
- state->progLength++;
- return JS_TRUE;
- case '\\':
- if (state->cp >= state->cpend) {
- /* a trailing '\' is an error */
- js_ReportCompileErrorNumber(state->context, state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_TRAILING_SLASH);
- return JS_FALSE;
- }
- c = *state->cp++;
- switch (c) {
- /* assertion escapes */
- case 'b' :
- state->result = NewRENode(state, REOP_WBDRY);
- if (!state->result)
- return JS_FALSE;
- state->progLength++;
- return JS_TRUE;
- case 'B':
- state->result = NewRENode(state, REOP_WNONBDRY);
- if (!state->result)
- return JS_FALSE;
- state->progLength++;
- return JS_TRUE;
- /* Decimal escape */
- case '0':
- if (JS_HAS_STRICT_OPTION(state->context))
- c = 0;
- else {
- doOctal:
- num = 0;
- while (state->cp < state->cpend) {
- if ('0' <= (c = *state->cp) && c <= '7') {
- state->cp++;
- tmp = 8 * num + (uintN)JS7_UNDEC(c);
- if (tmp > 0377)
- break;
- num = tmp;
- }
- else
- break;
- }
- c = (jschar)(num);
- }
- doFlat:
- state->result = NewRENode(state, REOP_FLAT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.flat.chr = c;
- state->result->u.flat.length = 1;
- state->progLength += 3;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- termStart = state->cp - 1;
- num = (uintN)getDecimalValue(c, state);
- if (num > 9 &&
- num > state->parenCount &&
- !JS_HAS_STRICT_OPTION(state->context)) {
- state->cp = termStart;
- goto doOctal;
- }
- state->result = NewRENode(state, REOP_BACKREF);
- if (!state->result)
- return JS_FALSE;
- state->result->u.parenIndex = num - 1;
- state->progLength += 3;
- break;
- /* Control escape */
- case 'f':
- c = 0xC;
- goto doFlat;
- case 'n':
- c = 0xA;
- goto doFlat;
- case 'r':
- c = 0xD;
- goto doFlat;
- case 't':
- c = 0x9;
- goto doFlat;
- case 'v':
- c = 0xB;
- goto doFlat;
- /* Control letter */
- case 'c':
- if (((state->cp + 1) < state->cpend) &&
- RE_IS_LETTER(state->cp[1]))
- c = (jschar)(*state->cp++ & 0x1F);
- else {
- /* back off to accepting the original '\' as a literal */
- --state->cp;
- c = '\\';
- }
- goto doFlat;
- /* HexEscapeSequence */
- case 'x':
- nDigits = 2;
- goto lexHex;
- /* UnicodeEscapeSequence */
- case 'u':
- nDigits = 4;
-lexHex:
- n = 0;
- for (i = 0; (i < nDigits)
- && (state->cp < state->cpend); i++) {
- uintN digit;
- c = *state->cp++;
- if (!isASCIIHexDigit(c, &digit)) {
- /*
- * back off to accepting the original
- * 'u' or 'x' as a literal
- */
- state->cp -= (i + 2);
- n = *state->cp++;
- break;
- }
- n = (n << 4) | digit;
- }
- c = (jschar)(n);
- goto doFlat;
- /* Character class escapes */
- case 'd':
- state->result = NewRENode(state, REOP_DIGIT);
-doSimple:
- if (!state->result)
- return JS_FALSE;
- state->progLength++;
- break;
- case 'D':
- state->result = NewRENode(state, REOP_NONDIGIT);
- goto doSimple;
- case 's':
- state->result = NewRENode(state, REOP_SPACE);
- goto doSimple;
- case 'S':
- state->result = NewRENode(state, REOP_NONSPACE);
- goto doSimple;
- case 'w':
- state->result = NewRENode(state, REOP_ALNUM);
- goto doSimple;
- case 'W':
- state->result = NewRENode(state, REOP_NONALNUM);
- goto doSimple;
- /* IdentityEscape */
- default:
- state->result = NewRENode(state, REOP_FLAT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.flat.chr = c;
- state->result->u.flat.length = 1;
- state->result->kid = (void *)(state->cp - 1);
- state->progLength += 3;
- break;
- }
- break;
- case '[':
- state->result = NewRENode(state, REOP_CLASS);
- if (!state->result)
- return JS_FALSE;
- termStart = state->cp;
- state->result->u.ucclass.startIndex = termStart - state->cpbegin;
- while (JS_TRUE) {
- if (state->cp == state->cpend) {
- js_ReportCompileErrorNumber(state->context, state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_UNTERM_CLASS, termStart);
- return JS_FALSE;
- }
- if (*state->cp == '\\')
- state->cp++;
- else {
- if (*state->cp == ']') {
- state->result->u.ucclass.kidlen = state->cp - termStart;
- break;
- }
- }
- state->cp++;
- }
- foundCachedCopy = JS_FALSE;
- for (i = 0; i < CLASS_CACHE_SIZE; i++) {
- if (state->classCache[i].start) {
- if (state->classCache[i].length == state->result->u.ucclass.kidlen) {
- foundCachedCopy = JS_TRUE;
- for (n = 0; n < state->classCache[i].length; n++) {
- if (state->classCache[i].start[n] != termStart[n]) {
- foundCachedCopy = JS_FALSE;
- break;
- }
- }
- if (foundCachedCopy) {
- state->result->u.ucclass.index = state->classCache[i].index;
- break;
- }
- }
- }
- else {
- state->classCache[i].start = termStart;
- state->classCache[i].length = state->result->u.ucclass.kidlen;
- state->classCache[i].index = state->classCount;
- break;
- }
- }
- if (!foundCachedCopy)
- state->result->u.ucclass.index = state->classCount++;
- /*
- * Call calculateBitmapSize now as we want any errors it finds
- * to be reported during the parse phase, not at execution.
- */
- if (!calculateBitmapSize(state, state->result, termStart, state->cp++))
- return JS_FALSE;
- state->progLength += 3; /* CLASS, <index> */
- break;
-
- case '.':
- state->result = NewRENode(state, REOP_DOT);
- goto doSimple;
- case '*':
- case '+':
- case '?':
- js_ReportCompileErrorNumber(state->context, state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_BAD_QUANTIFIER, state->cp - 1);
- return JS_FALSE;
-#if 0
- case '{': /* balance '}' */
- /* Treat left-curly in a non-quantifier context as an error only
- * if it's followed immediately by a decimal digit.
- * This is an Perl extension.
- */
- if ((state->cp != state->cpend) && JS7_ISDEC(*state->cp)) {
- js_ReportCompileErrorNumber(state->context, state->tokenStream,
- NULL, JSREPORT_ERROR,
- JSMSG_BAD_QUANTIFIER, state->cp - 1);
- return JS_FALSE;
- }
- /* fall thru... */
-#endif
- default:
- state->result = NewRENode(state, REOP_FLAT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.flat.chr = c;
- state->result->u.flat.length = 1;
- state->result->kid = (void *)(state->cp - 1);
- state->progLength += 3;
- break;
- }
- return parseQuantifier(state);
-}
-
-static JSBool
-parseQuantifier(CompilerState *state)
-{
- RENode *term;
- term = state->result;
- if (state->cp < state->cpend) {
- switch (*state->cp) {
- case '+':
- state->result = NewRENode(state, REOP_QUANT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.range.min = 1;
- state->result->u.range.max = -1;
- /* <PLUS>, <next> ... <ENDCHILD> */
- state->progLength += 4;
- goto quantifier;
- case '*':
- state->result = NewRENode(state, REOP_QUANT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.range.min = 0;
- state->result->u.range.max = -1;
- /* <STAR>, <next> ... <ENDCHILD> */
- state->progLength += 4;
- goto quantifier;
- case '?':
- state->result = NewRENode(state, REOP_QUANT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.range.min = 0;
- state->result->u.range.max = 1;
- /* <OPT>, <next> ... <ENDCHILD> */
- state->progLength += 4;
- goto quantifier;
- case '{': /* balance '}' */
- {
- intN err;
- intN min = 0;
- intN max = -1;
- jschar c;
- const jschar *errp = state->cp++;
-
- c = *state->cp;
- if (JS7_ISDEC(c)) {
- ++state->cp;
- min = getDecimalValue(c, state);
- c = *state->cp;
-
- if ((min + 1) >> 16) {
- err = JSMSG_MIN_TOO_BIG;
- goto quantError;
- }
- if (c == ',') {
- c = *++state->cp;
- if (JS7_ISDEC(c)) {
- ++state->cp;
- max = getDecimalValue(c, state);
- c = *state->cp;
- if ((max + 1) >> 16) {
- err = JSMSG_MAX_TOO_BIG;
- goto quantError;
- }
- if (min > max) {
- err = JSMSG_OUT_OF_ORDER;
- goto quantError;
- }
- }
- }
- else {
- max = min;
- }
- if (c == '}') {
- state->result = NewRENode(state, REOP_QUANT);
- if (!state->result)
- return JS_FALSE;
- state->result->u.range.min = min;
- state->result->u.range.max = max;
- /* QUANT, <min>, <max>, <next> ... <ENDCHILD> */
- state->progLength += 8;
- goto quantifier;
- }
- }
- state->cp = errp;
- return JS_TRUE;
-quantError:
- js_ReportCompileErrorNumber(state->context,
- state->tokenStream,
- NULL, JSREPORT_ERROR,
- err, errp);
- return JS_FALSE;
- }
- }
- }
- return JS_TRUE;
-
-quantifier:
- ++state->treeDepth;
- ++state->cp;
- state->result->kid = term;
- if ((state->cp < state->cpend) && (*state->cp == '?')) {
- ++state->cp;
- state->result->u.range.greedy = JS_FALSE;
- }
- else
- state->result->u.range.greedy = JS_TRUE;
- return JS_TRUE;
-}
-
-#define CHECK_OFFSET(diff) (JS_ASSERT(((diff) >= -32768) && ((diff) <= 32767)))
-#define SET_OFFSET(pc,off) ((pc)[0] = JUMP_OFFSET_HI(off), \
- (pc)[1] = JUMP_OFFSET_LO(off))
-#define GET_OFFSET(pc) ((int16)(((pc)[0] << 8) | (pc)[1]))
-#define OFFSET_LEN (2)
-#define GET_ARG(pc) GET_OFFSET(pc)
-#define SET_ARG(pc,arg) SET_OFFSET(pc,arg)
-#define ARG_LEN OFFSET_LEN
-
-/*
- * Recursively generate bytecode for the tree rooted at t. Iteratively.
- */
-
-typedef struct {
- RENode *nextAlt;
- jsbytecode *nextAltFixup, *nextTermFixup, *endTermFixup;
- RENode *continueNode;
- REOp continueOp;
-} EmitStateStackEntry;
-
-static jsbytecode *
-emitREBytecode(CompilerState *state, JSRegExp *re, intN treeDepth,
- jsbytecode *pc, RENode *t)
-{
- ptrdiff_t diff;
- RECharSet *charSet;
- EmitStateStackEntry *emitStateSP, *emitStateStack = NULL;
- REOp op;
-
- if (treeDepth) {
- emitStateStack =
- (EmitStateStackEntry *)JS_malloc(state->context,
- sizeof(EmitStateStackEntry)
- * treeDepth);
- if (!emitStateStack)
- return NULL;
- }
- emitStateSP = emitStateStack;
- op = t->op;
-
- while (JS_TRUE) {
- *pc++ = op;
- switch (op) {
- case REOP_EMPTY:
- --pc;
- break;
-
- case REOP_ALTPREREQ2:
- case REOP_ALTPREREQ:
- JS_ASSERT(emitStateSP);
- emitStateSP->endTermFixup = pc;
- pc += OFFSET_LEN;
- SET_ARG(pc, t->u.altprereq.ch1);
- pc += ARG_LEN;
- SET_ARG(pc, t->u.altprereq.ch2);
- pc += ARG_LEN;
-
- emitStateSP->nextAltFixup = pc; /* address of next alternate */
- pc += OFFSET_LEN;
-
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_JUMP;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
-
- case REOP_JUMP:
- emitStateSP->nextTermFixup = pc; /* address of following term */
- pc += OFFSET_LEN;
- diff = pc - emitStateSP->nextAltFixup;
- CHECK_OFFSET(diff);
- SET_OFFSET(emitStateSP->nextAltFixup, diff);
- emitStateSP->continueOp = REOP_ENDALT;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->u.kid2);
- op = t->op;
- continue;
-
- case REOP_ENDALT:
- diff = pc - emitStateSP->nextTermFixup;
- CHECK_OFFSET(diff);
- SET_OFFSET(emitStateSP->nextTermFixup, diff);
- if (t->op != REOP_ALT) {
- diff = pc - emitStateSP->endTermFixup;
- CHECK_OFFSET(diff);
- SET_OFFSET(emitStateSP->endTermFixup, diff);
- }
- break;
-
- case REOP_ALT:
- JS_ASSERT(emitStateSP);
- emitStateSP->nextAltFixup = pc; /* address of pointer to next alternate */
- pc += OFFSET_LEN;
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_JUMP;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
-
- case REOP_FLAT:
- /*
- * Consecutize FLAT's if possible.
- */
- if (t->kid) {
- while (t->next && (t->next->op == REOP_FLAT)
- && (((jschar*)(t->kid) + t->u.flat.length)
- == (jschar*)(t->next->kid))) {
- t->u.flat.length += t->next->u.flat.length;
- t->next = t->next->next;
- }
- }
- if (t->kid && (t->u.flat.length > 1)) {
- if (state->flags & JSREG_FOLD)
- pc[-1] = REOP_FLATi;
- else
- pc[-1] = REOP_FLAT;
- SET_ARG(pc, (jschar *)(t->kid) - state->cpbegin);
- pc += ARG_LEN;
- SET_ARG(pc, t->u.flat.length);
- pc += ARG_LEN;
- }
- else {
- if (t->u.flat.chr < 256) {
- if (state->flags & JSREG_FOLD)
- pc[-1] = REOP_FLAT1i;
- else
- pc[-1] = REOP_FLAT1;
- *pc++ = (jsbytecode)(t->u.flat.chr);
- }
- else {
- if (state->flags & JSREG_FOLD)
- pc[-1] = REOP_UCFLAT1i;
- else
- pc[-1] = REOP_UCFLAT1;
- SET_ARG(pc, t->u.flat.chr);
- pc += ARG_LEN;
- }
- }
- break;
-
- case REOP_LPAREN:
- JS_ASSERT(emitStateSP);
- SET_ARG(pc, t->u.parenIndex);
- pc += ARG_LEN;
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_RPAREN;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
- case REOP_RPAREN:
- SET_ARG(pc, t->u.parenIndex);
- pc += ARG_LEN;
- break;
-
- case REOP_BACKREF:
- SET_ARG(pc, t->u.parenIndex);
- pc += ARG_LEN;
- break;
- case REOP_ASSERT:
- JS_ASSERT(emitStateSP);
- emitStateSP->nextTermFixup = pc;
- pc += OFFSET_LEN;
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_ASSERTTEST;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
- case REOP_ASSERTTEST:
- case REOP_ASSERTNOTTEST:
- diff = pc - emitStateSP->nextTermFixup;
- CHECK_OFFSET(diff);
- SET_OFFSET(emitStateSP->nextTermFixup, diff);
- break;
- case REOP_ASSERT_NOT:
- JS_ASSERT(emitStateSP);
- emitStateSP->nextTermFixup = pc;
- pc += OFFSET_LEN;
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_ASSERTNOTTEST;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
- case REOP_QUANT:
- JS_ASSERT(emitStateSP);
- if ((t->u.range.min == 0) && (t->u.range.max == (uint16)(-1)))
- pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR;
- else
- if ((t->u.range.min == 0) && (t->u.range.max == 1))
- pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT;
- else
- if ((t->u.range.min == 1) && (t->u.range.max == (uint16)(-1)))
- pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;
- else {
- if (!t->u.range.greedy) pc[-1] = REOP_MINIMALQUANT;
- SET_ARG(pc, t->u.range.min);
- pc += ARG_LEN;
- SET_ARG(pc, t->u.range.max);
- pc += ARG_LEN;
- }
- emitStateSP->nextTermFixup = pc;
- pc += OFFSET_LEN;
- emitStateSP->continueNode = t;
- emitStateSP->continueOp = REOP_ENDCHILD;
- ++emitStateSP;
- JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);
- t = (RENode *)(t->kid);
- op = t->op;
- continue;
- case REOP_ENDCHILD:
- diff = pc - emitStateSP->nextTermFixup;
- CHECK_OFFSET(diff);
- SET_OFFSET(emitStateSP->nextTermFixup, diff);
- break;
- case REOP_CLASS:
- if (!t->u.ucclass.sense)
- pc[-1] = REOP_NCLASS;
- SET_ARG(pc, t->u.ucclass.index);
- pc += ARG_LEN;
- charSet = &re->classList[t->u.ucclass.index];
- charSet->converted = JS_FALSE;
- charSet->length = t->u.ucclass.bmsize;
- charSet->u.src.startIndex = t->u.ucclass.startIndex;
- charSet->u.src.length = t->u.ucclass.kidlen;
- charSet->sense = t->u.ucclass.sense;
- break;
- default:
- break;
- }
- t = t->next;
- if (t == NULL) {
- if (emitStateSP == emitStateStack)
- break;
- --emitStateSP;
- t = emitStateSP->continueNode;
- op = emitStateSP->continueOp;
- }
- else
- op = t->op;
- }
- if (emitStateStack)
- JS_free(state->context, emitStateStack);
- return pc;
-}
-
-
-JSRegExp *
-js_NewRegExp(JSContext *cx, JSTokenStream *ts,
- JSString *str, uintN flags, JSBool flat)
-{
- JSRegExp *re;
- void *mark;
- CompilerState state;
- size_t resize;
- jsbytecode *endPC;
- uint32 i;
- size_t len;
-
- re = NULL;
- mark = JS_ARENA_MARK(&cx->tempPool);
-
- state.context = cx;
- state.tokenStream = ts;
- state.cpbegin = state.cp = JSSTRING_CHARS(str);
- state.cpend = state.cp + JSSTRING_LENGTH(str);
- state.flags = flags;
- state.parenCount = 0;
- state.classCount = 0;
- state.progLength = 0;
- state.treeDepth = 0;
- for (i = 0; i < CLASS_CACHE_SIZE; i++)
- state.classCache[i].start = NULL;
-
- len = JSSTRING_LENGTH(str);
-
- if (len != 0 && flat) {
- state.result = NewRENode(&state, REOP_FLAT);
- state.result->u.flat.chr = *state.cpbegin;
- state.result->u.flat.length = JSSTRING_LENGTH(str);
- state.result->kid = (void *)(state.cpbegin);
- state.progLength += 5;
- }
- else {
- if (!parseRegExp(&state))
- goto out;
- }
- resize = sizeof *re + state.progLength + 1;
- re = (JSRegExp *) JS_malloc(cx, JS_ROUNDUP(resize, sizeof(jsword)));
- if (!re)
- goto out;
-
- re->classCount = state.classCount;
- if (state.classCount) {
- re->classList = (RECharSet *)JS_malloc(cx, sizeof(RECharSet)
- * state.classCount);
- if (!re->classList)
- goto out;
- }
- else
- re->classList = NULL;
- endPC = emitREBytecode(&state, re, state.treeDepth, re->program, state.result);
- if (!endPC) {
- re = NULL;
- goto out;
- }
- *endPC++ = REOP_END;
- JS_ASSERT(endPC <= (re->program + (state.progLength + 1)));
-
- re->nrefs = 1;
- re->parenCount = state.parenCount;
- re->flags = flags;
- re->source = str;
-
-out:
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return re;
-}
-
-JSRegExp *
-js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
- JSString *str, JSString *opt, JSBool flat)
-{
- uintN flags;
- jschar *s;
- size_t i, n;
- char charBuf[2];
-
- flags = 0;
- if (opt) {
- s = JSSTRING_CHARS(opt);
- for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) {
- switch (s[i]) {
- case 'g':
- flags |= JSREG_GLOB;
- break;
- case 'i':
- flags |= JSREG_FOLD;
- break;
- case 'm':
- flags |= JSREG_MULTILINE;
- break;
- default:
- charBuf[0] = (char)s[i];
- charBuf[1] = '\0';
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_FLAG, charBuf);
- return NULL;
- }
- }
- }
- return js_NewRegExp(cx, ts, str, flags, flat);
-}
-
-
-#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
-#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
-
-/*
- * Save the current state of the match - the position in the input
- * text as well as the position in the bytecode. The state of any
- * parent expressions is also saved (preceding state).
- * Contents of parenCount parentheses from parenIndex are also saved.
- */
-static REBackTrackData *
-pushBackTrackState(REGlobalData *gData, REOp op,
- jsbytecode *target, REMatchState *x, const jschar *cp,
- intN parenIndex, intN parenCount)
-{
- intN i;
- REBackTrackData *result
- = (REBackTrackData *)((char *)(gData->backTrackSP) + gData->cursz);
-
- size_t sz = sizeof(REBackTrackData)
- + gData->stateStackTop * sizeof(REProgState)
- + parenCount * sizeof(RECapture);
-
-
- if (((char *)result + sz)
- > (char *)gData->backTrackStack + gData->maxBackTrack) {
- ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack;
- gData->backTrackStack
- = (REBackTrackData *)JS_ArenaGrow(&gData->pool,
- gData->backTrackStack,
- gData->maxBackTrack,
- gData->maxBackTrack);
- gData->maxBackTrack <<= 1;
- if (!gData->backTrackStack)
- return NULL;
- result = (REBackTrackData *)((char *)gData->backTrackStack + offset);
- }
- gData->backTrackSP = result;
- result->sz = gData->cursz;
- gData->cursz = sz;
-
- result->backtrack_op = op;
- result->backtrack_pc = target;
- result->cp = cp;
- result->parenCount = parenCount;
-
- result->precedingStateTop = gData->stateStackTop;
- JS_ASSERT(gData->stateStackTop);
- memcpy(result + 1, gData->stateStack,
- sizeof(REProgState) * result->precedingStateTop);
-
- if (parenCount != -1) {
- result->parenIndex = parenIndex;
- memcpy((char *)(result + 1)
- + sizeof(REProgState) * result->precedingStateTop,
- &x->parens[parenIndex],
- sizeof(RECapture) * parenCount);
- for (i = 0; i < parenCount; i++)
- x->parens[parenIndex + i].index = -1;
- }
-
- return result;
-}
-
-
-/*
- * Consecutive literal characters.
- */
-#if 0
-static REMatchState *
-flatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
- intN length)
-{
- intN i;
- if ((x->cp + length) > gData->cpend)
- return NULL;
- for (i = 0; i < length; i++) {
- if (matchChars[i] != x->cp[i])
- return NULL;
- }
- x->cp += length;
- return x;
-}
-#endif
-
-static REMatchState *
-flatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
- intN length)
-{
- intN i;
- if ((x->cp + length) > gData->cpend)
- return NULL;
- for (i = 0; i < length; i++) {
- if (upcase(matchChars[i]) != upcase(x->cp[i]))
- return NULL;
- }
- x->cp += length;
- return x;
-}
-
-/*
- * 1. Evaluate DecimalEscape to obtain an EscapeValue E.
- * 2. If E is not a character then go to step 6.
- * 3. Let ch be E's character.
- * 4. Let A be a one-element RECharSet containing the character ch.
- * 5. Call CharacterSetMatcher(A, false) and return its Matcher result.
- * 6. E must be an integer. Let n be that integer.
- * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.
- * 8. Return an internal Matcher closure that takes two arguments, a State x
- * and a Continuation c, and performs the following:
- * 1. Let cap be x's captures internal array.
- * 2. Let s be cap[n].
- * 3. If s is undefined, then call c(x) and return its result.
- * 4. Let e be x's endIndex.
- * 5. Let len be s's length.
- * 6. Let f be e+len.
- * 7. If f>InputLength, return failure.
- * 8. If there exists an integer i between 0 (inclusive) and len (exclusive)
- * such that Canonicalize(s[i]) is not the same character as
- * Canonicalize(Input [e+i]), then return failure.
- * 9. Let y be the State (f, cap).
- * 10. Call c(y) and return its result.
- */
-static REMatchState *
-backrefMatcher(REGlobalData *gData, REMatchState *x, uintN parenIndex)
-{
- uintN len;
- uintN i;
- const jschar *parenContent;
- RECapture *s = &x->parens[parenIndex];
- if (s->index == -1)
- return x;
-
- len = s->length;
- if ((x->cp + len) > gData->cpend)
- return NULL;
-
- parenContent = &gData->cpbegin[s->index];
- if (gData->regexp->flags & JSREG_FOLD) {
- for (i = 0; i < len; i++) {
- if (upcase(parenContent[i]) != upcase(x->cp[i]))
- return NULL;
- }
- }
- else {
- for (i = 0; i < len; i++) {
- if (parenContent[i] != x->cp[i])
- return NULL;
- }
- }
- x->cp += len;
- return x;
-}
-
-
-/* Add a single character to the RECharSet */
-static void
-addCharacterToCharSet(RECharSet *cs, jschar c)
-{
- uintN byteIndex = (uintN)(c / 8);
- JS_ASSERT(c <= cs->length);
- cs->u.bits[byteIndex] |= 1 << (c & 0x7);
-}
-
-
-/* Add a character range, c1 to c2 (inclusive) to the RECharSet */
-static void
-addCharacterRangeToCharSet(RECharSet *cs, jschar c1, jschar c2)
-{
- uintN i;
-
- uintN byteIndex1 = (uintN)(c1 / 8);
- uintN byteIndex2 = (uintN)(c2 / 8);
-
- JS_ASSERT((c2 <= cs->length) && (c1 <= c2));
-
- c1 &= 0x7;
- c2 &= 0x7;
-
- if (byteIndex1 == byteIndex2)
- cs->u.bits[byteIndex1] |= ((uint8)(0xFF) >> (7 - (c2 - c1))) << c1;
- else {
- cs->u.bits[byteIndex1] |= 0xFF << c1;
- for (i = byteIndex1 + 1; i < byteIndex2; i++)
- cs->u.bits[i] = 0xFF;
- cs->u.bits[byteIndex2] |= (uint8)(0xFF) >> (7 - c2);
- }
-}
-
-/* Compile the source of the class into a RECharSet */
-static JSBool
-processCharSet(REGlobalData *gData, RECharSet *charSet)
-{
- const jschar *src = JSSTRING_CHARS(gData->regexp->source)
- + charSet->u.src.startIndex;
- const jschar *end = src + charSet->u.src.length;
-
- jschar rangeStart, thisCh;
- uintN byteLength;
- jschar c;
- uintN n;
- intN nDigits;
- intN i;
- JSBool inRange = JS_FALSE;
-
- JS_ASSERT(!charSet->converted);
- charSet->converted = JS_TRUE;
-
- byteLength = (charSet->length / 8) + 1;
- charSet->u.bits = (uint8 *)JS_malloc(gData->cx, byteLength);
- if (!charSet->u.bits)
- return JS_FALSE;
- memset(charSet->u.bits, 0, byteLength);
-
- if (src == end)
- return JS_TRUE;
-
- if (*src == '^') {
- JS_ASSERT(charSet->sense == JS_FALSE);
- ++src;
- }
- else
- JS_ASSERT(charSet->sense == JS_TRUE);
-
-
- while (src != end) {
- switch (*src) {
- case '\\':
- ++src;
- c = *src++;
- switch (c) {
- case 'b':
- thisCh = 0x8;
- break;
- case 'f':
- thisCh = 0xC;
- break;
- case 'n':
- thisCh = 0xA;
- break;
- case 'r':
- thisCh = 0xD;
- break;
- case 't':
- thisCh = 0x9;
- break;
- case 'v':
- thisCh = 0xB;
- break;
- case 'c':
- if (((src + 1) < end) && JS_ISWORD(src[1]))
- thisCh = (jschar)(*src++ & 0x1F);
- else {
- --src;
- thisCh = '\\';
- }
- break;
- case 'x':
- nDigits = 2;
- goto lexHex;
- case 'u':
- nDigits = 4;
-lexHex:
- n = 0;
- for (i = 0; (i < nDigits) && (src < end); i++) {
- uintN digit;
- c = *src++;
- if (!isASCIIHexDigit(c, &digit)) {
- /*
- * Back off to accepting the original '\'
- * as a literal
- */
- src -= (i + 1);
- n = '\\';
- break;
- }
- n = (n << 4) | digit;
- }
- thisCh = (jschar)(n);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /*
- * This is a non-ECMA extension - decimal escapes (in this
- * case, octal!) are supposed to be an error inside class
- * ranges, but supported here for backwards compatibility.
- *
- */
- n = JS7_UNDEC(c);
- c = *src;
- if ('0' <= c && c <= '7') {
- src++;
- n = 8 * n + JS7_UNDEC(c);
- c = *src;
- if ('0' <= c && c <= '7') {
- src++;
- i = 8 * n + JS7_UNDEC(c);
- if (i <= 0377)
- n = i;
- else
- src--;
- }
- }
- thisCh = (jschar)(n);
- break;
-
- case 'd':
- addCharacterRangeToCharSet(charSet, '0', '9');
- continue; /* don't need range processing */
- case 'D':
- addCharacterRangeToCharSet(charSet, 0, '0' - 1);
- addCharacterRangeToCharSet(charSet, (jschar)('9' + 1),
- (jschar)(charSet->length));
- continue;
- case 's':
- for (i = (intN)(charSet->length); i >= 0; i--)
- if (JS_ISSPACE(i))
- addCharacterToCharSet(charSet, (jschar)(i));
- continue;
- case 'S':
- for (i = (intN)(charSet->length); i >= 0; i--)
- if (!JS_ISSPACE(i))
- addCharacterToCharSet(charSet, (jschar)(i));
- continue;
- case 'w':
- for (i = (intN)(charSet->length); i >= 0; i--)
- if (JS_ISWORD(i))
- addCharacterToCharSet(charSet, (jschar)(i));
- continue;
- case 'W':
- for (i = (intN)(charSet->length); i >= 0; i--)
- if (!JS_ISWORD(i))
- addCharacterToCharSet(charSet, (jschar)(i));
- continue;
- default:
- thisCh = c;
- break;
-
- }
- break;
-
- default:
- thisCh = *src++;
- break;
-
- }
- if (inRange) {
- if (gData->regexp->flags & JSREG_FOLD) {
- addCharacterRangeToCharSet(charSet, upcase(rangeStart),
- upcase(thisCh));
- addCharacterRangeToCharSet(charSet, downcase(rangeStart),
- downcase(thisCh));
- } else {
- addCharacterRangeToCharSet(charSet, rangeStart, thisCh);
- }
- inRange = JS_FALSE;
- }
- else {
- if (gData->regexp->flags & JSREG_FOLD) {
- addCharacterToCharSet(charSet, upcase(thisCh));
- addCharacterToCharSet(charSet, downcase(thisCh));
- } else {
- addCharacterToCharSet(charSet, thisCh);
- }
- if (src < (end - 1)) {
- if (*src == '-') {
- ++src;
- inRange = JS_TRUE;
- rangeStart = thisCh;
- }
- }
- }
- }
- return JS_TRUE;
-}
-
-void
-js_DestroyRegExp(JSContext *cx, JSRegExp *re)
-{
- uintN i;
- if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) {
- if (re->classList) {
- for (i = 0; i < re->classCount; i++) {
- if (re->classList[i].converted)
- JS_free(cx, re->classList[i].u.bits);
- re->classList[i].u.bits = NULL;
- }
- JS_free(cx, re->classList);
- }
- JS_free(cx, re);
- }
-}
-
-static JSBool
-reallocStateStack(REGlobalData *gData)
-{
- size_t sz = sizeof(REProgState) * gData->maxStateStack;
- gData->maxStateStack <<= 1;
- gData->stateStack
- = (REProgState *)JS_ArenaGrow(&gData->pool, gData->stateStack, sz, sz);
- if (!gData->stateStack) {
- gData->ok = JS_FALSE;
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-/*
-* Apply the current op against the given input to see if
-* it's going to match or fail. Return false if we don't
-* get a match, true if we do and update the state of the
-* input and pc if the update flag is true.
-*/
-static REMatchState *simpleMatch(REGlobalData *gData, REMatchState *x,
- REOp op, jsbytecode **startpc, JSBool update)
-{
- REMatchState *result = NULL;
- jschar matchCh;
- intN parenIndex;
- intN offset, length, index;
- jsbytecode *pc = *startpc; /* pc has already been incremented past op */
- jschar *source;
- const jschar *startcp = x->cp;
- jschar ch;
- RECharSet *charSet;
-
-
- switch (op) {
- default:
- JS_ASSERT(JS_FALSE);
- case REOP_BOL:
- if (x->cp != gData->cpbegin) {
- if (gData->cx->regExpStatics.multiline ||
- (gData->regexp->flags & JSREG_MULTILINE)) {
- if (!RE_IS_LINE_TERM(x->cp[-1]))
- break;
- }
- else
- break;
- }
- result = x;
- break;
- case REOP_EOL:
- if (x->cp != gData->cpend) {
- if (gData->cx->regExpStatics.multiline ||
- (gData->regexp->flags & JSREG_MULTILINE)) {
- if (!RE_IS_LINE_TERM(*x->cp))
- break;
- }
- else
- break;
- }
- result = x;
- break;
- case REOP_WBDRY:
- if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1]))
- ^ !((x->cp != gData->cpend) && JS_ISWORD(*x->cp)))
- result = x;
- break;
- case REOP_WNONBDRY:
- if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1]))
- ^ ((x->cp != gData->cpend) && JS_ISWORD(*x->cp)))
- result = x;
- break;
- case REOP_DOT:
- if (x->cp != gData->cpend && !RE_IS_LINE_TERM(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_DIGIT:
- if (x->cp != gData->cpend && JS_ISDIGIT(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_NONDIGIT:
- if (x->cp != gData->cpend && !JS_ISDIGIT(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_ALNUM:
- if (x->cp != gData->cpend && JS_ISWORD(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_NONALNUM:
- if (x->cp != gData->cpend && !JS_ISWORD(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_SPACE:
- if (x->cp != gData->cpend && JS_ISSPACE(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_NONSPACE:
- if (x->cp != gData->cpend && !JS_ISSPACE(*x->cp)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_BACKREF:
- parenIndex = GET_ARG(pc);
- pc += ARG_LEN;
- result = backrefMatcher(gData, x, parenIndex);
- break;
- case REOP_FLAT:
- offset = GET_ARG(pc);
- pc += ARG_LEN;
- length = GET_ARG(pc);
- pc += ARG_LEN;
- source = JSSTRING_CHARS(gData->regexp->source) + offset;
- if ((x->cp + length) <= gData->cpend) {
- for (index = 0; index < length; index++) {
- if (source[index] != x->cp[index])
- return NULL;
- }
- x->cp += length;
- result = x;
- }
- break;
- case REOP_FLAT1:
- matchCh = *pc++;
- if ((x->cp != gData->cpend) && (*x->cp == matchCh)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_FLATi:
- offset = GET_ARG(pc);
- pc += ARG_LEN;
- length = GET_ARG(pc);
- pc += ARG_LEN;
- source = JSSTRING_CHARS(gData->regexp->source);
- result = flatNIMatcher(gData, x, source + offset, length);
- break;
- case REOP_FLAT1i:
- matchCh = *pc++;
- if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_UCFLAT1:
- matchCh = GET_ARG(pc);
- pc += ARG_LEN;
- if ((x->cp != gData->cpend) && (*x->cp == matchCh)) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_UCFLAT1i:
- matchCh = GET_ARG(pc);
- pc += ARG_LEN;
- if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) {
- result = x;
- result->cp++;
- }
- break;
- case REOP_CLASS:
- index = GET_ARG(pc);
- pc += ARG_LEN;
- if (x->cp != gData->cpend) {
- charSet = &gData->regexp->classList[index];
- JS_ASSERT(charSet->converted);
- ch = *x->cp;
- index = ch / 8;
- if ((charSet->length != 0) &&
- ( (ch <= charSet->length)
- && ((charSet->u.bits[index] & (1 << (ch & 0x7))) != 0) )) {
- result = x;
- result->cp++;
- }
- }
- break;
- case REOP_NCLASS:
- index = GET_ARG(pc);
- pc += ARG_LEN;
- if (x->cp != gData->cpend) {
- charSet = &gData->regexp->classList[index];
- JS_ASSERT(charSet->converted);
- ch = *x->cp;
- index = ch / 8;
- if ((charSet->length == 0) ||
- ( (ch > charSet->length)
- || ((charSet->u.bits[index] & (1 << (ch & 0x7))) == 0) )) {
- result = x;
- result->cp++;
- }
- }
- break;
- }
- if (result != NULL) {
- if (update)
- *startpc = pc;
- else
- x->cp = startcp;
- return result;
- }
- x->cp = startcp;
- return NULL;
-}
-
-static REMatchState *
-executeREBytecode(REGlobalData *gData, REMatchState *x)
-{
- REMatchState *result;
- REBackTrackData *backTrackData;
- intN offset;
- jsbytecode *nextpc;
- REOp nextop;
- RECapture *cap;
- REProgState *curState;
- const jschar *startcp;
- uintN parenIndex, k;
- uintN parenSoFar = 0;
-
- jschar matchCh1, matchCh2;
- RECharSet *charSet;
-
- JSBool anchor;
- jsbytecode *pc = gData->regexp->program;
- REOp op = (REOp)(*pc++);
-
- /*
- * If the first node is a simple match, step the index into
- * the string until that match is made, or fail if it can't be
- * found at all.
- */
- if (REOP_IS_SIMPLE(op)) {
- anchor = JS_FALSE;
- while (x->cp <= gData->cpend) {
- nextpc = pc; /* reset back to start each time */
- result = simpleMatch(gData, x, op, &nextpc, JS_TRUE);
- if (result) {
- anchor = JS_TRUE;
- x = result;
- pc = nextpc; /* accept skip to next opcode */
- op = (REOp)(*pc++);
- break;
- }
- else {
- gData->skipped++;
- x->cp++;
- }
- }
- if (!anchor)
- return NULL;
- }
-
- while (JS_TRUE) {
- if (REOP_IS_SIMPLE(op))
- result = simpleMatch(gData, x, op, &pc, JS_TRUE);
- else {
- curState = &gData->stateStack[gData->stateStackTop];
- switch (op) {
- case REOP_EMPTY:
- result = x;
- break;
-
- case REOP_ALTPREREQ2:
- nextpc = pc + GET_OFFSET(pc); /* start of next op */
- pc += ARG_LEN;
- matchCh2 = GET_ARG(pc);
- pc += ARG_LEN;
- k = GET_ARG(pc);
- pc += ARG_LEN;
-
- if (x->cp != gData->cpend) {
- if (*x->cp == matchCh2)
- goto doAlt;
-
- charSet = &gData->regexp->classList[k];
- if (!charSet->converted)
- if (!processCharSet(gData, charSet))
- return NULL;
- matchCh1 = *x->cp;
- k = matchCh1 / 8;
- if ((charSet->length == 0 ||
- matchCh1 > charSet->length ||
- (charSet->u.bits[k] & (1 << (matchCh1 & 0x7))) == 0)
- ^ charSet->sense) {
- goto doAlt;
- }
- }
- result = NULL;
- break;
-
- case REOP_ALTPREREQ:
- nextpc = pc + GET_OFFSET(pc); /* start of next op */
- pc += ARG_LEN;
- matchCh1 = GET_ARG(pc);
- pc += ARG_LEN;
- matchCh2 = GET_ARG(pc);
- pc += ARG_LEN;
- if ((x->cp == gData->cpend)
- || ((*x->cp != matchCh1) && (*x->cp != matchCh2))) {
- result = NULL;
- break;
- }
- /* else false thru... */
-
- case REOP_ALT:
-doAlt:
- nextpc = pc + GET_OFFSET(pc); /* start of next alternate */
- pc += ARG_LEN; /* start of this alternate */
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- op = (REOp)(*pc++);
- startcp = x->cp;
- if (REOP_IS_SIMPLE(op)) {
- if (!simpleMatch(gData, x, op, &pc, JS_TRUE)) {
- op = (REOp)(*nextpc++);
- pc = nextpc;
- continue;
- }
- else { /* accept the match and move on */
- result = x;
- op = (REOp)(*pc++);
- }
- }
- nextop = (REOp)(*nextpc++);
- if (!pushBackTrackState(gData, nextop, nextpc, x, startcp, 0, 0))
- return NULL;
- continue;
-
- /*
- * Occurs at (succesful) end of REOP_ALT,
- */
- case REOP_JUMP:
- --gData->stateStackTop;
- offset = GET_OFFSET(pc);
- pc += offset;
- op = (REOp)(*pc++);
- continue;
-
- /*
- * Occurs at last (succesful) end of REOP_ALT,
- */
- case REOP_ENDALT:
- --gData->stateStackTop;
- op = (REOp)(*pc++);
- continue;
-
- case REOP_LPAREN:
- parenIndex = GET_ARG(pc);
- if ((parenIndex + 1) > parenSoFar)
- parenSoFar = parenIndex + 1;
- pc += ARG_LEN;
- x->parens[parenIndex].index = x->cp - gData->cpbegin;
- x->parens[parenIndex].length = 0;
- op = (REOp)(*pc++);
- continue;
- case REOP_RPAREN:
- parenIndex = GET_ARG(pc);
- pc += ARG_LEN;
- cap = &x->parens[parenIndex];
- cap->length = x->cp - (gData->cpbegin + cap->index);
- op = (REOp)(*pc++);
- continue;
-
- case REOP_ASSERT:
- nextpc = pc + GET_OFFSET(pc); /* start of term after ASSERT */
- pc += ARG_LEN; /* start of ASSERT child */
- op = (REOp)(*pc++);
- if (REOP_IS_SIMPLE(op)
- && !simpleMatch(gData, x, op, &pc, JS_FALSE)) {
- result = NULL;
- break;
- }
- else {
- curState->u.assertion.top
- = (char *)gData->backTrackSP
- - (char *)gData->backTrackStack;
- curState->u.assertion.sz = gData->cursz;
- curState->index = x->cp - gData->cpbegin;
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (!pushBackTrackState(gData, REOP_ASSERTTEST,
- nextpc, x, x->cp, 0, 0))
- return NULL;
- }
- continue;
- case REOP_ASSERT_NOT:
- nextpc = pc + GET_OFFSET(pc);
- pc += ARG_LEN;
- op = (REOp)(*pc++);
- if (REOP_IS_SIMPLE(op)
- /* Note - fail to fail! */
- && simpleMatch(gData, x, op, &pc, JS_FALSE)) {
- result = NULL;
- break;
- }
- else {
- curState->u.assertion.top
- = (char *)gData->backTrackSP
- - (char *)gData->backTrackStack;
- curState->u.assertion.sz = gData->cursz;
- curState->index = x->cp - gData->cpbegin;
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (!pushBackTrackState(gData, REOP_ASSERTNOTTEST,
- nextpc, x, x->cp, 0, 0))
- return NULL;
- }
- continue;
- case REOP_ASSERTTEST:
- --gData->stateStackTop;
- --curState;
- x->cp = gData->cpbegin + curState->index;
- gData->backTrackSP
- = (REBackTrackData *)((char *)gData->backTrackStack
- + curState->u.assertion.top);
- gData->cursz = curState->u.assertion.sz;
- if (result != NULL)
- result = x;
- break;
- case REOP_ASSERTNOTTEST:
- --gData->stateStackTop;
- --curState;
- x->cp = gData->cpbegin + curState->index;
- gData->backTrackSP
- = (REBackTrackData *)((char *)gData->backTrackStack
- + curState->u.assertion.top);
- gData->cursz = curState->u.assertion.sz;
- if (result == NULL)
- result = x;
- else
- result = NULL;
- break;
-
- case REOP_END:
- if (x != NULL)
- return x;
- break;
-
- case REOP_STAR:
- curState->u.quantifier.min = 0;
- curState->u.quantifier.max = -1;
- goto quantcommon;
- case REOP_PLUS:
- curState->u.quantifier.min = 1;
- curState->u.quantifier.max = -1;
- goto quantcommon;
- case REOP_OPT:
- curState->u.quantifier.min = 0;
- curState->u.quantifier.max = 1;
- goto quantcommon;
- case REOP_QUANT:
- curState->u.quantifier.min = GET_ARG(pc);
- pc += ARG_LEN;
- curState->u.quantifier.max = GET_ARG(pc);
- pc += ARG_LEN;
-quantcommon:
- if (curState->u.quantifier.max == 0) {
- pc = pc + GET_OFFSET(pc);
- op = (REOp)(*pc++);
- result = x;
- continue;
- }
- /* Step over <next> */
- nextpc = pc + ARG_LEN;
- op = (REOp)(*nextpc++);
- startcp = x->cp;
- if (REOP_IS_SIMPLE(op)) {
- if (!simpleMatch(gData, x, op, &nextpc, JS_TRUE)) {
- if (curState->u.quantifier.min == 0)
- result = x;
- else
- result = NULL;
- pc = pc + GET_OFFSET(pc);
- break;
- }
- else {
- op = (REOp)(*nextpc++);
- result = x;
- }
- }
- curState->index = startcp - gData->cpbegin;
- curState->continue_op = REOP_REPEAT;
- curState->continue_pc = pc;
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (curState->u.quantifier.min == 0)
- if (!pushBackTrackState(gData, REOP_REPEAT,
- pc, x, startcp, 0, 0))
- return NULL;
- pc = nextpc;
- continue;
-
- case REOP_ENDCHILD: /* marks the end of a quantifier child */
- pc = curState[-1].continue_pc;
- op = curState[-1].continue_op;
- continue;
-
- case REOP_REPEAT:
- --curState;
-repeatAgain:
- --gData->stateStackTop;
- if (result == NULL) {
- /*
- * There's been a failure, see if we have enough children.
- */
- if (curState->u.quantifier.min == 0) {
- result = x;
- goto repeatDone;
- }
- break;
- }
- else {
- if ((curState->u.quantifier.min == 0)
- && (x->cp == gData->cpbegin + curState->index)) {
- /* matched an empty string, that'll get us nowhere */
- result = NULL;
- break;
- }
- if (curState->u.quantifier.min != 0)
- curState->u.quantifier.min--;
- if (curState->u.quantifier.max != (uint16)(-1))
- curState->u.quantifier.max--;
- if (curState->u.quantifier.max == 0) {
- result = x;
- goto repeatDone;
- }
- nextpc = pc + ARG_LEN;
- nextop = (REOp)(*nextpc);
- startcp = x->cp;
- if (REOP_IS_SIMPLE(nextop)) {
- nextpc++;
- if (!simpleMatch(gData, x, nextop, &nextpc, JS_TRUE)) {
- if (curState->u.quantifier.min == 0) {
- result = x;
- goto repeatDone;
- }
- else
- result = NULL;
- break;
- }
- result = x;
- }
- curState->index = startcp - gData->cpbegin;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (curState->u.quantifier.min == 0)
- if (!pushBackTrackState(gData, REOP_REPEAT,
- pc, x, startcp,
- curState->parenSoFar,
- parenSoFar
- - curState->parenSoFar))
- return NULL;
- if (*nextpc == REOP_ENDCHILD)
- goto repeatAgain;
- pc = nextpc;
- op = (REOp)(*pc++);
- parenSoFar = curState->parenSoFar;
- }
- continue;
-repeatDone:
- pc = pc + GET_OFFSET(pc);
- break;
-
-
- case REOP_MINIMALSTAR:
- curState->u.quantifier.min = 0;
- curState->u.quantifier.max = -1;
- goto minimalquantcommon;
- case REOP_MINIMALPLUS:
- curState->u.quantifier.min = 1;
- curState->u.quantifier.max = -1;
- goto minimalquantcommon;
- case REOP_MINIMALOPT:
- curState->u.quantifier.min = 0;
- curState->u.quantifier.max = 1;
- goto minimalquantcommon;
- case REOP_MINIMALQUANT:
- curState->u.quantifier.min = GET_ARG(pc);
- pc += ARG_LEN;
- curState->u.quantifier.max = GET_ARG(pc);
- pc += ARG_LEN;
-minimalquantcommon:
- curState->index = x->cp - gData->cpbegin;
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (curState->u.quantifier.min != 0) {
- curState->continue_op = REOP_MINIMALREPEAT;
- curState->continue_pc = pc;
- /* step over <next> */
- pc += ARG_LEN;
- op = (REOp)(*pc++);
- }
- else {
- if (!pushBackTrackState(gData, REOP_MINIMALREPEAT,
- pc, x, x->cp, 0, 0))
- return NULL;
- --gData->stateStackTop;
- pc = pc + GET_OFFSET(pc);
- op = (REOp)(*pc++);
- }
- continue;
-
- case REOP_MINIMALREPEAT:
- --gData->stateStackTop;
- --curState;
-
- if (result == NULL) {
- /*
- * Non-greedy failure - try to consume another child.
- */
- if ((curState->u.quantifier.max == (uint16)(-1))
- || (curState->u.quantifier.max > 0)) {
- curState->index = x->cp - gData->cpbegin;
- curState->continue_op = REOP_MINIMALREPEAT;
- curState->continue_pc = pc;
- pc += ARG_LEN;
- for (k = curState->parenSoFar; k < parenSoFar; k++)
- x->parens[k].index = -1;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- op = (REOp)(*pc++);
- continue;
- }
- else {
- /* Don't need to adjust pc since we're going to pop. */
- break;
- }
- }
- else {
- if ((curState->u.quantifier.min == 0)
- && (x->cp == gData->cpbegin + curState->index)) {
- /* Matched an empty string, that'll get us nowhere. */
- result = NULL;
- break;
- }
- if (curState->u.quantifier.min != 0)
- curState->u.quantifier.min--;
- if (curState->u.quantifier.max != (uint16)(-1))
- curState->u.quantifier.max--;
- if (curState->u.quantifier.min != 0) {
- curState->continue_op = REOP_MINIMALREPEAT;
- curState->continue_pc = pc;
- pc += ARG_LEN;
- for (k = curState->parenSoFar; k < parenSoFar; k++)
- x->parens[k].index = -1;
- curState->index = x->cp - gData->cpbegin;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- op = (REOp)(*pc++);
- continue;
- }
- else {
- curState->index = x->cp - gData->cpbegin;
- curState->parenSoFar = parenSoFar;
- ++gData->stateStackTop;
- if (gData->stateStackTop == gData->maxStateStack)
- if (!reallocStateStack(gData))
- return NULL;
- if (!pushBackTrackState(gData, REOP_MINIMALREPEAT,
- pc, x, x->cp,
- curState->parenSoFar,
- parenSoFar
- - curState->parenSoFar))
- return NULL;
- --gData->stateStackTop;
- pc = pc + GET_OFFSET(pc);
- op = (REOp)(*pc++);
- continue;
- }
- }
-
- default:
- JS_ASSERT(JS_FALSE);
- result = NULL;
- }
- }
- /*
- * If the match failed and there's a backtrack option, take it.
- * Otherwise this is a complete and utter failure.
- */
- if (result == NULL) {
- if (gData->cursz > 0) {
- backTrackData = gData->backTrackSP;
- gData->cursz = backTrackData->sz;
- gData->backTrackSP
- = (REBackTrackData *)((char *)backTrackData
- - backTrackData->sz);
- x->cp = backTrackData->cp;
- pc = backTrackData->backtrack_pc;
- op = backTrackData->backtrack_op;
- gData->stateStackTop = backTrackData->precedingStateTop;
- JS_ASSERT(gData->stateStackTop);
-
- memcpy(gData->stateStack, backTrackData + 1,
- sizeof(REProgState) * backTrackData->precedingStateTop);
- curState = &gData->stateStack[gData->stateStackTop - 1];
-
- if (backTrackData->parenCount) {
- memcpy(&x->parens[backTrackData->parenIndex],
- (char *)(backTrackData + 1) + sizeof(REProgState) * backTrackData->precedingStateTop,
- sizeof(RECapture) * backTrackData->parenCount);
- parenSoFar = backTrackData->parenIndex + backTrackData->parenCount;
- }
- else {
- for (k = curState->parenSoFar; k < parenSoFar; k++)
- x->parens[k].index = -1;
- parenSoFar = curState->parenSoFar;
- }
- continue;
- }
- else
- return NULL;
- }
- else
- x = result;
-
- /*
- * Continue with the expression.
- */
- op = (REOp)*pc++;
- }
- return NULL;
-}
-
-static REMatchState *
-MatchRegExp(REGlobalData *gData, REMatchState *x)
-{
- REMatchState *result;
- const jschar *cp = x->cp;
- const jschar *cp2;
- uintN j;
-
- /*
- * Have to include the position beyond the last character
- * in order to detect end-of-input/line condition.
- */
- for (cp2 = cp; cp2 <= gData->cpend; cp2++) {
- gData->skipped = cp2 - cp;
- x->cp = cp2;
- for (j = 0; j < gData->regexp->parenCount; j++)
- x->parens[j].index = -1;
- result = executeREBytecode(gData, x);
- if (!gData->ok || result)
- return result;
- gData->backTrackSP = gData->backTrackStack;
- gData->cursz = 0;
- gData->stateStackTop = 0;
- cp2 = cp + gData->skipped;
- }
- return NULL;
-}
-
-
-static REMatchState *
-initMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re)
-{
- REMatchState *result;
- uintN i;
-
- gData->maxBackTrack = INITIAL_BACKTRACK;
- JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *,
- &gData->pool,
- INITIAL_BACKTRACK);
- if (!gData->backTrackStack)
- return NULL;
- gData->backTrackSP = gData->backTrackStack;
- gData->cursz = 0;
-
-
- gData->maxStateStack = INITIAL_STATESTACK;
- JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *,
- &gData->pool,
- sizeof(REProgState) * INITIAL_STATESTACK);
- if (!gData->stateStack)
- return NULL;
- gData->stateStackTop = 0;
-
- gData->cx = cx;
- gData->regexp = re;
- gData->ok = JS_TRUE;
-
- JS_ARENA_ALLOCATE_CAST(result, REMatchState *,
- &gData->pool,
- sizeof(REMatchState)
- + (re->parenCount - 1) * sizeof(RECapture));
- if (!result)
- return NULL;
-
- for (i = 0; i < re->classCount; i++)
- if (!re->classList[i].converted)
- if (!processCharSet(gData, &re->classList[i]))
- return NULL;
-
- return result;
-}
-
-JSBool
-js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
- JSBool test, jsval *rval)
-{
- REGlobalData gData;
- REMatchState *x, *result;
-
- const jschar *cp, *ep;
- size_t i, length, start;
- JSSubString *morepar;
- JSBool ok;
- JSRegExpStatics *res;
- ptrdiff_t matchlen;
- uintN num, morenum;
- JSString *parstr, *matchstr;
- JSObject *obj;
-
- RECapture *parsub;
-
- /*
- * It's safe to load from cp because JSStrings have a zero at the end,
- * and we never let cp get beyond cpend.
- */
- start = *indexp;
- length = JSSTRING_LENGTH(str);
- if (start > length)
- start = length;
- cp = JSSTRING_CHARS(str);
- gData.cpbegin = cp;
- gData.cpend = cp + length;
- cp += start;
- gData.start = start;
- gData.skipped = 0;
-
- JS_InitArenaPool(&gData.pool, "RegExpPool", 8096, 4);
- x = initMatch(cx, &gData, re);
- if (!x)
- return JS_FALSE;
- x->cp = cp;
-
- /*
- * Call the recursive matcher to do the real work. Return null on mismatch
- * whether testing or not. On match, return an extended Array object.
- */
- result = MatchRegExp(&gData, x);
- if (!(ok = gData.ok)) goto out;
- if (!result) {
- *rval = JSVAL_NULL;
- goto out;
- }
- cp = result->cp;
- i = PTRDIFF(cp, gData.cpbegin, jschar);
- *indexp = i;
- matchlen = i - (start + gData.skipped);
- ep = cp;
- cp -= matchlen;
-
- if (test) {
- /*
- * Testing for a match and updating cx->regExpStatics: don't allocate
- * an array object, do return true.
- */
- *rval = JSVAL_TRUE;
-
- /* Avoid warning. (gcc doesn't detect that obj is needed iff !test); */
- obj = NULL;
- } else {
- /*
- * The array returned on match has element 0 bound to the matched
- * string, elements 1 through state.parenCount bound to the paren
- * matches, an index property telling the length of the left context,
- * and an input property referring to the input string.
- */
- obj = js_NewArrayObject(cx, 0, NULL);
- if (!obj) {
- ok = JS_FALSE;
- goto out;
- }
- *rval = OBJECT_TO_JSVAL(obj);
-
-#define DEFVAL(val, id) { \
- ok = js_DefineProperty(cx, obj, id, val, \
- JS_PropertyStub, JS_PropertyStub, \
- JSPROP_ENUMERATE, NULL); \
- if (!ok) { \
- cx->newborn[GCX_OBJECT] = NULL; \
- cx->newborn[GCX_STRING] = NULL; \
- goto out; \
- } \
-}
-
- matchstr = js_NewStringCopyN(cx, cp, matchlen, 0);
- if (!matchstr) {
- cx->newborn[GCX_OBJECT] = NULL;
- ok = JS_FALSE;
- goto out;
- }
- DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSVAL(0));
- }
-
- res = &cx->regExpStatics;
- res->input = str;
- res->parenCount = re->parenCount;
- if (re->parenCount == 0)
- res->lastParen = js_EmptySubString;
- else {
- for (num = 0; num < re->parenCount; num++) {
- parsub = &result->parens[num];
- if (num < 9) {
- if (parsub->index == -1) {
- res->parens[num].chars = NULL;
- res->parens[num].length = 0;
- }
- else {
- res->parens[num].chars = gData.cpbegin + parsub->index;
- res->parens[num].length = parsub->length;
- }
- } else {
- morenum = num - 9;
- morepar = res->moreParens;
- if (!morepar) {
- res->moreLength = 10;
- morepar = (JSSubString*) JS_malloc(cx,
- 10 * sizeof(JSSubString));
- } else if (morenum >= res->moreLength) {
- res->moreLength += 10;
- morepar = (JSSubString*) JS_realloc(cx, morepar,
- res->moreLength * sizeof(JSSubString));
- }
- if (!morepar) {
- cx->newborn[GCX_OBJECT] = NULL;
- cx->newborn[GCX_STRING] = NULL;
- ok = JS_FALSE;
- goto out;
- }
- res->moreParens = morepar;
- if (parsub->index == -1) {
- morepar[morenum].chars = NULL;
- morepar[morenum].length = 0;
- }
- else {
- morepar[morenum].chars = gData.cpbegin + parsub->index;
- morepar[morenum].length = parsub->length;
- }
- }
- if (test)
- continue;
- if (parsub->index == -1)
- ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1),
- JSVAL_VOID, NULL, NULL,
- JSPROP_ENUMERATE, NULL);
- else {
- parstr = js_NewStringCopyN(cx, gData.cpbegin + parsub->index,
- parsub->length, 0);
- if (!parstr) {
- cx->newborn[GCX_OBJECT] = NULL;
- cx->newborn[GCX_STRING] = NULL;
- ok = JS_FALSE;
- goto out;
- }
- ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1),
- STRING_TO_JSVAL(parstr), NULL, NULL,
- JSPROP_ENUMERATE, NULL);
- }
- if (!ok) {
- cx->newborn[GCX_OBJECT] = NULL;
- cx->newborn[GCX_STRING] = NULL;
- goto out;
- }
- }
- if (parsub->index == -1) {
- res->lastParen.chars = NULL;
- res->lastParen.length = 0;
- }
- else {
- res->lastParen.chars = gData.cpbegin + parsub->index;
- res->lastParen.length = parsub->length;
- }
- }
-
- if (!test) {
- /*
- * Define the index and input properties last for better for/in loop
- * order (so they come after the elements).
- */
- DEFVAL(INT_TO_JSVAL(start + gData.skipped),
- (jsid)cx->runtime->atomState.indexAtom);
- DEFVAL(STRING_TO_JSVAL(str),
- (jsid)cx->runtime->atomState.inputAtom);
- }
-
-#undef DEFVAL
-
- res->lastMatch.chars = cp;
- res->lastMatch.length = matchlen;
- if (cx->version == JSVERSION_1_2) {
- /*
- * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
- * in scalar contexts, and unintentionally for the string.match "list"
- * psuedo-context. On "hi there bye", the following would result:
- *
- * Language while(/ /g){print("$`");} s/ /$`/g
- * perl4.036 "hi", "there" "hihitherehi therebye"
- * perl5 "hi", "hi there" "hihitherehi therebye"
- * js1.2 "hi", "there" "hihitheretherebye"
- */
- res->leftContext.chars = JSSTRING_CHARS(str) + start;
- res->leftContext.length = gData.skipped;
- } else {
- /*
- * For JS1.3 and ECMAv2, emulate Perl5 exactly:
- *
- * js1.3 "hi", "hi there" "hihitherehi therebye"
- */
- res->leftContext.chars = JSSTRING_CHARS(str);
- res->leftContext.length = start + gData.skipped;
- }
- res->rightContext.chars = ep;
- res->rightContext.length = gData.cpend - ep;
-
-out:
- JS_FinishArenaPool(&gData.pool);
- return ok;
-}
-
-/************************************************************************/
-
-enum regexp_tinyid {
- REGEXP_SOURCE = -1,
- REGEXP_GLOBAL = -2,
- REGEXP_IGNORE_CASE = -3,
- REGEXP_LAST_INDEX = -4,
- REGEXP_MULTILINE = -5
-};
-
-#define REGEXP_PROP_ATTRS (JSPROP_PERMANENT|JSPROP_SHARED)
-
-static JSPropertySpec regexp_props[] = {
- {"source", REGEXP_SOURCE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
- {"global", REGEXP_GLOBAL, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
- {"ignoreCase", REGEXP_IGNORE_CASE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
- {"lastIndex", REGEXP_LAST_INDEX, REGEXP_PROP_ATTRS,0,0},
- {"multiline", REGEXP_MULTILINE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
- {0,0,0,0,0}
-};
-
-static JSBool
-regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsint slot;
- JSRegExp *re;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- slot = JSVAL_TO_INT(id);
- if (slot == REGEXP_LAST_INDEX)
- return JS_GetReservedSlot(cx, obj, 0, vp);
-
- JS_LOCK_OBJ(cx, obj);
- re = (JSRegExp *) JS_GetInstancePrivate(cx, obj, &js_RegExpClass, NULL);
- if (re) {
- switch (slot) {
- case REGEXP_SOURCE:
- *vp = STRING_TO_JSVAL(re->source);
- break;
- case REGEXP_GLOBAL:
- *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0);
- break;
- case REGEXP_IGNORE_CASE:
- *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0);
- break;
- case REGEXP_MULTILINE:
- *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0);
- break;
- }
- }
- JS_UNLOCK_OBJ(cx, obj);
- return JS_TRUE;
-}
-
-static JSBool
-regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSBool ok;
- jsint slot;
- jsdouble lastIndex;
-
- ok = JS_TRUE;
- if (!JSVAL_IS_INT(id))
- return ok;
- slot = JSVAL_TO_INT(id);
- if (slot == REGEXP_LAST_INDEX) {
- if (!js_ValueToNumber(cx, *vp, &lastIndex))
- return JS_FALSE;
- lastIndex = js_DoubleToInteger(lastIndex);
- ok = js_NewNumberValue(cx, lastIndex, vp) &&
- JS_SetReservedSlot(cx, obj, 0, *vp);
- }
- return ok;
-}
-
-/*
- * RegExp class static properties and their Perl counterparts:
- *
- * RegExp.input $_
- * RegExp.multiline $*
- * RegExp.lastMatch $&
- * RegExp.lastParen $+
- * RegExp.leftContext $`
- * RegExp.rightContext $'
- */
-enum regexp_static_tinyid {
- REGEXP_STATIC_INPUT = -1,
- REGEXP_STATIC_MULTILINE = -2,
- REGEXP_STATIC_LAST_MATCH = -3,
- REGEXP_STATIC_LAST_PAREN = -4,
- REGEXP_STATIC_LEFT_CONTEXT = -5,
- REGEXP_STATIC_RIGHT_CONTEXT = -6
-};
-
-JSBool
-js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res)
-{
- JS_ClearRegExpStatics(cx);
- return js_AddRoot(cx, &res->input, "res->input");
-}
-
-void
-js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res)
-{
- if (res->moreParens) {
- JS_free(cx, res->moreParens);
- res->moreParens = NULL;
- }
- js_RemoveRoot(cx->runtime, &res->input);
-}
-
-static JSBool
-regexp_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- jsint slot;
- JSRegExpStatics *res;
- JSString *str;
- JSSubString *sub;
-
- res = &cx->regExpStatics;
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- slot = JSVAL_TO_INT(id);
- switch (slot) {
- case REGEXP_STATIC_INPUT:
- *vp = res->input ? STRING_TO_JSVAL(res->input)
- : JS_GetEmptyStringValue(cx);
- return JS_TRUE;
- case REGEXP_STATIC_MULTILINE:
- *vp = BOOLEAN_TO_JSVAL(res->multiline);
- return JS_TRUE;
- case REGEXP_STATIC_LAST_MATCH:
- sub = &res->lastMatch;
- break;
- case REGEXP_STATIC_LAST_PAREN:
- sub = &res->lastParen;
- break;
- case REGEXP_STATIC_LEFT_CONTEXT:
- sub = &res->leftContext;
- break;
- case REGEXP_STATIC_RIGHT_CONTEXT:
- sub = &res->rightContext;
- break;
- default:
- sub = REGEXP_PAREN_SUBSTRING(res, slot);
- break;
- }
- str = js_NewStringCopyN(cx, sub->chars, sub->length, 0);
- if (!str)
- return JS_FALSE;
- *vp = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-regexp_static_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSRegExpStatics *res;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- res = &cx->regExpStatics;
- /* XXX use if-else rather than switch to keep MSVC1.52 from crashing */
- if (JSVAL_TO_INT(id) == REGEXP_STATIC_INPUT) {
- if (!JSVAL_IS_STRING(*vp) &&
- !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
- return JS_FALSE;
- }
- res->input = JSVAL_TO_STRING(*vp);
- } else if (JSVAL_TO_INT(id) == REGEXP_STATIC_MULTILINE) {
- if (!JSVAL_IS_BOOLEAN(*vp) &&
- !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) {
- return JS_FALSE;
- }
- res->multiline = JSVAL_TO_BOOLEAN(*vp);
- }
- return JS_TRUE;
-}
-
-static JSPropertySpec regexp_static_props[] = {
- {"input",
- REGEXP_STATIC_INPUT,
- JSPROP_ENUMERATE|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_setProperty},
- {"multiline",
- REGEXP_STATIC_MULTILINE,
- JSPROP_ENUMERATE|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_setProperty},
- {"lastMatch",
- REGEXP_STATIC_LAST_MATCH,
- JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"lastParen",
- REGEXP_STATIC_LAST_PAREN,
- JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"leftContext",
- REGEXP_STATIC_LEFT_CONTEXT,
- JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"rightContext",
- REGEXP_STATIC_RIGHT_CONTEXT,
- JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
-
- /* XXX should have block scope and local $1, etc. */
- {"$1", 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$2", 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$3", 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$4", 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$5", 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$6", 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$7", 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$8", 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
- {"$9", 8, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
- regexp_static_getProperty, regexp_static_getProperty},
-
- {0,0,0,0,0}
-};
-
-static void
-regexp_finalize(JSContext *cx, JSObject *obj)
-{
- JSRegExp *re;
-
- re = (JSRegExp *) JS_GetPrivate(cx, obj);
- if (!re)
- return;
- js_DestroyRegExp(cx, re);
-}
-
-/* Forward static prototype. */
-static JSBool
-regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-static JSBool
-regexp_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return regexp_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
-}
-
-#if JS_HAS_XDR
-
-#include "jsxdrapi.h"
-
-static JSBool
-regexp_xdrObject(JSXDRState *xdr, JSObject **objp)
-{
- JSRegExp *re;
- JSString *source;
- uint8 flags;
-
- if (xdr->mode == JSXDR_ENCODE) {
- re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp);
- if (!re)
- return JS_FALSE;
- source = re->source;
- flags = (uint8) re->flags;
- }
- if (!JS_XDRString(xdr, &source) ||
- !JS_XDRUint8(xdr, &flags)) {
- return JS_FALSE;
- }
- if (xdr->mode == JSXDR_DECODE) {
- *objp = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
- if (!*objp)
- return JS_FALSE;
- re = js_NewRegExp(xdr->cx, NULL, source, flags, JS_FALSE);
- if (!re)
- return JS_FALSE;
- if (!JS_SetPrivate(xdr->cx, *objp, re) ||
- !js_SetLastIndex(xdr->cx, *objp, 0)) {
- js_DestroyRegExp(xdr->cx, re);
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-#else /* !JS_HAS_XDR */
-
-#define regexp_xdrObject NULL
-
-#endif /* !JS_HAS_XDR */
-
-static uint32
-regexp_mark(JSContext *cx, JSObject *obj, void *arg)
-{
- JSRegExp *re = (JSRegExp *) JS_GetPrivate(cx, obj);
- if (re)
- JS_MarkGCThing(cx, re->source, "source", arg);
- return 0;
-}
-
-JSClass js_RegExpClass = {
- js_RegExp_str,
- JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
- JS_PropertyStub, JS_PropertyStub, regexp_getProperty, regexp_setProperty,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, regexp_finalize,
- NULL, NULL, regexp_call, NULL,
- regexp_xdrObject, NULL, regexp_mark, 0
-};
-
-static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0};
-
-static JSBool
-regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSRegExp *re;
- const jschar *source;
- jschar *chars;
- size_t length, nflags;
- uintN flags;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
- return JS_FALSE;
- JS_LOCK_OBJ(cx, obj);
- re = (JSRegExp *) JS_GetPrivate(cx, obj);
- if (!re) {
- JS_UNLOCK_OBJ(cx, obj);
- *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
- return JS_TRUE;
- }
-
- source = JSSTRING_CHARS(re->source);
- length = JSSTRING_LENGTH(re->source);
- if (length == 0) {
- source = empty_regexp_ucstr;
- length = sizeof(empty_regexp_ucstr) / sizeof(jschar) - 1;
- }
- length += 2;
- nflags = 0;
- for (flags = re->flags; flags != 0; flags &= flags - 1)
- nflags++;
- chars = (jschar*) JS_malloc(cx, (length + nflags + 1) * sizeof(jschar));
- if (!chars) {
- JS_UNLOCK_OBJ(cx, obj);
- return JS_FALSE;
- }
-
- chars[0] = '/';
- js_strncpy(&chars[1], source, length - 2);
- chars[length-1] = '/';
- if (nflags) {
- if (re->flags & JSREG_GLOB)
- chars[length++] = 'g';
- if (re->flags & JSREG_FOLD)
- chars[length++] = 'i';
- if (re->flags & JSREG_MULTILINE)
- chars[length++] = 'm';
- }
- JS_UNLOCK_OBJ(cx, obj);
- chars[length] = 0;
-
- str = js_NewString(cx, chars, length, 0);
- if (!str) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *opt, *str;
- JSRegExp *oldre, *re;
- JSBool ok;
- JSObject *obj2;
-
- if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
- return JS_FALSE;
- opt = NULL;
- if (argc == 0) {
- str = cx->runtime->emptyString;
- } else {
- if (JSVAL_IS_OBJECT(argv[0])) {
- /*
- * If we get passed in a RegExp object we construct a new
- * RegExp that is a duplicate of it by re-compiling the
- * original source code. ECMA requires that it be an error
- * here if the flags are specified. (We must use the flags
- * from the original RegExp also).
- */
- obj2 = JSVAL_TO_OBJECT(argv[0]);
- if (obj2 && OBJ_GET_CLASS(cx, obj2) == &js_RegExpClass) {
- if (argc >= 2 && !JSVAL_IS_VOID(argv[1])) { /* 'flags' passed */
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_NEWREGEXP_FLAGGED);
- return JS_FALSE;
- }
- JS_LOCK_OBJ(cx, obj2);
- re = (JSRegExp *) JS_GetPrivate(cx, obj2);
- if (!re) {
- JS_UNLOCK_OBJ(cx, obj2);
- return JS_FALSE;
- }
- re = js_NewRegExp(cx, NULL, re->source, re->flags, JS_FALSE);
- JS_UNLOCK_OBJ(cx, obj2);
- goto madeit;
- }
- }
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str);
- if (argc > 1) {
- if (JSVAL_IS_VOID(argv[1])) {
- opt = NULL;
- } else {
- opt = js_ValueToString(cx, argv[1]);
- if (!opt)
- return JS_FALSE;
- argv[1] = STRING_TO_JSVAL(opt);
- }
- }
- }
- re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE);
-madeit:
- if (!re)
- return JS_FALSE;
- JS_LOCK_OBJ(cx, obj);
- oldre = (JSRegExp *) JS_GetPrivate(cx, obj);
- ok = JS_SetPrivate(cx, obj, re) && js_SetLastIndex(cx, obj, 0);
- JS_UNLOCK_OBJ(cx, obj);
- if (!ok) {
- js_DestroyRegExp(cx, re);
- } else {
- if (oldre)
- js_DestroyRegExp(cx, oldre);
- *rval = OBJECT_TO_JSVAL(obj);
- }
- return ok;
-}
-
-static JSBool
-regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- JSBool test, jsval *rval)
-{
- JSBool ok;
- JSRegExp *re;
- jsdouble lastIndex;
- JSString *str;
- size_t i;
-
- ok = JS_InstanceOf(cx, obj, &js_RegExpClass, argv);
- if (!ok)
- return JS_FALSE;
- JS_LOCK_OBJ(cx, obj);
- re = (JSRegExp *) JS_GetPrivate(cx, obj);
- if (!re) {
- JS_UNLOCK_OBJ(cx, obj);
- return JS_TRUE;
- }
-
- /* NB: we must reach out: after this paragraph, in order to drop re. */
- HOLD_REGEXP(cx, re);
- if (re->flags & JSREG_GLOB) {
- ok = js_GetLastIndex(cx, obj, &lastIndex);
- } else {
- lastIndex = 0;
- }
- JS_UNLOCK_OBJ(cx, obj);
- if (!ok)
- goto out;
-
- /* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */
- if (argc == 0) {
- str = cx->regExpStatics.input;
- if (!str) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_NO_INPUT,
- JS_GetStringBytes(re->source),
- (re->flags & JSREG_GLOB) ? "g" : "",
- (re->flags & JSREG_FOLD) ? "i" : "",
- (re->flags & JSREG_MULTILINE) ? "m" : "");
- ok = JS_FALSE;
- goto out;
- }
- } else {
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- goto out;
- argv[0] = STRING_TO_JSVAL(str);
- }
-
- if (lastIndex < 0 || JSSTRING_LENGTH(str) < lastIndex) {
- ok = js_SetLastIndex(cx, obj, 0);
- *rval = JSVAL_NULL;
- } else {
- i = (size_t) lastIndex;
- ok = js_ExecuteRegExp(cx, re, str, &i, test, rval);
- if (ok && (re->flags & JSREG_GLOB))
- ok = js_SetLastIndex(cx, obj, (*rval == JSVAL_NULL) ? 0 : i);
- }
-
-out:
- DROP_REGEXP(cx, re);
- return ok;
-}
-
-static JSBool
-regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return regexp_exec_sub(cx, obj, argc, argv, JS_FALSE, rval);
-}
-
-static JSBool
-regexp_test(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (!regexp_exec_sub(cx, obj, argc, argv, JS_TRUE, rval))
- return JS_FALSE;
- if (*rval != JSVAL_TRUE)
- *rval = JSVAL_FALSE;
- return JS_TRUE;
-}
-
-static JSFunctionSpec regexp_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, regexp_toString, 0,0,0},
-#endif
- {js_toString_str, regexp_toString, 0,0,0},
- {"compile", regexp_compile, 1,0,0},
- {"exec", regexp_exec, 0,0,0},
- {"test", regexp_test, 0,0,0},
- {0,0,0,0,0}
-};
-
-static JSBool
-RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- /*
- * If first arg is regexp and no flags are given, just return the arg.
- * (regexp_compile detects the regexp + flags case and throws a
- * TypeError.) See 10.15.3.1.
- */
- if ((argc < 2 || JSVAL_IS_VOID(argv[1])) && JSVAL_IS_OBJECT(argv[0]) &&
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0])) == &js_RegExpClass) {
- *rval = argv[0];
- return JS_TRUE;
- }
-
- /* Otherwise, replace obj with a new RegExp object. */
- obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- }
- return regexp_compile(cx, obj, argc, argv, rval);
-}
-
-JSObject *
-js_InitRegExpClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto, *ctor;
- jsval rval;
-
- proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1,
- regexp_props, regexp_methods,
- regexp_static_props, NULL);
-
- if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
- return NULL;
- if (!JS_AliasProperty(cx, ctor, "input", "$_") ||
- !JS_AliasProperty(cx, ctor, "multiline", "$*") ||
- !JS_AliasProperty(cx, ctor, "lastMatch", "$&") ||
- !JS_AliasProperty(cx, ctor, "lastParen", "$+") ||
- !JS_AliasProperty(cx, ctor, "leftContext", "$`") ||
- !JS_AliasProperty(cx, ctor, "rightContext", "$'")) {
- goto bad;
- }
-
- /* Give RegExp.prototype private data so it matches the empty string. */
- if (!regexp_compile(cx, proto, 0, NULL, &rval))
- goto bad;
- return proto;
-
-bad:
- JS_DeleteProperty(cx, obj, js_RegExpClass.name);
- return NULL;
-}
-
-JSObject *
-js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
- jschar *chars, size_t length, uintN flags)
-{
- JSString *str;
- JSObject *obj;
- JSRegExp *re;
-
- str = js_NewStringCopyN(cx, chars, length, 0);
- if (!str)
- return NULL;
- re = js_NewRegExp(cx, ts, str, flags, JS_FALSE);
- if (!re)
- return NULL;
- obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
- if (!obj || !JS_SetPrivate(cx, obj, re) || !js_SetLastIndex(cx, obj, 0)) {
- js_DestroyRegExp(cx, re);
- return NULL;
- }
- return obj;
-}
-
-JSObject *
-js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent)
-{
- JSObject *clone;
- JSRegExp *re;
-
- JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
- clone = js_NewObject(cx, &js_RegExpClass, NULL, parent);
- if (!clone)
- return NULL;
- re = JS_GetPrivate(cx, obj);
- if (!JS_SetPrivate(cx, clone, re) || !js_SetLastIndex(cx, clone, 0)) {
- cx->newborn[GCX_OBJECT] = NULL;
- return NULL;
- }
- HOLD_REGEXP(cx, re);
- return clone;
-}
-
-JSBool
-js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex)
-{
- jsval v;
-
- return JS_GetReservedSlot(cx, obj, 0, &v) &&
- js_ValueToNumber(cx, v, lastIndex);
-}
-
-JSBool
-js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex)
-{
- jsval v;
-
- return js_NewNumberValue(cx, lastIndex, &v) &&
- JS_SetReservedSlot(cx, obj, 0, v);
-}
-
-#endif /* JS_HAS_REGEXPS */
diff --git a/src/extension/script/js/jsregexp.h b/src/extension/script/js/jsregexp.h
deleted file mode 100644
index 0485c2860..000000000
--- a/src/extension/script/js/jsregexp.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsregexp_h___
-#define jsregexp_h___
-/*
- * JS regular expression interface.
- */
-#include <stddef.h>
-#include "jspubtd.h"
-#include "jsstr.h"
-
-#ifdef JS_THREADSAFE
-#include "jsdhash.h"
-#endif
-
-struct JSRegExpStatics {
- JSString *input; /* input string to match (perl $_, GC root) */
- JSBool multiline; /* whether input contains newlines (perl $*) */
- uintN parenCount; /* number of valid elements in parens[] */
- uintN moreLength; /* number of allocated elements in moreParens */
- JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */
- JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */
- JSSubString lastMatch; /* last string matched (perl $&) */
- JSSubString lastParen; /* last paren matched (perl $+) */
- JSSubString leftContext; /* input to left of last match (perl $`) */
- JSSubString rightContext; /* input to right of last match (perl $') */
-};
-
-/*
- * This struct holds a bitmap representation of a class from a regexp.
- * There's a list of these referenced by the classList field in the JSRegExp
- * struct below. The initial state has startIndex set to the offset in the
- * original regexp source of the beginning of the class contents. The first
- * use of the class converts the source representation into a bitmap.
- *
- */
-typedef struct RECharSet {
- JSBool converted;
- JSBool sense;
- uint16 length;
- union {
- uint8 *bits;
- struct {
- uint16 startIndex;
- uint16 length;
- } src;
- } u;
-} RECharSet;
-
-/*
- * This macro is safe because moreParens is guaranteed to be allocated and big
- * enough to hold parenCount, or else be null when parenCount is 0.
- */
-#define REGEXP_PAREN_SUBSTRING(res, num) \
- (((jsuint)(num) < (jsuint)(res)->parenCount) \
- ? ((jsuint)(num) < 9) \
- ? &(res)->parens[num] \
- : &(res)->moreParens[(num) - 9] \
- : &js_EmptySubString)
-
-typedef struct RENode RENode;
-
-struct JSRegExp {
- jsrefcount nrefs; /* reference count */
- uint32 parenCount:24, /* number of parenthesized submatches */
- flags:8; /* flags, see jsapi.h's JSREG_* defines */
- uint32 classCount; /* count [...] bitmaps */
- RECharSet *classList; /* list of [...] bitmaps */
- JSString *source; /* locked source string, sans // */
- jsbytecode program[1]; /* regular expression bytecode */
-};
-
-extern JSRegExp *
-js_NewRegExp(JSContext *cx, JSTokenStream *ts,
- JSString *str, uintN flags, JSBool flat);
-
-extern JSRegExp *
-js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
- JSString *str, JSString *opt, JSBool flat);
-
-extern void
-js_DestroyRegExp(JSContext *cx, JSRegExp *re);
-
-/*
- * Execute re on input str at *indexp, returning null in *rval on mismatch.
- * On match, return true if test is true, otherwise return an array object.
- * Update *indexp and cx->regExpStatics always on match.
- */
-extern JSBool
-js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
- JSBool test, jsval *rval);
-
-/*
- * These two add and remove GC roots, respectively, so their calls must be
- * well-ordered.
- */
-extern JSBool
-js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res);
-
-extern void
-js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res);
-
-#define JSVAL_IS_REGEXP(cx, v) \
- (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass)
-
-extern JSClass js_RegExpClass;
-
-extern JSObject *
-js_InitRegExpClass(JSContext *cx, JSObject *obj);
-
-/*
- * Create a new RegExp object.
- */
-extern JSObject *
-js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
- jschar *chars, size_t length, uintN flags);
-
-extern JSBool
-js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
-
-extern JSObject *
-js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent);
-
-extern JSBool
-js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex);
-
-extern JSBool
-js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex);
-
-#endif /* jsregexp_h___ */
diff --git a/src/extension/script/js/jsscan.c b/src/extension/script/js/jsscan.c
deleted file mode 100644
index e0bc5cd92..000000000
--- a/src/extension/script/js/jsscan.c
+++ /dev/null
@@ -1,1315 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS lexical scanner.
- */
-#include "jsstddef.h"
-#include <stdio.h> /* first to avoid trouble on some systems */
-#include <errno.h>
-#include <limits.h>
-#include <math.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h" /* Added by JSIFY */
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsdtoa.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsemit.h"
-#include "jsexn.h"
-#include "jsnum.h"
-#include "jsopcode.h"
-#include "jsregexp.h"
-#include "jsscan.h"
-
-#define RESERVE_JAVA_KEYWORDS
-#define RESERVE_ECMA_KEYWORDS
-
-static struct keyword {
- const char *name;
- JSTokenType tokentype; /* JSTokenType */
- JSOp op; /* JSOp */
- JSVersion version; /* JSVersion */
-} keywords[] = {
- {"break", TOK_BREAK, JSOP_NOP, JSVERSION_DEFAULT},
- {"case", TOK_CASE, JSOP_NOP, JSVERSION_DEFAULT},
- {"continue", TOK_CONTINUE, JSOP_NOP, JSVERSION_DEFAULT},
- {"default", TOK_DEFAULT, JSOP_NOP, JSVERSION_DEFAULT},
- {js_delete_str, TOK_DELETE, JSOP_NOP, JSVERSION_DEFAULT},
- {"do", TOK_DO, JSOP_NOP, JSVERSION_DEFAULT},
- {"else", TOK_ELSE, JSOP_NOP, JSVERSION_DEFAULT},
- {"export", TOK_EXPORT, JSOP_NOP, JSVERSION_1_2},
- {js_false_str, TOK_PRIMARY, JSOP_FALSE, JSVERSION_DEFAULT},
- {"for", TOK_FOR, JSOP_NOP, JSVERSION_DEFAULT},
- {js_function_str, TOK_FUNCTION, JSOP_NOP, JSVERSION_DEFAULT},
- {"if", TOK_IF, JSOP_NOP, JSVERSION_DEFAULT},
- {js_in_str, TOK_IN, JSOP_IN, JSVERSION_DEFAULT},
- {js_new_str, TOK_NEW, JSOP_NEW, JSVERSION_DEFAULT},
- {js_null_str, TOK_PRIMARY, JSOP_NULL, JSVERSION_DEFAULT},
- {"return", TOK_RETURN, JSOP_NOP, JSVERSION_DEFAULT},
- {"switch", TOK_SWITCH, JSOP_NOP, JSVERSION_DEFAULT},
- {js_this_str, TOK_PRIMARY, JSOP_THIS, JSVERSION_DEFAULT},
- {js_true_str, TOK_PRIMARY, JSOP_TRUE, JSVERSION_DEFAULT},
- {js_typeof_str, TOK_UNARYOP, JSOP_TYPEOF,JSVERSION_DEFAULT},
- {"var", TOK_VAR, JSOP_DEFVAR,JSVERSION_DEFAULT},
- {js_void_str, TOK_UNARYOP, JSOP_VOID, JSVERSION_DEFAULT},
- {"while", TOK_WHILE, JSOP_NOP, JSVERSION_DEFAULT},
- {"with", TOK_WITH, JSOP_NOP, JSVERSION_DEFAULT},
-
-#if JS_HAS_CONST
- {js_const_str, TOK_VAR, JSOP_DEFCONST,JSVERSION_DEFAULT},
-#else
- {js_const_str, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
-#endif
-
-#if JS_HAS_EXCEPTIONS
- {"try", TOK_TRY, JSOP_NOP, JSVERSION_DEFAULT},
- {"catch", TOK_CATCH, JSOP_NOP, JSVERSION_DEFAULT},
- {"finally", TOK_FINALLY, JSOP_NOP, JSVERSION_DEFAULT},
- {"throw", TOK_THROW, JSOP_NOP, JSVERSION_DEFAULT},
-#else
- {"try", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"catch", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"finally", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"throw", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
-#endif
-
-#if JS_HAS_INSTANCEOF
- {js_instanceof_str, TOK_INSTANCEOF, JSOP_INSTANCEOF,JSVERSION_1_4},
-#else
- {js_instanceof_str, TOK_RESERVED, JSOP_NOP, JSVERSION_1_4},
-#endif
-
-#ifdef RESERVE_JAVA_KEYWORDS
- {"abstract", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"boolean", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"byte", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"char", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"class", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"double", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"extends", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"final", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"float", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"goto", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"implements", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"import", TOK_IMPORT, JSOP_NOP, JSVERSION_DEFAULT},
- {"int", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"interface", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"long", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"native", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"package", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"private", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"protected", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"public", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"short", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"static", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"super", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"synchronized", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"throws", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"transient", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
- {"volatile", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT},
-#endif
-
-#ifdef RESERVE_ECMA_KEYWORDS
- {"enum", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3},
-#endif
-
-#if JS_HAS_DEBUGGER_KEYWORD
- {"debugger", TOK_DEBUGGER, JSOP_NOP, JSVERSION_1_3},
-#elif defined(RESERVE_ECMA_KEYWORDS)
- {"debugger", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3},
-#endif
- {0, TOK_EOF, JSOP_NOP, JSVERSION_DEFAULT}
-};
-
-JSBool
-js_InitScanner(JSContext *cx)
-{
- struct keyword *kw;
- JSAtom *atom;
-
- for (kw = keywords; kw->name; kw++) {
- atom = js_Atomize(cx, kw->name, strlen(kw->name), ATOM_PINNED);
- if (!atom)
- return JS_FALSE;
- ATOM_SET_KEYWORD(atom, kw);
- }
- return JS_TRUE;
-}
-
-JS_FRIEND_API(void)
-js_MapKeywords(void (*mapfun)(const char *))
-{
- struct keyword *kw;
-
- for (kw = keywords; kw->name; kw++)
- mapfun(kw->name);
-}
-
-JSTokenStream *
-js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
- const char *filename, uintN lineno,
- JSPrincipals *principals)
-{
- JSTokenStream *ts;
-
- ts = js_NewBufferTokenStream(cx, base, length);
- if (!ts)
- return NULL;
- ts->filename = filename;
- ts->lineno = lineno;
- if (principals)
- JSPRINCIPALS_HOLD(cx, principals);
- ts->principals = principals;
- return ts;
-}
-
-JS_FRIEND_API(JSTokenStream *)
-js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length)
-{
- size_t nb;
- JSTokenStream *ts;
-
- nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar);
- JS_ARENA_ALLOCATE_CAST(ts, JSTokenStream *, &cx->tempPool, nb);
- if (!ts) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- memset(ts, 0, nb);
- ts->lineno = 1;
- ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = (jschar *)(ts + 1);
- ts->userbuf.base = (jschar *)base;
- ts->userbuf.limit = (jschar *)base + length;
- ts->userbuf.ptr = (jschar *)base;
- ts->listener = cx->runtime->sourceHandler;
- ts->listenerData = cx->runtime->sourceHandlerData;
- return ts;
-}
-
-JS_FRIEND_API(JSTokenStream *)
-js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
-{
- jschar *base;
- JSTokenStream *ts;
- FILE *file;
-
- JS_ARENA_ALLOCATE_CAST(base, jschar *, &cx->tempPool,
- JS_LINE_LIMIT * sizeof(jschar));
- if (!base)
- return NULL;
- ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT);
- if (!ts)
- return NULL;
- if (!filename || strcmp(filename, "-") == 0) {
- file = defaultfp;
- } else {
- file = fopen(filename, "r");
- if (!file) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
- filename, "No such file or directory");
- return NULL;
- }
- }
- ts->userbuf.ptr = ts->userbuf.limit;
- ts->file = file;
- ts->filename = filename;
- return ts;
-}
-
-JS_FRIEND_API(JSBool)
-js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
-{
- if (ts->principals)
- JSPRINCIPALS_DROP(cx, ts->principals);
- return !ts->file || fclose(ts->file) == 0;
-}
-
-static int
-my_fgets(char *buf, int size, FILE *file)
-{
- int n, i, c;
- JSBool crflag;
-
- n = size - 1;
- if (n < 0)
- return -1;
-
- crflag = JS_FALSE;
- for (i = 0; i < n && (c = getc(file)) != EOF; i++) {
- buf[i] = c;
- if (c == '\n') { /* any \n ends a line */
- i++; /* keep the \n; we know there is room for \0 */
- break;
- }
- if (crflag) { /* \r not followed by \n ends line at the \r */
- ungetc(c, file);
- break; /* and overwrite c in buf with \0 */
- }
- crflag = (c == '\r');
- }
-
- buf[i] = '\0';
- return i;
-}
-
-static int32
-GetChar(JSTokenStream *ts)
-{
- int32 c;
- ptrdiff_t i, j, len, olen;
- JSBool crflag;
- char cbuf[JS_LINE_LIMIT];
- jschar *ubuf, *nl;
-
- if (ts->ungetpos != 0) {
- c = ts->ungetbuf[--ts->ungetpos];
- } else {
- do {
- if (ts->linebuf.ptr == ts->linebuf.limit) {
- len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar);
- if (len <= 0) {
- if (!ts->file) {
- ts->flags |= TSF_EOF;
- return EOF;
- }
-
- /* Fill ts->userbuf so that \r and \r\n convert to \n. */
- crflag = (ts->flags & TSF_CRFLAG) != 0;
- len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
- if (len <= 0) {
- ts->flags |= TSF_EOF;
- return EOF;
- }
- olen = len;
- ubuf = ts->userbuf.base;
- i = 0;
- if (crflag) {
- ts->flags &= ~TSF_CRFLAG;
- if (cbuf[0] != '\n') {
- ubuf[i++] = '\n';
- len++;
- ts->linepos--;
- }
- }
- for (j = 0; i < len; i++, j++)
- ubuf[i] = (jschar) (unsigned char) cbuf[j];
- ts->userbuf.limit = ubuf + len;
- ts->userbuf.ptr = ubuf;
- }
- if (ts->listener) {
- ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len,
- &ts->listenerTSData, ts->listenerData);
- }
-
- /*
- * Any one of \n, \r, or \r\n ends a line (longest match wins).
- * Also allow the Unicode line and paragraph separators.
- */
- for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) {
- /*
- * Try to prevent value-testing on most characters by
- * filtering out characters that aren't 000x or 202x.
- */
- if ((*nl & 0xDFD0) == 0) {
- if (*nl == '\n')
- break;
- if (*nl == '\r') {
- if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')
- nl++;
- break;
- }
- if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
- break;
- }
- }
-
- /*
- * If there was a line terminator, copy thru it into linebuf.
- * Else copy JS_LINE_LIMIT-1 bytes into linebuf.
- */
- if (nl < ts->userbuf.limit)
- len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1;
- if (len >= JS_LINE_LIMIT)
- len = JS_LINE_LIMIT - 1;
- js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len);
- ts->userbuf.ptr += len;
- olen = len;
-
- /*
- * Make sure linebuf contains \n for EOL (don't do this in
- * userbuf because the user's string might be readonly).
- */
- if (nl < ts->userbuf.limit) {
- if (*nl == '\r') {
- if (ts->linebuf.base[len-1] == '\r') {
- /*
- * Does the line segment end in \r? We must check
- * for a \n at the front of the next segment before
- * storing a \n into linebuf. This case matters
- * only when we're reading from a file.
- */
- if (nl + 1 == ts->userbuf.limit && ts->file) {
- len--;
- ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */
- if (len == 0) {
- /*
- * This can happen when a segment ends in
- * \r\r. Start over. ptr == limit in this
- * case, so we'll fall into buffer-filling
- * code.
- */
- return GetChar(ts);
- }
- } else {
- ts->linebuf.base[len-1] = '\n';
- }
- }
- } else if (*nl == '\n') {
- if (nl > ts->userbuf.base &&
- nl[-1] == '\r' &&
- ts->linebuf.base[len-2] == '\r') {
- len--;
- JS_ASSERT(ts->linebuf.base[len] == '\n');
- ts->linebuf.base[len-1] = '\n';
- }
- } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {
- ts->linebuf.base[len-1] = '\n';
- }
- }
-
- /* Reset linebuf based on adjusted segment length. */
- ts->linebuf.limit = ts->linebuf.base + len;
- ts->linebuf.ptr = ts->linebuf.base;
-
- /* Update position of linebuf within physical userbuf line. */
- if (!(ts->flags & TSF_NLFLAG))
- ts->linepos += ts->linelen;
- else
- ts->linepos = 0;
- if (ts->linebuf.limit[-1] == '\n')
- ts->flags |= TSF_NLFLAG;
- else
- ts->flags &= ~TSF_NLFLAG;
-
- /* Update linelen from original segment length. */
- ts->linelen = olen;
- }
- c = *ts->linebuf.ptr++;
- } while (JS_ISFORMAT(c));
- }
- if (c == '\n')
- ts->lineno++;
- return c;
-}
-
-static void
-UngetChar(JSTokenStream *ts, int32 c)
-{
- if (c == EOF)
- return;
- JS_ASSERT(ts->ungetpos < sizeof ts->ungetbuf / sizeof ts->ungetbuf[0]);
- if (c == '\n')
- ts->lineno--;
- ts->ungetbuf[ts->ungetpos++] = (jschar)c;
-}
-
-static int32
-PeekChar(JSTokenStream *ts)
-{
- int32 c;
-
- c = GetChar(ts);
- UngetChar(ts, c);
- return c;
-}
-
-static JSBool
-PeekChars(JSTokenStream *ts, intN n, jschar *cp)
-{
- intN i, j;
- int32 c;
-
- for (i = 0; i < n; i++) {
- c = GetChar(ts);
- if (c == EOF)
- break;
- cp[i] = (jschar)c;
- }
- for (j = i - 1; j >= 0; j--)
- UngetChar(ts, cp[j]);
- return i == n;
-}
-
-static void
-SkipChars(JSTokenStream *ts, intN n)
-{
- while (--n >= 0)
- GetChar(ts);
-}
-
-static JSBool
-MatchChar(JSTokenStream *ts, int32 expect)
-{
- int32 c;
-
- c = GetChar(ts);
- if (c == expect)
- return JS_TRUE;
- UngetChar(ts, c);
- return JS_FALSE;
-}
-
-JSBool
-js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts,
- JSCodeGenerator *cg, uintN flags,
- const uintN errorNumber, ...)
-{
- va_list ap;
- JSErrorReporter onError;
- JSErrorReport report;
- jschar *tokenptr;
- JSString *linestr = NULL;
- char *message;
- JSBool warning;
-
- if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
- return JS_TRUE;
-
- memset(&report, 0, sizeof (struct JSErrorReport));
- report.flags = flags;
- report.errorNumber = errorNumber;
- message = NULL;
-
- va_start(ap, errorNumber);
- if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
- errorNumber, &message, &report, &warning,
- JS_TRUE, ap)) {
- return JS_FALSE;
- }
- va_end(ap);
-
- js_AddRoot(cx, &linestr, "error line buffer");
-
- JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
- onError = cx->errorReporter;
- if (onError) {
- /*
- * We are typically called with non-null ts and null cg from jsparse.c.
- * We can be called with null ts from the regexp compilation functions.
- * The code generator (jsemit.c) may pass null ts and non-null cg.
- */
- if (ts) {
- report.filename = ts->filename;
- report.lineno = ts->lineno;
- linestr = js_NewStringCopyN(cx, ts->linebuf.base,
- ts->linebuf.limit - ts->linebuf.base,
- 0);
- report.linebuf = linestr
- ? JS_GetStringBytes(linestr)
- : NULL;
- tokenptr =
- ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].ptr;
- report.tokenptr = linestr
- ? report.linebuf + (tokenptr - ts->linebuf.base)
- : NULL;
- report.uclinebuf = linestr
- ? JS_GetStringChars(linestr)
- : NULL;
- report.uctokenptr = linestr
- ? report.uclinebuf + (tokenptr - ts->linebuf.base)
- : NULL;
- } else if (cg) {
- report.filename = cg->filename;
- report.lineno = CG_CURRENT_LINE(cg);
- }
-
-#if JS_HAS_ERROR_EXCEPTIONS
- /*
- * If there's a runtime exception type associated with this error
- * number, set that as the pending exception. For errors occuring at
- * compile time, this is very likely to be a JSEXN_SYNTAXERR.
- *
- * If an exception is thrown but not caught, the JSREPORT_EXCEPTION
- * flag will be set in report.flags. Proper behavior for an error
- * reporter is to ignore a report with this flag for all but top-level
- * compilation errors. The exception will remain pending, and so long
- * as the non-top-level "load", "eval", or "compile" native function
- * returns false, the top-level reporter will eventually receive the
- * uncaught exception report.
- *
- * XXX it'd probably be best if there was only one call to this
- * function, but there seem to be two error reporter call points.
- */
-
- /*
- * Only try to raise an exception if there isn't one already set -
- * otherwise the exception will describe only the last compile error,
- * which is likely spurious.
- */
- if (!(ts && (ts->flags & TSF_ERROR)))
- if (js_ErrorToException(cx, message, &report))
- onError = NULL;
-
- /*
- * Suppress any compiletime errors that don't occur at the top level.
- * This may still fail, as interplevel may be zero in contexts where we
- * don't really want to call the error reporter, as when js is called
- * by other code which could catch the error.
- */
- if (cx->interpLevel != 0)
- onError = NULL;
-#endif
- if (cx->runtime->debugErrorHook && onError) {
- JSDebugErrorHook hook = cx->runtime->debugErrorHook;
- /* test local in case debugErrorHook changed on another thread */
- if (hook && !hook(cx, message, &report,
- cx->runtime->debugErrorHookData)) {
- onError = NULL;
- }
- }
- if (onError)
- (*onError)(cx, message, &report);
- }
- if (message)
- JS_free(cx, message);
- if (report.messageArgs) {
- int i = 0;
- while (report.messageArgs[i])
- JS_free(cx, (void *)report.messageArgs[i++]);
- JS_free(cx, (void *)report.messageArgs);
- }
- if (report.ucmessage)
- JS_free(cx, (void *)report.ucmessage);
-
- js_RemoveRoot(cx->runtime, &linestr);
-
- if (ts && !JSREPORT_IS_WARNING(flags)) {
- /* Set the error flag to suppress spurious reports. */
- ts->flags |= TSF_ERROR;
- }
- return warning;
-}
-
-JSTokenType
-js_PeekToken(JSContext *cx, JSTokenStream *ts)
-{
- JSTokenType tt;
-
- if (ts->lookahead != 0) {
- tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type;
- } else {
- tt = js_GetToken(cx, ts);
- js_UngetToken(ts);
- }
- return tt;
-}
-
-JSTokenType
-js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts)
-{
- JSTokenType tt;
-
- JS_ASSERT(ts->lookahead == 0 ||
- ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos));
- ts->flags |= TSF_NEWLINES;
- tt = js_PeekToken(cx, ts);
- ts->flags &= ~TSF_NEWLINES;
- return tt;
-}
-
-#define TBMIN 64
-
-static JSBool
-GrowTokenBuf(JSContext *cx, JSTokenBuf *tb)
-{
- jschar *base;
- ptrdiff_t offset, length;
- size_t tbsize;
- JSArenaPool *pool;
-
- base = tb->base;
- offset = PTRDIFF(tb->ptr, base, jschar);
- pool = &cx->tempPool;
- if (!base) {
- tbsize = TBMIN * sizeof(jschar);
- length = TBMIN;
- JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize);
- } else {
- length = PTRDIFF(tb->limit, base, jschar);
- tbsize = length * sizeof(jschar);
- length <<= 1;
- JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize);
- }
- if (!base) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- tb->base = base;
- tb->limit = base + length;
- tb->ptr = base + offset;
- return JS_TRUE;
-}
-
-static JSBool
-AddToTokenBuf(JSContext *cx, JSTokenBuf *tb, jschar c)
-{
- if (tb->ptr == tb->limit && !GrowTokenBuf(cx, tb))
- return JS_FALSE;
- *tb->ptr++ = c;
- return JS_TRUE;
-}
-
-/*
- * We have encountered a '\': check for a Unicode escape sequence after it,
- * returning the character code value if we found a Unicode escape sequence.
- * Otherwise, non-destructively return the original '\'.
- */
-static int32
-GetUnicodeEscape(JSTokenStream *ts)
-{
- jschar cp[5];
- int32 c;
-
- if (PeekChars(ts, 5, cp) && cp[0] == 'u' &&
- JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
- JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4]))
- {
- c = (((((JS7_UNHEX(cp[1]) << 4)
- + JS7_UNHEX(cp[2])) << 4)
- + JS7_UNHEX(cp[3])) << 4)
- + JS7_UNHEX(cp[4]);
- SkipChars(ts, 5);
- return c;
- }
- return '\\';
-}
-
-JSTokenType
-js_GetToken(JSContext *cx, JSTokenStream *ts)
-{
- JSTokenType tt;
- JSToken *tp;
- int32 c;
- JSAtom *atom;
- JSBool hadUnicodeEscape;
-
-#define INIT_TOKENBUF(tb) ((tb)->ptr = (tb)->base)
-#define FINISH_TOKENBUF(tb) if (!AddToTokenBuf(cx, tb, 0)) RETURN(TOK_ERROR)
-#define TOKEN_LENGTH(tb) ((tb)->ptr - (tb)->base - 1)
-#define RETURN(tt) { if (tt == TOK_ERROR) ts->flags |= TSF_ERROR; \
- tp->pos.end.index = ts->linepos + \
- (ts->linebuf.ptr - ts->linebuf.base) - \
- ts->ungetpos; \
- return (tp->type = tt); }
-
- /* If there was a fatal error, keep returning TOK_ERROR. */
- if (ts->flags & TSF_ERROR)
- return TOK_ERROR;
-
- /* Check for a pushed-back token resulting from mismatching lookahead. */
- while (ts->lookahead != 0) {
- ts->lookahead--;
- ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
- tt = CURRENT_TOKEN(ts).type;
- if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES))
- return tt;
- }
-
-retry:
- do {
- c = GetChar(ts);
- if (c == '\n') {
- ts->flags &= ~TSF_DIRTYLINE;
- if (ts->flags & TSF_NEWLINES)
- break;
- }
- } while (JS_ISSPACE(c));
-
- ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
- tp = &CURRENT_TOKEN(ts);
- tp->ptr = ts->linebuf.ptr - 1;
- tp->pos.begin.index = ts->linepos + (tp->ptr - ts->linebuf.base);
- tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno;
-
- if (c == EOF)
- RETURN(TOK_EOF);
- if (c != '-' && c != '\n')
- ts->flags |= TSF_DIRTYLINE;
-
- hadUnicodeEscape = JS_FALSE;
- if (JS_ISIDENT_START(c) ||
- (c == '\\' &&
- (c = GetUnicodeEscape(ts),
- hadUnicodeEscape = JS_ISIDENT_START(c)))) {
- INIT_TOKENBUF(&ts->tokenbuf);
- for (;;) {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- if (c == '\\') {
- c = GetUnicodeEscape(ts);
- if (!JS_ISIDENT(c))
- break;
- hadUnicodeEscape = JS_TRUE;
- } else {
- if (!JS_ISIDENT(c))
- break;
- }
- }
- UngetChar(ts, c);
- FINISH_TOKENBUF(&ts->tokenbuf);
-
- atom = js_AtomizeChars(cx,
- ts->tokenbuf.base,
- TOKEN_LENGTH(&ts->tokenbuf),
- 0);
- if (!atom)
- RETURN(TOK_ERROR);
- if (!hadUnicodeEscape && ATOM_KEYWORD(atom)) {
- struct keyword *kw = ATOM_KEYWORD(atom);
-
- if (JSVERSION_IS_ECMA(cx->version) || kw->version <= cx->version) {
- tp->t_op = (JSOp) kw->op;
- RETURN(kw->tokentype);
- }
- }
- tp->t_op = JSOP_NAME;
- tp->t_atom = atom;
- RETURN(TOK_NAME);
- }
-
- if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) {
- jsint radix;
- const jschar *endptr;
- jsdouble dval;
-
- radix = 10;
- INIT_TOKENBUF(&ts->tokenbuf);
-
- if (c == '0') {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- if (JS_TOLOWER(c) == 'x') {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- radix = 16;
- } else if (JS7_ISDEC(c)) {
- radix = 8;
- }
- }
-
- while (JS7_ISHEX(c)) {
- if (radix < 16) {
- if (JS7_ISLET(c))
- break;
-
- /*
- * We permit 08 and 09 as decimal numbers, which makes our
- * behaviour a superset of the ECMA numeric grammar. We might
- * not always be so permissive, so we warn about it.
- */
- if (radix == 8 && c >= '8') {
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING,
- JSMSG_BAD_OCTAL,
- c == '8' ? "08" : "09")) {
- RETURN(TOK_ERROR);
- }
- radix = 10;
- }
- }
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- }
-
- if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) {
- if (c == '.') {
- do {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- } while (JS7_ISDEC(c));
- }
- if (JS_TOLOWER(c) == 'e') {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- if (c == '+' || c == '-') {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- }
- if (!JS7_ISDEC(c)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_MISSING_EXPONENT);
- RETURN(TOK_ERROR);
- }
- do {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- } while (JS7_ISDEC(c));
- }
- }
-
- UngetChar(ts, c);
- FINISH_TOKENBUF(&ts->tokenbuf);
-
- if (radix == 10) {
- if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_OUT_OF_MEMORY);
- RETURN(TOK_ERROR);
- }
- } else {
- if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_OUT_OF_MEMORY);
- RETURN(TOK_ERROR);
- }
- }
- tp->t_dval = dval;
- RETURN(TOK_NUMBER);
- }
-
- if (c == '"' || c == '\'') {
- int32 val, qc = c;
-
- INIT_TOKENBUF(&ts->tokenbuf);
- while ((c = GetChar(ts)) != qc) {
- if (c == '\n' || c == EOF) {
- UngetChar(ts, c);
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_UNTERMINATED_STRING);
- RETURN(TOK_ERROR);
- }
- if (c == '\\') {
- switch (c = GetChar(ts)) {
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
-
- default:
- if ('0' <= c && c < '8') {
- val = JS7_UNDEC(c);
- c = PeekChar(ts);
- if ('0' <= c && c < '8') {
- val = 8 * val + JS7_UNDEC(c);
- GetChar(ts);
- c = PeekChar(ts);
- if ('0' <= c && c < '8') {
- int32 save = val;
- val = 8 * val + JS7_UNDEC(c);
- if (val <= 0377)
- GetChar(ts);
- else
- val = save;
- }
- }
- c = (jschar)val;
- } else if (c == 'u') {
- jschar cp[4];
- if (PeekChars(ts, 4, cp) &&
- JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) &&
- JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) {
- c = (((((JS7_UNHEX(cp[0]) << 4)
- + JS7_UNHEX(cp[1])) << 4)
- + JS7_UNHEX(cp[2])) << 4)
- + JS7_UNHEX(cp[3]);
- SkipChars(ts, 4);
- }
- } else if (c == 'x') {
- jschar cp[2];
- if (PeekChars(ts, 2, cp) &&
- JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) {
- c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]);
- SkipChars(ts, 2);
- }
- } else if (c == '\n' && JSVERSION_IS_ECMA(cx->version)) {
- /* ECMA follows C by removing escaped newlines. */
- continue;
- }
- break;
- }
- }
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- }
- FINISH_TOKENBUF(&ts->tokenbuf);
- atom = js_AtomizeChars(cx,
- ts->tokenbuf.base,
- TOKEN_LENGTH(&ts->tokenbuf),
- 0);
- if (!atom)
- RETURN(TOK_ERROR);
- tp->pos.end.lineno = (uint16)ts->lineno;
- tp->t_op = JSOP_STRING;
- tp->t_atom = atom;
- RETURN(TOK_STRING);
- }
-
- switch (c) {
- case '\n':
- c = TOK_EOL;
- break;
-
- case ';': c = TOK_SEMI; break;
- case '.': c = TOK_DOT; break;
- case '[': c = TOK_LB; break;
- case ']': c = TOK_RB; break;
- case '{': c = TOK_LC; break;
- case '}': c = TOK_RC; break;
- case '(': c = TOK_LP; break;
- case ')': c = TOK_RP; break;
- case ',': c = TOK_COMMA; break;
- case '?': c = TOK_HOOK; break;
-
- case ':':
- /*
- * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an
- * object initializer, likewise for setter.
- */
- tp->t_op = JSOP_NOP;
- c = TOK_COLON;
- break;
-
- case '|':
- if (MatchChar(ts, c)) {
- c = TOK_OR;
- } else if (MatchChar(ts, '=')) {
- tp->t_op = JSOP_BITOR;
- c = TOK_ASSIGN;
- } else {
- c = TOK_BITOR;
- }
- break;
-
- case '^':
- if (MatchChar(ts, '=')) {
- tp->t_op = JSOP_BITXOR;
- c = TOK_ASSIGN;
- } else {
- c = TOK_BITXOR;
- }
- break;
-
- case '&':
- if (MatchChar(ts, c)) {
- c = TOK_AND;
- } else if (MatchChar(ts, '=')) {
- tp->t_op = JSOP_BITAND;
- c = TOK_ASSIGN;
- } else {
- c = TOK_BITAND;
- }
- break;
-
- case '=':
- if (MatchChar(ts, c)) {
-#if JS_HAS_TRIPLE_EQOPS
- tp->t_op = MatchChar(ts, c) ? JSOP_NEW_EQ : (JSOp)cx->jsop_eq;
-#else
- tp->t_op = cx->jsop_eq;
-#endif
- c = TOK_EQOP;
- } else {
- tp->t_op = JSOP_NOP;
- c = TOK_ASSIGN;
- }
- break;
-
- case '!':
- if (MatchChar(ts, '=')) {
-#if JS_HAS_TRIPLE_EQOPS
- tp->t_op = MatchChar(ts, '=') ? JSOP_NEW_NE : (JSOp)cx->jsop_ne;
-#else
- tp->t_op = cx->jsop_ne;
-#endif
- c = TOK_EQOP;
- } else {
- tp->t_op = JSOP_NOT;
- c = TOK_UNARYOP;
- }
- break;
-
- case '<':
- /* NB: treat HTML begin-comment as comment-till-end-of-line */
- if (MatchChar(ts, '!')) {
- if (MatchChar(ts, '-')) {
- if (MatchChar(ts, '-'))
- goto skipline;
- UngetChar(ts, '-');
- }
- UngetChar(ts, '!');
- }
- if (MatchChar(ts, c)) {
- tp->t_op = JSOP_LSH;
- c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
- } else {
- tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT;
- c = TOK_RELOP;
- }
- break;
-
- case '>':
- if (MatchChar(ts, c)) {
- tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH;
- c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
- } else {
- tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT;
- c = TOK_RELOP;
- }
- break;
-
- case '*':
- tp->t_op = JSOP_MUL;
- c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR;
- break;
-
- case '/':
- if (MatchChar(ts, '/')) {
-skipline:
- while ((c = GetChar(ts)) != EOF && c != '\n')
- /* skip to end of line */;
- UngetChar(ts, c);
- goto retry;
- }
- if (MatchChar(ts, '*')) {
- while ((c = GetChar(ts)) != EOF &&
- !(c == '*' && MatchChar(ts, '/'))) {
- /* Ignore all characters until comment close. */
- }
- if (c == EOF) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_UNTERMINATED_COMMENT);
- RETURN(TOK_ERROR);
- }
- goto retry;
- }
-
-#if JS_HAS_REGEXPS
- if (ts->flags & TSF_REGEXP) {
- JSObject *obj;
- uintN flags;
-
- INIT_TOKENBUF(&ts->tokenbuf);
- while ((c = GetChar(ts)) != '/') {
- if (c == '\n' || c == EOF) {
- UngetChar(ts, c);
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_UNTERMINATED_REGEXP);
- RETURN(TOK_ERROR);
- }
- if (c == '\\') {
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- c = GetChar(ts);
- }
- if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c))
- RETURN(TOK_ERROR);
- }
- FINISH_TOKENBUF(&ts->tokenbuf);
- for (flags = 0; ; ) {
- if (MatchChar(ts, 'g'))
- flags |= JSREG_GLOB;
- else if (MatchChar(ts, 'i'))
- flags |= JSREG_FOLD;
- else if (MatchChar(ts, 'm'))
- flags |= JSREG_MULTILINE;
- else
- break;
- }
- c = PeekChar(ts);
- if (JS7_ISLET(c)) {
- tp->ptr = ts->linebuf.ptr - 1;
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_BAD_REGEXP_FLAG);
- (void) GetChar(ts);
- RETURN(TOK_ERROR);
- }
- obj = js_NewRegExpObject(cx, ts,
- ts->tokenbuf.base,
- TOKEN_LENGTH(&ts->tokenbuf),
- flags);
- if (!obj)
- RETURN(TOK_ERROR);
- atom = js_AtomizeObject(cx, obj, 0);
- if (!atom)
- RETURN(TOK_ERROR);
- tp->t_op = JSOP_OBJECT;
- tp->t_atom = atom;
- RETURN(TOK_OBJECT);
- }
-#endif /* JS_HAS_REGEXPS */
-
- tp->t_op = JSOP_DIV;
- c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
- break;
-
- case '%':
- tp->t_op = JSOP_MOD;
- c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
- break;
-
- case '~':
- tp->t_op = JSOP_BITNOT;
- c = TOK_UNARYOP;
- break;
-
- case '+':
- if (MatchChar(ts, '=')) {
- tp->t_op = JSOP_ADD;
- c = TOK_ASSIGN;
- } else if (MatchChar(ts, c)) {
- c = TOK_INC;
- } else {
- tp->t_op = JSOP_POS;
- c = TOK_PLUS;
- }
- break;
-
- case '-':
- if (MatchChar(ts, '=')) {
- tp->t_op = JSOP_SUB;
- c = TOK_ASSIGN;
- } else if (MatchChar(ts, c)) {
- if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE))
- goto skipline;
- c = TOK_DEC;
- } else {
- tp->t_op = JSOP_NEG;
- c = TOK_MINUS;
- }
- ts->flags |= TSF_DIRTYLINE;
- break;
-
-#if JS_HAS_SHARP_VARS
- case '#':
- {
- uint32 n;
-
- c = GetChar(ts);
- if (!JS7_ISDEC(c)) {
- UngetChar(ts, c);
- goto badchar;
- }
- n = (uint32)JS7_UNDEC(c);
- for (;;) {
- c = GetChar(ts);
- if (!JS7_ISDEC(c))
- break;
- n = 10 * n + JS7_UNDEC(c);
- if (n >= ATOM_INDEX_LIMIT) {
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_SHARPVAR_TOO_BIG);
- RETURN(TOK_ERROR);
- }
- }
- tp->t_dval = (jsdouble) n;
- if (JS_HAS_STRICT_OPTION(cx) &&
- (c == '=' || c == '#')) {
- char buf[20];
- JS_snprintf(buf, sizeof buf, "#%u%c", n, c);
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
- JSREPORT_WARNING |
- JSREPORT_STRICT,
- JSMSG_DEPRECATED_USAGE,
- buf)) {
- RETURN(TOK_ERROR);
- }
- }
- if (c == '=')
- RETURN(TOK_DEFSHARP);
- if (c == '#')
- RETURN(TOK_USESHARP);
- goto badchar;
- }
-
- badchar:
-#endif /* JS_HAS_SHARP_VARS */
-
- default:
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
- JSMSG_ILLEGAL_CHARACTER);
- RETURN(TOK_ERROR);
- }
-
- JS_ASSERT(c < TOK_LIMIT);
- RETURN((JSTokenType)c);
-
-#undef INIT_TOKENBUF
-#undef FINISH_TOKENBUF
-#undef TOKEN_LENGTH
-#undef RETURN
-}
-
-void
-js_UngetToken(JSTokenStream *ts)
-{
- JS_ASSERT(ts->lookahead < NTOKENS_MASK);
- if (ts->flags & TSF_ERROR)
- return;
- ts->lookahead++;
- ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
-}
-
-JSBool
-js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
-{
- if (js_GetToken(cx, ts) == tt)
- return JS_TRUE;
- js_UngetToken(ts);
- return JS_FALSE;
-}
diff --git a/src/extension/script/js/jsscan.h b/src/extension/script/js/jsscan.h
deleted file mode 100644
index c61eff926..000000000
--- a/src/extension/script/js/jsscan.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsscan_h___
-#define jsscan_h___
-/*
- * JS lexical scanner interface.
- */
-#include <stddef.h>
-#include <stdio.h>
-#include "jsopcode.h"
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-JS_BEGIN_EXTERN_C
-
-typedef enum JSTokenType {
- TOK_ERROR = -1, /* well-known as the only code < EOF */
- TOK_EOF = 0, /* end of file */
- TOK_EOL = 1, /* end of line */
- TOK_SEMI = 2, /* semicolon */
- TOK_COMMA = 3, /* comma operator */
- TOK_ASSIGN = 4, /* assignment ops (= += -= etc.) */
- TOK_HOOK = 5, TOK_COLON = 6, /* conditional (?:) */
- TOK_OR = 7, /* logical or (||) */
- TOK_AND = 8, /* logical and (&&) */
- TOK_BITOR = 9, /* bitwise-or (|) */
- TOK_BITXOR = 10, /* bitwise-xor (^) */
- TOK_BITAND = 11, /* bitwise-and (&) */
- TOK_EQOP = 12, /* equality ops (== !=) */
- TOK_RELOP = 13, /* relational ops (< <= > >=) */
- TOK_SHOP = 14, /* shift ops (<< >> >>>) */
- TOK_PLUS = 15, /* plus */
- TOK_MINUS = 16, /* minus */
- TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */
- TOK_UNARYOP = 19, /* unary prefix operator */
- TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */
- TOK_DOT = 22, /* member operator (.) */
- TOK_LB = 23, TOK_RB = 24, /* left and right brackets */
- TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */
- TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */
- TOK_NAME = 29, /* identifier */
- TOK_NUMBER = 30, /* numeric constant */
- TOK_STRING = 31, /* string constant */
- TOK_OBJECT = 32, /* RegExp or other object constant */
- TOK_PRIMARY = 33, /* true, false, null, this, super */
- TOK_FUNCTION = 34, /* function keyword */
- TOK_EXPORT = 35, /* export keyword */
- TOK_IMPORT = 36, /* import keyword */
- TOK_IF = 37, /* if keyword */
- TOK_ELSE = 38, /* else keyword */
- TOK_SWITCH = 39, /* switch keyword */
- TOK_CASE = 40, /* case keyword */
- TOK_DEFAULT = 41, /* default keyword */
- TOK_WHILE = 42, /* while keyword */
- TOK_DO = 43, /* do keyword */
- TOK_FOR = 44, /* for keyword */
- TOK_BREAK = 45, /* break keyword */
- TOK_CONTINUE = 46, /* continue keyword */
- TOK_IN = 47, /* in keyword */
- TOK_VAR = 48, /* var keyword */
- TOK_WITH = 49, /* with keyword */
- TOK_RETURN = 50, /* return keyword */
- TOK_NEW = 51, /* new keyword */
- TOK_DELETE = 52, /* delete keyword */
- TOK_DEFSHARP = 53, /* #n= for object/array initializers */
- TOK_USESHARP = 54, /* #n# for object/array initializers */
- TOK_TRY = 55, /* try keyword */
- TOK_CATCH = 56, /* catch keyword */
- TOK_FINALLY = 57, /* finally keyword */
- TOK_THROW = 58, /* throw keyword */
- TOK_INSTANCEOF = 59, /* instanceof keyword */
- TOK_DEBUGGER = 60, /* debugger keyword */
- TOK_RESERVED, /* reserved keywords */
- TOK_LIMIT /* domain size */
-} JSTokenType;
-
-#define IS_PRIMARY_TOKEN(tt) \
- ((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME))
-
-struct JSTokenPtr {
- uint16 index; /* index of char in physical line */
- uint16 lineno; /* physical line number */
-};
-
-struct JSTokenPos {
- JSTokenPtr begin; /* first character and line of token */
- JSTokenPtr end; /* index 1 past last char, last line */
-};
-
-struct JSToken {
- JSTokenType type; /* char value or above enumerator */
- JSTokenPos pos; /* token position in file */
- jschar *ptr; /* beginning of token in line buffer */
- union {
- struct {
- JSOp op; /* operator, for minimal parser */
- JSAtom *atom; /* atom table entry */
- } s;
- jsdouble dval; /* floating point number */
- } u;
-};
-
-#define t_op u.s.op
-#define t_atom u.s.atom
-#define t_dval u.dval
-
-typedef struct JSTokenBuf {
- jschar *base; /* base of line or stream buffer */
- jschar *limit; /* limit for quick bounds check */
- jschar *ptr; /* next char to get, or slot to use */
-} JSTokenBuf;
-
-#define JS_LINE_LIMIT 256 /* logical line buffer size limit --
- physical line length is unlimited */
-#define NTOKENS 4 /* 1 current + 2 lookahead, rounded */
-#define NTOKENS_MASK (NTOKENS-1) /* to power of 2 to avoid divmod by 3 */
-
-struct JSTokenStream {
- JSToken tokens[NTOKENS];/* circular token buffer */
- uintN cursor; /* index of last parsed token */
- uintN lookahead; /* count of lookahead tokens */
- uintN lineno; /* current line number */
- uintN ungetpos; /* next free char slot in ungetbuf */
- jschar ungetbuf[6]; /* at most 6, for \uXXXX lookahead */
- uintN flags; /* flags -- see below */
- ptrdiff_t linelen; /* physical linebuf segment length */
- ptrdiff_t linepos; /* linebuf offset in physical line */
- JSTokenBuf linebuf; /* line buffer for diagnostics */
- JSTokenBuf userbuf; /* user input buffer if !file */
- JSTokenBuf tokenbuf; /* current token string buffer */
- const char *filename; /* input filename or null */
- FILE *file; /* stdio stream if reading from file */
- JSPrincipals *principals; /* principals associated with source */
- JSSourceHandler listener; /* callback for source; eg debugger */
- void *listenerData; /* listener 'this' data */
- void *listenerTSData;/* listener data for this TokenStream */
-};
-
-#define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor])
-#define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno)
-
-/* JSTokenStream flags */
-#define TSF_ERROR 0x01 /* fatal error while compiling */
-#define TSF_EOF 0x02 /* hit end of file */
-#define TSF_NEWLINES 0x04 /* tokenize newlines */
-#define TSF_REGEXP 0x08 /* looking for a regular expression */
-#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */
-#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */
-#define TSF_DIRTYLINE 0x80 /* stuff other than whitespace since start of line */
-
-/* Unicode separators that are treated as line terminators, in addition to \n, \r */
-#define LINE_SEPARATOR 0x2028
-#define PARA_SEPARATOR 0x2029
-
-/*
- * Create a new token stream, either from an input buffer or from a file.
- * Return null on file-open or memory-allocation failure.
- *
- * NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient
- * memory in the current context's temp pool. This memory is deallocated via
- * JS_ARENA_RELEASE() after parsing is finished.
- */
-extern JSTokenStream *
-js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
- const char *filename, uintN lineno, JSPrincipals *principals);
-
-extern JS_FRIEND_API(JSTokenStream *)
-js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length);
-
-extern JS_FRIEND_API(JSTokenStream *)
-js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
-
-extern JS_FRIEND_API(JSBool)
-js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
-
-/*
- * Initialize the scanner, installing JS keywords into cx's global scope.
- */
-extern JSBool
-js_InitScanner(JSContext *cx);
-
-/*
- * Friend-exported API entry point to call a mapping function on each reserved
- * identifier in the scanner's keyword table.
- */
-extern JS_FRIEND_API(void)
-js_MapKeywords(void (*mapfun)(const char *));
-
-/*
- * Report a compile-time error by its number, using ts or cg to show context.
- * Return true for a warning, false for an error.
- */
-extern JSBool
-js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts,
- JSCodeGenerator *cg, uintN flags,
- const uintN errorNumber, ...);
-
-/*
- * Look ahead one token and return its type.
- */
-extern JSTokenType
-js_PeekToken(JSContext *cx, JSTokenStream *ts);
-
-extern JSTokenType
-js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts);
-
-/*
- * Get the next token from ts.
- */
-extern JSTokenType
-js_GetToken(JSContext *cx, JSTokenStream *ts);
-
-/*
- * Push back the last scanned token onto ts.
- */
-extern void
-js_UngetToken(JSTokenStream *ts);
-
-/*
- * Get the next token from ts if its type is tt.
- */
-extern JSBool
-js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt);
-
-JS_END_EXTERN_C
-
-#endif /* jsscan_h___ */
diff --git a/src/extension/script/js/jsscope.c b/src/extension/script/js/jsscope.c
deleted file mode 100644
index 20243e9b7..000000000
--- a/src/extension/script/js/jsscope.c
+++ /dev/null
@@ -1,1581 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS symbol tables.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsarena.h"
-#include "jsbit.h"
-#include "jsclist.h"
-#include "jsdhash.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsdbgapi.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsscope.h"
-#include "jsstr.h"
-
-JSScope *
-js_GetMutableScope(JSContext *cx, JSObject *obj)
-{
- JSScope *scope, *newscope;
-
- scope = OBJ_SCOPE(obj);
- JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
- if (scope->object == obj)
- return scope;
- newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj),
- obj);
- if (!newscope)
- return NULL;
- JS_LOCK_SCOPE(cx, newscope);
- obj->map = js_HoldObjectMap(cx, &newscope->map);
- scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj);
- JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
- return newscope;
-}
-
-/*
- * JSScope uses multiplicative hashing, _a la_ jsdhash.[ch], but specialized
- * to minimize footprint. But if a scope has fewer than SCOPE_HASH_THRESHOLD
- * entries, we use linear search and avoid allocating scope->table.
- */
-#define SCOPE_HASH_THRESHOLD 6
-#define MIN_SCOPE_SIZE_LOG2 4
-#define MIN_SCOPE_SIZE JS_BIT(MIN_SCOPE_SIZE_LOG2)
-#define SCOPE_TABLE_NBYTES(n) ((n) * sizeof(JSScopeProperty *))
-
-static void
-InitMinimalScope(JSScope *scope)
-{
- scope->hashShift = JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2;
- scope->entryCount = scope->removedCount = 0;
- scope->table = NULL;
- scope->lastProp = NULL;
-}
-
-static JSBool
-CreateScopeTable(JSScope *scope)
-{
- int sizeLog2;
- JSScopeProperty *sprop, **spp;
-
- JS_ASSERT(!scope->table);
- JS_ASSERT(scope->lastProp);
-
- if (scope->entryCount > SCOPE_HASH_THRESHOLD) {
- /*
- * Ouch: calloc failed at least once already -- let's try again,
- * overallocating to hold at least twice the current population.
- */
- sizeLog2 = JS_CeilingLog2(2 * scope->entryCount);
- scope->hashShift = JS_DHASH_BITS - sizeLog2;
- } else {
- JS_ASSERT(scope->hashShift == JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2);
- sizeLog2 = MIN_SCOPE_SIZE_LOG2;
- }
-
- scope->table = (JSScopeProperty **)
- calloc(JS_BIT(sizeLog2), sizeof(JSScopeProperty *));
- if (!scope->table)
- return JS_FALSE;
-
- scope->hashShift = JS_DHASH_BITS - sizeLog2;
- for (sprop = scope->lastProp; sprop; sprop = sprop->parent) {
- spp = js_SearchScope(scope, sprop->id, JS_TRUE);
- SPROP_STORE_PRESERVING_COLLISION(spp, sprop);
- }
- return JS_TRUE;
-}
-
-JSScope *
-js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
- JSObject *obj)
-{
- JSScope *scope;
-
- scope = (JSScope *) JS_malloc(cx, sizeof(JSScope));
- if (!scope)
- return NULL;
-
- js_InitObjectMap(&scope->map, nrefs, ops, clasp);
- scope->object = obj;
- scope->flags = 0;
- InitMinimalScope(scope);
-
-#ifdef JS_THREADSAFE
- scope->ownercx = cx;
- memset(&scope->lock, 0, sizeof scope->lock);
-
- /*
- * Set u.link = NULL, not u.count = 0, in case the target architecture's
- * null pointer has a non-zero integer representation.
- */
- scope->u.link = NULL;
-
-#ifdef DEBUG
- scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL;
- scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0;
-#endif
-#endif
-
- JS_RUNTIME_METER(cx->runtime, liveScopes);
- JS_RUNTIME_METER(cx->runtime, totalScopes);
- return scope;
-}
-
-#ifdef DEBUG_SCOPE_COUNT
-extern void
-js_unlog_scope(JSScope *scope);
-#endif
-
-void
-js_DestroyScope(JSContext *cx, JSScope *scope)
-{
-#ifdef DEBUG_SCOPE_COUNT
- js_unlog_scope(scope);
-#endif
-
-#ifdef JS_THREADSAFE
- /* Scope must be single-threaded at this point, so set scope->ownercx. */
- JS_ASSERT(scope->u.count == 0);
- scope->ownercx = cx;
- js_FinishLock(&scope->lock);
-#endif
- if (scope->table)
- JS_free(cx, scope->table);
-
-#ifdef DEBUG
- JS_LOCK_RUNTIME_VOID(cx->runtime,
- cx->runtime->liveScopeProps -= scope->entryCount);
-#endif
- JS_RUNTIME_UNMETER(cx->runtime, liveScopes);
- JS_free(cx, scope);
-}
-
-#ifdef DEBUG_brendan
-typedef struct JSScopeStats {
- jsrefcount searches;
- jsrefcount steps;
- jsrefcount hits;
- jsrefcount misses;
- jsrefcount stepHits;
- jsrefcount stepMisses;
- jsrefcount adds;
- jsrefcount redundantAdds;
- jsrefcount addFailures;
- jsrefcount changeFailures;
- jsrefcount compresses;
- jsrefcount grows;
- jsrefcount removes;
- jsrefcount removeFrees;
- jsrefcount uselessRemoves;
- jsrefcount shrinks;
-} JSScopeStats;
-
-JS_FRIEND_DATA(JSScopeStats) js_scope_stats;
-
-# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x)
-#else
-# define METER(x) /* nothing */
-#endif
-
-/*
- * Double hashing needs the second hash code to be relatively prime to table
- * size, so we simply make hash2 odd. The inputs to multiplicative hash are
- * the golden ratio, expressed as a fixed-point 32 bit fraction, and the int
- * property index or named property's atom number (observe that most objects
- * have either no indexed properties, or almost all indexed and a few names,
- * so collisions between index and atom number are unlikely).
- */
-#define SCOPE_HASH0(id) (HASH_ID(id) * JS_GOLDEN_RATIO)
-#define SCOPE_HASH1(hash0,shift) ((hash0) >> (shift))
-#define SCOPE_HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1)
-
-JS_FRIEND_API(JSScopeProperty **)
-js_SearchScope(JSScope *scope, jsid id, JSBool adding)
-{
- JSHashNumber hash0, hash1, hash2;
- int hashShift, sizeLog2;
- JSScopeProperty *stored, *sprop, **spp, **firstRemoved;
- uint32 sizeMask;
-
- METER(searches);
- if (!scope->table) {
- /* Not enough properties to justify hashing: search from lastProp. */
- JS_ASSERT(!SCOPE_HAD_MIDDLE_DELETE(scope));
- for (spp = &scope->lastProp; (sprop = *spp); spp = &sprop->parent) {
- if (sprop->id == id) {
- METER(hits);
- return spp;
- }
- }
- METER(misses);
- return spp;
- }
-
- /* Compute the primary hash address. */
- hash0 = SCOPE_HASH0(id);
- hashShift = scope->hashShift;
- hash1 = SCOPE_HASH1(hash0, hashShift);
- spp = scope->table + hash1;
-
- /* Miss: return space for a new entry. */
- stored = *spp;
- if (SPROP_IS_FREE(stored)) {
- METER(misses);
- return spp;
- }
-
- /* Hit: return entry. */
- sprop = SPROP_CLEAR_COLLISION(stored);
- if (sprop && sprop->id == id) {
- METER(hits);
- return spp;
- }
-
- /* Collision: double hash. */
- sizeLog2 = JS_DHASH_BITS - hashShift;
- hash2 = SCOPE_HASH2(hash0, sizeLog2, hashShift);
- sizeMask = JS_BITMASK(sizeLog2);
-
- /* Save the first removed entry pointer so we can recycle it if adding. */
- if (SPROP_IS_REMOVED(stored)) {
- firstRemoved = spp;
- } else {
- firstRemoved = NULL;
- if (adding && !SPROP_HAD_COLLISION(stored))
- SPROP_FLAG_COLLISION(spp, sprop);
- }
-
- for (;;) {
- METER(steps);
- hash1 -= hash2;
- hash1 &= sizeMask;
- spp = scope->table + hash1;
-
- stored = *spp;
- if (SPROP_IS_FREE(stored)) {
- METER(stepMisses);
- return (adding && firstRemoved) ? firstRemoved : spp;
- }
-
- sprop = SPROP_CLEAR_COLLISION(stored);
- if (sprop && sprop->id == id) {
- METER(stepHits);
- return spp;
- }
-
- if (SPROP_IS_REMOVED(stored)) {
- if (!firstRemoved)
- firstRemoved = spp;
- } else {
- if (adding && !SPROP_HAD_COLLISION(stored))
- SPROP_FLAG_COLLISION(spp, sprop);
- }
- }
-
- /* NOTREACHED */
- return NULL;
-}
-
-static JSBool
-ChangeScope(JSContext *cx, JSScope *scope, int change)
-{
- int oldlog2, newlog2;
- uint32 oldsize, newsize, nbytes;
- JSScopeProperty **table, **oldtable, **spp, **oldspp, *sprop;
-
- /* Grow, shrink, or compress by changing scope->table. */
- oldlog2 = JS_DHASH_BITS - scope->hashShift;
- newlog2 = oldlog2 + change;
- oldsize = JS_BIT(oldlog2);
- newsize = JS_BIT(newlog2);
- nbytes = SCOPE_TABLE_NBYTES(newsize);
- table = (JSScopeProperty **) calloc(nbytes, 1);
- if (!table) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- /* Now that we have a new table allocated, update scope members. */
- scope->hashShift = JS_DHASH_BITS - newlog2;
- scope->removedCount = 0;
- oldtable = scope->table;
- scope->table = table;
-
- /* Copy only live entries, leaving removed and free ones behind. */
- for (oldspp = oldtable; oldsize != 0; oldspp++) {
- sprop = SPROP_FETCH(oldspp);
- if (sprop) {
- spp = js_SearchScope(scope, sprop->id, JS_TRUE);
- JS_ASSERT(SPROP_IS_FREE(*spp));
- *spp = sprop;
- }
- oldsize--;
- }
-
- /* Finally, free the old table storage. */
- JS_free(cx, oldtable);
- return JS_TRUE;
-}
-
-/*
- * Take care to exclude the mark and duplicate bits, in case we're called from
- * the GC, or we are searching for a property that has not yet been flagged as
- * a duplicate when making a duplicate formal parameter.
- */
-#define SPROP_FLAGS_NOT_MATCHED (SPROP_MARK | SPROP_IS_DUPLICATE)
-
-JS_STATIC_DLL_CALLBACK(JSDHashNumber)
-js_HashScopeProperty(JSDHashTable *table, const void *key)
-{
- const JSScopeProperty *sprop = (const JSScopeProperty *)key;
- JSDHashNumber hash;
- JSPropertyOp gsop;
-
- /* Accumulate from least to most random so the low bits are most random. */
- hash = 0;
- gsop = sprop->getter;
- if (gsop)
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;
- gsop = sprop->setter;
- if (gsop)
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;
-
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4)
- ^ (sprop->flags & ~SPROP_FLAGS_NOT_MATCHED);
-
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->attrs;
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->shortid;
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->slot;
- hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->id;
- return hash;
-}
-
-#define SPROP_MATCH(sprop, child) \
- SPROP_MATCH_PARAMS(sprop, (child)->id, (child)->getter, (child)->setter, \
- (child)->slot, (child)->attrs, (child)->flags, \
- (child)->shortid)
-
-#define SPROP_MATCH_PARAMS(sprop, aid, agetter, asetter, aslot, aattrs, \
- aflags, ashortid) \
- ((sprop)->id == (aid) && \
- SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \
- aflags, ashortid))
-
-#define SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \
- aflags, ashortid) \
- ((sprop)->getter == (agetter) && \
- (sprop)->setter == (asetter) && \
- (sprop)->slot == (aslot) && \
- (sprop)->attrs == (aattrs) && \
- (((sprop)->flags ^ (aflags)) & ~SPROP_FLAGS_NOT_MATCHED) == 0 && \
- (sprop)->shortid == (ashortid))
-
-JS_STATIC_DLL_CALLBACK(JSBool)
-js_MatchScopeProperty(JSDHashTable *table,
- const JSDHashEntryHdr *hdr,
- const void *key)
-{
- const JSPropertyTreeEntry *entry = (const JSPropertyTreeEntry *)hdr;
- const JSScopeProperty *sprop = entry->child;
- const JSScopeProperty *kprop = (const JSScopeProperty *)key;
-
- return SPROP_MATCH(sprop, kprop);
-}
-
-static const JSDHashTableOps PropertyTreeHashOps = {
- JS_DHashAllocTable,
- JS_DHashFreeTable,
- JS_DHashGetKeyStub,
- js_HashScopeProperty,
- js_MatchScopeProperty,
- JS_DHashMoveEntryStub,
- JS_DHashClearEntryStub,
- JS_DHashFinalizeStub,
- NULL
-};
-
-/*
- * A property tree node on rt->propertyFreeList overlays the following prefix
- * struct on JSScopeProperty.
- */
-typedef struct FreeNode {
- jsid id;
- JSScopeProperty *next;
- JSScopeProperty **prevp;
-} FreeNode;
-
-#define FREENODE(sprop) ((FreeNode *) (sprop))
-
-#define FREENODE_INSERT(list, sprop) \
- JS_BEGIN_MACRO \
- FREENODE(sprop)->next = (list); \
- FREENODE(sprop)->prevp = &(list); \
- if (list) \
- FREENODE(list)->prevp = &FREENODE(sprop)->next; \
- (list) = (sprop); \
- JS_END_MACRO
-
-#define FREENODE_REMOVE(sprop) \
- JS_BEGIN_MACRO \
- *FREENODE(sprop)->prevp = FREENODE(sprop)->next; \
- if (FREENODE(sprop)->next) \
- FREENODE(FREENODE(sprop)->next)->prevp = FREENODE(sprop)->prevp; \
- JS_END_MACRO
-
-/* NB: Called with the runtime lock held. */
-static JSScopeProperty *
-NewScopeProperty(JSRuntime *rt)
-{
- JSScopeProperty *sprop;
-
- sprop = rt->propertyFreeList;
- if (sprop) {
- FREENODE_REMOVE(sprop);
- } else {
- JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *,
- &rt->propertyArenaPool,
- sizeof(JSScopeProperty));
- if (!sprop)
- return NULL;
- }
-
- JS_RUNTIME_METER(rt, livePropTreeNodes);
- JS_RUNTIME_METER(rt, totalPropTreeNodes);
- return sprop;
-}
-
-#define CHUNKY_KIDS_TAG ((jsuword)1)
-#define KIDS_IS_CHUNKY(kids) ((jsuword)(kids) & CHUNKY_KIDS_TAG)
-#define KIDS_TO_CHUNK(kids) ((PropTreeKidsChunk *) \
- ((jsuword)(kids) & ~CHUNKY_KIDS_TAG))
-#define CHUNK_TO_KIDS(chunk) ((JSScopeProperty *) \
- ((jsuword)(chunk) | CHUNKY_KIDS_TAG))
-#define MAX_KIDS_PER_CHUNK 10
-
-typedef struct PropTreeKidsChunk PropTreeKidsChunk;
-
-struct PropTreeKidsChunk {
- JSScopeProperty *kids[MAX_KIDS_PER_CHUNK];
- PropTreeKidsChunk *next;
-};
-
-static PropTreeKidsChunk *
-NewPropTreeKidsChunk(JSRuntime *rt)
-{
- PropTreeKidsChunk *chunk;
-
- chunk = calloc(1, sizeof *chunk);
- if (!chunk)
- return NULL;
- JS_ASSERT(((jsuword)chunk & CHUNKY_KIDS_TAG) == 0);
- JS_RUNTIME_METER(rt, propTreeKidsChunks);
- return chunk;
-}
-
-static void
-DestroyPropTreeKidsChunk(JSRuntime *rt, PropTreeKidsChunk *chunk)
-{
- JS_RUNTIME_UNMETER(rt, propTreeKidsChunks);
- free(chunk);
-}
-
-/* NB: Called with the runtime lock held. */
-static JSBool
-InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent,
- JSScopeProperty *child)
-{
- JSPropertyTreeEntry *entry;
- JSScopeProperty **childp, *kids, *sprop;
- PropTreeKidsChunk *chunk, **chunkp;
- uintN i;
-
- JS_ASSERT(!parent || child->parent != parent);
-
- if (!parent) {
- entry = (JSPropertyTreeEntry *)
- JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD);
- if (!entry)
- return JS_FALSE;
- childp = &entry->child;
- sprop = *childp;
- if (!sprop) {
- *childp = child;
- } else {
- /*
- * A "Duplicate child" case.
- *
- * We can't do away with child, as at least one live scope entry
- * still points at it. What's more, that scope's lastProp chains
- * through an ancestor line to reach child, and js_Enumerate and
- * others count on this linkage. We must leave child out of the
- * hash table, and not require it to be there when we eventually
- * GC it (see RemovePropertyTreeChild, below).
- *
- * It is necessary to leave the duplicate child out of the hash
- * table to preserve entry uniqueness. It is safe to leave the
- * child out of the hash table (unlike the duplicate child cases
- * below), because the child's parent link will be null, which
- * can't dangle.
- */
- JS_ASSERT(sprop != child && SPROP_MATCH(sprop, child));
- JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
- }
- } else {
- childp = &parent->kids;
- kids = *childp;
- if (kids) {
- if (KIDS_IS_CHUNKY(kids)) {
- chunk = KIDS_TO_CHUNK(kids);
- do {
- for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
- childp = &chunk->kids[i];
- sprop = *childp;
- if (!sprop)
- goto insert;
-
- JS_ASSERT(sprop != child);
- if (SPROP_MATCH(sprop, child)) {
- /*
- * Duplicate child, see comment above. In this
- * case, we must let the duplicate be inserted at
- * this level in the tree, so we keep iterating,
- * looking for an empty slot in which to insert.
- */
- JS_ASSERT(sprop != child);
- JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
- }
- }
- chunkp = &chunk->next;
- } while ((chunk = *chunkp) != NULL);
-
- chunk = NewPropTreeKidsChunk(rt);
- if (!chunk)
- return JS_FALSE;
- *chunkp = chunk;
- childp = &chunk->kids[0];
- } else {
- sprop = kids;
- JS_ASSERT(sprop != child);
- if (SPROP_MATCH(sprop, child)) {
- /*
- * Duplicate child, see comment above. Once again, we
- * must let duplicates created by deletion pile up in a
- * kids-chunk-list, in order to find them when sweeping
- * and thereby avoid dangling parent pointers.
- */
- JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
- }
-
- chunk = NewPropTreeKidsChunk(rt);
- if (!chunk)
- return JS_FALSE;
- parent->kids = CHUNK_TO_KIDS(chunk);
- chunk->kids[0] = sprop;
- childp = &chunk->kids[1];
- }
- }
- insert:
- *childp = child;
- }
-
- child->parent = parent;
- return JS_TRUE;
-}
-
-/* NB: Called with the runtime lock held. */
-static void
-RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child)
-{
- JSPropertyTreeEntry *entry;
- JSScopeProperty *parent, *kids, *kid;
- PropTreeKidsChunk *list, *chunk, **chunkp, *lastChunk;
- uintN i, j;
-
- parent = child->parent;
- if (!parent) {
- /*
- * Don't remove child if it is not in rt->propertyTreeHash, but only
- * matches a root child in the table that has compatible members. See
- * the "Duplicate child" comments in InsertPropertyTreeChild, above.
- */
- entry = (JSPropertyTreeEntry *)
- JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_LOOKUP);
-
- if (entry->child == child)
- JS_DHashTableRawRemove(&rt->propertyTreeHash, &entry->hdr);
- } else {
- kids = parent->kids;
- if (KIDS_IS_CHUNKY(kids)) {
- list = chunk = KIDS_TO_CHUNK(kids);
- chunkp = &list;
-
- do {
- for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
- if (chunk->kids[i] == child) {
- lastChunk = chunk;
- if (!lastChunk->next) {
- j = i + 1;
- } else {
- j = 0;
- do {
- chunkp = &lastChunk->next;
- lastChunk = *chunkp;
- } while (lastChunk->next);
- }
- for (; j < MAX_KIDS_PER_CHUNK; j++) {
- if (!lastChunk->kids[j])
- break;
- }
- --j;
- if (chunk != lastChunk || j > i)
- chunk->kids[i] = lastChunk->kids[j];
- lastChunk->kids[j] = NULL;
- if (j == 0) {
- *chunkp = NULL;
- if (!list)
- parent->kids = NULL;
- DestroyPropTreeKidsChunk(rt, lastChunk);
- }
- return;
- }
- }
-
- chunkp = &chunk->next;
- } while ((chunk = *chunkp) != NULL);
- } else {
- kid = kids;
- if (kid == child)
- parent->kids = NULL;
- }
- }
-}
-
-/*
- * Called *without* the runtime lock held, this function acquires that lock
- * only when inserting a new child. Thus there may be races to find or add
- * a node that result in duplicates. We expect such races to be rare!
- */
-static JSScopeProperty *
-GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
- JSScopeProperty *child)
-{
- JSRuntime *rt;
- JSPropertyTreeEntry *entry;
- JSScopeProperty *sprop;
- PropTreeKidsChunk *chunk;
- uintN i;
-
- rt = cx->runtime;
- if (!parent) {
- JS_LOCK_RUNTIME(rt);
-
- entry = (JSPropertyTreeEntry *)
- JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD);
- if (!entry)
- goto out_of_memory;
-
- sprop = entry->child;
- if (sprop)
- goto out;
- } else {
- /*
- * Because chunks are appended at the end and never deleted except by
- * the GC, we can search without taking the runtime lock. We may miss
- * a matching sprop added by another thread, and make a duplicate one,
- * but that is an unlikely, therefore small, cost. The property tree
- * has extremely low fan-out below its root in popular embeddings with
- * real-world workloads.
- *
- * If workload changes so as to increase fan-out significantly below
- * the property tree root, we'll want to add another tag bit stored in
- * parent->kids that indicates a JSDHashTable pointer.
- */
- entry = NULL;
- sprop = parent->kids;
- if (sprop) {
- if (KIDS_IS_CHUNKY(sprop)) {
- chunk = KIDS_TO_CHUNK(sprop);
- do {
- for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
- sprop = chunk->kids[i];
- if (!sprop)
- goto not_found;
-
- if (SPROP_MATCH(sprop, child))
- return sprop;
- }
- } while ((chunk = chunk->next) != NULL);
- } else {
- if (SPROP_MATCH(sprop, child))
- return sprop;
- }
- }
-
- not_found:
- JS_LOCK_RUNTIME(rt);
- }
-
- sprop = NewScopeProperty(rt);
- if (!sprop)
- goto out_of_memory;
-
- sprop->id = child->id;
- sprop->getter = child->getter;
- sprop->setter = child->setter;
- sprop->slot = child->slot;
- sprop->attrs = child->attrs;
- sprop->flags = child->flags;
- sprop->shortid = child->shortid;
- sprop->parent = sprop->kids = NULL;
- if (!parent) {
- entry->child = sprop;
- } else {
- if (!InsertPropertyTreeChild(rt, parent, sprop))
- goto out_of_memory;
- }
-
-out:
- JS_UNLOCK_RUNTIME(rt);
- return sprop;
-
-out_of_memory:
- JS_UNLOCK_RUNTIME(rt);
- JS_ReportOutOfMemory(cx);
- return NULL;
-}
-
-#ifdef DEBUG_notbrendan
-#define CHECK_ANCESTOR_LINE(scope, sparse) \
- JS_BEGIN_MACRO \
- if ((scope)->table) CheckAncestorLine(scope, sparse); \
- JS_END_MACRO
-
-static void
-CheckAncestorLine(JSScope *scope, JSBool sparse)
-{
- uint32 size;
- JSScopeProperty **spp, **start, **end, *ancestorLine, *sprop, *aprop;
- uint32 entryCount, ancestorCount;
-
- ancestorLine = SCOPE_LAST_PROP(scope);
- if (ancestorLine)
- JS_ASSERT(SCOPE_HAS_PROPERTY(scope, ancestorLine));
-
- entryCount = 0;
- size = SCOPE_CAPACITY(scope);
- start = scope->table;
- for (spp = start, end = start + size; spp < end; spp++) {
- sprop = SPROP_FETCH(spp);
- if (sprop) {
- entryCount++;
- for (aprop = ancestorLine; aprop; aprop = aprop->parent) {
- if (aprop == sprop)
- break;
- }
- JS_ASSERT(aprop);
- }
- }
- JS_ASSERT(entryCount == scope->entryCount);
-
- ancestorCount = 0;
- for (sprop = ancestorLine; sprop; sprop = sprop->parent) {
- if (SCOPE_HAD_MIDDLE_DELETE(scope) &&
- !SCOPE_HAS_PROPERTY(scope, sprop)) {
- JS_ASSERT(sparse || (sprop->flags & SPROP_IS_DUPLICATE));
- continue;
- }
- ancestorCount++;
- }
- JS_ASSERT(ancestorCount == scope->entryCount);
-}
-#else
-#define CHECK_ANCESTOR_LINE(scope, sparse) /* nothing */
-#endif
-
-static void
-ReportReadOnlyScope(JSContext *cx, JSScope *scope)
-{
- JSString *str;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(scope->object));
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_READ_ONLY,
- str
- ? JS_GetStringBytes(str)
- : LOCKED_OBJ_GET_CLASS(scope->object)->name);
-}
-
-JSScopeProperty *
-js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
- JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
- uintN attrs, uintN flags, intN shortid)
-{
- JSScopeProperty **spp, *sprop, *overwriting, **spvec, **spp2, child;
- uint32 size, splen, i;
- int change;
-
- JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
-
- /*
- * You can't add properties to a sealed scope. But note well that you can
- * change property attributes in a sealed scope, even though that replaces
- * a JSScopeProperty * in the scope's hash table -- but no id is added, so
- * the scope remains sealed.
- */
- if (SCOPE_IS_SEALED(scope)) {
- ReportReadOnlyScope(cx, scope);
- return NULL;
- }
-
- /*
- * Normalize stub getter and setter values for faster is-stub testing in
- * the SPROP_CALL_[GS]ETTER macros.
- */
- if (getter == JS_PropertyStub)
- getter = NULL;
- if (setter == JS_PropertyStub)
- setter = NULL;
-
- /*
- * Search for id in order to claim its entry, allocating a property tree
- * node if one doesn't already exist for our parameters.
- */
- spp = js_SearchScope(scope, id, JS_TRUE);
- sprop = overwriting = SPROP_FETCH(spp);
- if (!sprop) {
- /* Check whether we need to grow, if the load factor is >= .75. */
- size = SCOPE_CAPACITY(scope);
- if (scope->entryCount + scope->removedCount >= size - (size >> 2)) {
- if (scope->removedCount >= size >> 2) {
- METER(compresses);
- change = 0;
- } else {
- METER(grows);
- change = 1;
- }
- if (!ChangeScope(cx, scope, change) &&
- scope->entryCount + scope->removedCount == size - 1) {
- METER(addFailures);
- return NULL;
- }
- spp = js_SearchScope(scope, id, JS_TRUE);
- JS_ASSERT(!SPROP_FETCH(spp));
- }
- } else {
- /* Property exists: js_SearchScope must have returned a valid entry. */
- JS_ASSERT(!SPROP_IS_REMOVED(*spp));
-
- /*
- * If all property members match, this is a redundant add and we can
- * return early. If the caller wants to allocate a slot, but doesn't
- * care which slot, copy sprop->slot into slot so we can match sprop,
- * if all other members match.
- */
- if (!(attrs & JSPROP_SHARED) &&
- slot == SPROP_INVALID_SLOT &&
- SPROP_HAS_VALID_SLOT(sprop, scope)) {
- slot = sprop->slot;
- }
- if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs,
- flags, shortid)) {
- METER(redundantAdds);
- return sprop;
- }
-
- /*
- * Duplicate formal parameters require us to leave the old property
- * on the ancestor line, so the decompiler can find it, even though
- * its entry in scope->table is overwritten to point at a new property
- * descending from the old one. The SPROP_IS_DUPLICATE flag helps us
- * cope with the consequent disparity between ancestor line height and
- * scope->entryCount.
- */
- if (flags & SPROP_IS_DUPLICATE) {
- sprop->flags |= SPROP_IS_DUPLICATE;
- } else {
- /*
- * If we are clearing sprop to force an existing property to be
- * overwritten (apart from a duplicate formal parameter), we must
- * unlink it from the ancestor line at scope->lastProp, lazily if
- * sprop is not lastProp. And we must remove the entry at *spp,
- * precisely so the lazy "middle delete" fixup code further below
- * won't find sprop in scope->table, in spite of sprop being on
- * the ancestor line.
- *
- * When we finally succeed in finding or creating a new sprop
- * and storing its pointer at *spp, we'll use the |overwriting|
- * local saved when we first looked up id to decide whether we're
- * indeed creating a new entry, or merely overwriting an existing
- * property.
- */
- if (sprop == SCOPE_LAST_PROP(scope)) {
- do {
- SCOPE_REMOVE_LAST_PROP(scope);
- if (!SCOPE_HAD_MIDDLE_DELETE(scope))
- break;
- sprop = SCOPE_LAST_PROP(scope);
- } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
- } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
- /*
- * If we have no hash table yet, we need one now. The middle
- * delete code is simple-minded that way!
- */
- if (!scope->table) {
- if (!CreateScopeTable(scope)) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- spp = js_SearchScope(scope, id, JS_TRUE);
- sprop = overwriting = SPROP_FETCH(spp);
- }
- SCOPE_SET_MIDDLE_DELETE(scope);
- }
- }
-
- /*
- * If we fail later on trying to find or create a new sprop, we will
- * goto fail_overwrite and restore *spp from |overwriting|. Note that
- * we don't bother to keep scope->removedCount in sync, because we'll
- * fix up *spp and scope->entryCount shortly, no matter how control
- * flow returns from this function.
- */
- if (scope->table)
- SPROP_STORE_PRESERVING_COLLISION(spp, NULL);
- scope->entryCount--;
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
- sprop = NULL;
- }
-
- if (!sprop) {
- /*
- * If properties were deleted from the middle of the list starting at
- * scope->lastProp, we may need to fork the property tree and squeeze
- * all deleted properties out of scope's ancestor line. Otherwise we
- * risk adding a node with the same id as a "middle" node, violating
- * the rule that properties along an ancestor line have distinct ids
- * (unless flagged SPROP_IS_DUPLICATE).
- */
- if (SCOPE_HAD_MIDDLE_DELETE(scope)) {
- JS_ASSERT(scope->table);
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
-
- splen = scope->entryCount;
- if (splen == 0) {
- JS_ASSERT(scope->lastProp == NULL);
- } else {
- /*
- * Enumerate live entries in scope->table using a temporary
- * vector, by walking the (possibly sparse, due to deletions)
- * ancestor line from scope->lastProp.
- */
- spvec = (JSScopeProperty **)
- JS_malloc(cx, SCOPE_TABLE_NBYTES(splen));
- if (!spvec)
- goto fail_overwrite;
- i = splen;
- sprop = SCOPE_LAST_PROP(scope);
- JS_ASSERT(sprop);
- do {
- /*
- * NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY --
- * the latter insists that sprop->id maps to sprop, while
- * the former simply tests whether sprop->id is bound in
- * scope. We must allow for duplicate formal parameters
- * along the ancestor line, and fork them as needed.
- */
- if (!SCOPE_GET_PROPERTY(scope, sprop->id))
- continue;
-
- JS_ASSERT(sprop != overwriting);
- if (i == 0) {
- /*
- * If our original splen estimate, scope->entryCount,
- * is less than the ancestor line height, there must
- * be duplicate formal parameters in this (function
- * object) scope. Count remaining ancestors in order
- * to realloc spvec.
- */
- JSScopeProperty *tmp = sprop;
- do {
- if (SCOPE_GET_PROPERTY(scope, tmp->id))
- i++;
- } while ((tmp = tmp->parent) != NULL);
- spp2 = (JSScopeProperty **)
- JS_realloc(cx, spvec, SCOPE_TABLE_NBYTES(splen+i));
- if (!spp2) {
- JS_free(cx, spvec);
- goto fail_overwrite;
- }
-
- spvec = spp2;
- memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen));
- splen += i;
- }
-
- spvec[--i] = sprop;
- } while ((sprop = sprop->parent) != NULL);
- JS_ASSERT(i == 0);
-
- /*
- * Now loop forward through spvec, forking the property tree
- * whenever we see a "parent gap" due to deletions from scope.
- * NB: sprop is null on first entry to the loop body.
- */
- do {
- if (spvec[i]->parent == sprop) {
- sprop = spvec[i];
- } else {
- sprop = GetPropertyTreeChild(cx, sprop, spvec[i]);
- if (!sprop) {
- JS_free(cx, spvec);
- goto fail_overwrite;
- }
-
- spp2 = js_SearchScope(scope, sprop->id, JS_FALSE);
- JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]);
- SPROP_STORE_PRESERVING_COLLISION(spp2, sprop);
- }
- } while (++i < splen);
- JS_free(cx, spvec);
-
- /*
- * Now sprop points to the last property in scope, where the
- * ancestor line from sprop to the root is dense w.r.t. scope:
- * it contains no nodes not mapped by scope->table, apart from
- * any stinking ECMA-mandated duplicate formal parameters.
- */
- scope->lastProp = sprop;
- CHECK_ANCESTOR_LINE(scope, JS_FALSE);
- JS_RUNTIME_METER(cx->runtime, middleDeleteFixups);
- }
-
- SCOPE_CLR_MIDDLE_DELETE(scope);
- }
-
- /*
- * Aliases share another property's slot, passed in the |slot| param.
- * Shared properties have no slot. Unshared properties that do not
- * alias another property's slot get one here, but may lose it due to
- * a JS_ClearScope call.
- */
- if (!(flags & SPROP_IS_ALIAS)) {
- if (attrs & JSPROP_SHARED) {
- slot = SPROP_INVALID_SLOT;
- } else {
- /*
- * We may have set slot from a nearly-matching sprop, above.
- * If so, we're overwriting that nearly-matching sprop, so we
- * can reuse its slot -- we don't need to allocate a new one.
- * Callers should therefore pass SPROP_INVALID_SLOT for all
- * non-alias, unshared property adds.
- */
- if (slot != SPROP_INVALID_SLOT)
- JS_ASSERT(overwriting);
- else if (!js_AllocSlot(cx, scope->object, &slot))
- goto fail_overwrite;
- }
- }
-
- /*
- * Check for a watchpoint on a deleted property; if one exists, change
- * setter to js_watch_set.
- * XXXbe this could get expensive with lots of watchpoints...
- */
- if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) &&
- js_FindWatchPoint(cx->runtime, scope, id)) {
- setter = js_WrapWatchedSetter(cx, id, attrs, setter);
- if (!setter)
- goto fail_overwrite;
- }
-
- /* Find or create a property tree node labeled by our arguments. */
- child.id = id;
- child.getter = getter;
- child.setter = setter;
- child.slot = slot;
- child.attrs = attrs;
- child.flags = flags;
- child.shortid = shortid;
- sprop = GetPropertyTreeChild(cx, scope->lastProp, &child);
- if (!sprop)
- goto fail_overwrite;
-
- /* Store the tree node pointer in the table entry for id. */
- if (scope->table)
- SPROP_STORE_PRESERVING_COLLISION(spp, sprop);
- scope->entryCount++;
- scope->lastProp = sprop;
- CHECK_ANCESTOR_LINE(scope, JS_FALSE);
- if (!overwriting) {
- JS_RUNTIME_METER(cx->runtime, liveScopeProps);
- JS_RUNTIME_METER(cx->runtime, totalScopeProps);
- }
-
- /*
- * If we reach the hashing threshold, try to allocate scope->table.
- * If we can't (a rare event, preceded by swapping to death on most
- * modern OSes), stick with linear search rather than whining about
- * this little set-back. Therefore we must test !scope->table and
- * scope->entryCount >= SCOPE_HASH_THRESHOLD, not merely whether the
- * entry count just reached the threshold.
- */
- if (!scope->table && scope->entryCount >= SCOPE_HASH_THRESHOLD)
- (void) CreateScopeTable(scope);
- }
-
- METER(adds);
- return sprop;
-
-fail_overwrite:
- if (overwriting) {
- /*
- * We may or may not have forked overwriting out of scope's ancestor
- * line, so we must check (the alternative is to set a flag above, but
- * that hurts the common, non-error case). If we did fork overwriting
- * out, we'll add it back at scope->lastProp. This means enumeration
- * order can change due to a failure to overwrite an id.
- * XXXbe very minor incompatibility
- */
- for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) {
- if (!sprop) {
- sprop = SCOPE_LAST_PROP(scope);
- if (overwriting->parent == sprop) {
- scope->lastProp = overwriting;
- } else {
- sprop = GetPropertyTreeChild(cx, sprop, overwriting);
- if (sprop) {
- JS_ASSERT(sprop != overwriting);
- scope->lastProp = sprop;
- }
- overwriting = sprop;
- }
- break;
- }
- if (sprop == overwriting)
- break;
- }
- if (overwriting) {
- if (scope->table)
- SPROP_STORE_PRESERVING_COLLISION(spp, overwriting);
- scope->entryCount++;
- }
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
- }
- METER(addFailures);
- return NULL;
-}
-
-JSScopeProperty *
-js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,
- JSScopeProperty *sprop, uintN attrs, uintN mask,
- JSPropertyOp getter, JSPropertyOp setter)
-{
- JSScopeProperty child, *newsprop, **spp;
-
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
-
- /* Allow only shared (slot-less) => unshared (slot-full) transition. */
- attrs |= sprop->attrs & mask;
- JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) ||
- !(attrs & JSPROP_SHARED));
- if (getter == JS_PropertyStub)
- getter = NULL;
- if (setter == JS_PropertyStub)
- setter = NULL;
- if (sprop->attrs == attrs &&
- sprop->getter == getter &&
- sprop->setter == setter) {
- return sprop;
- }
-
- child.id = sprop->id;
- child.getter = getter;
- child.setter = setter;
- child.slot = sprop->slot;
- child.attrs = attrs;
- child.flags = sprop->flags;
- child.shortid = sprop->shortid;
-
- if (SCOPE_LAST_PROP(scope) == sprop) {
- /*
- * Optimize the case where the last property added to scope is changed
- * to have a different attrs, getter, or setter. In the last property
- * case, we need not fork the property tree. But since we do not call
- * js_AddScopeProperty, we may need to allocate a new slot directly.
- */
- if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) {
- JS_ASSERT(child.slot == SPROP_INVALID_SLOT);
- if (!js_AllocSlot(cx, scope->object, &child.slot))
- return NULL;
- }
-
- newsprop = GetPropertyTreeChild(cx, sprop->parent, &child);
- if (newsprop) {
- spp = js_SearchScope(scope, sprop->id, JS_FALSE);
- JS_ASSERT(SPROP_FETCH(spp) == sprop);
-
- if (scope->table)
- SPROP_STORE_PRESERVING_COLLISION(spp, newsprop);
- scope->lastProp = newsprop;
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
- }
- } else {
- /*
- * Let js_AddScopeProperty handle this |overwriting| case, including
- * the conservation of sprop->slot (if it's valid). We must not call
- * js_RemoveScopeProperty here, it will free a valid sprop->slot and
- * js_AddScopeProperty won't re-allocate it.
- */
- newsprop = js_AddScopeProperty(cx, scope, child.id,
- child.getter, child.setter, child.slot,
- child.attrs, child.flags, child.shortid);
- }
-
-#ifdef DEBUG_brendan
- if (!newsprop)
- METER(changeFailures);
-#endif
- return newsprop;
-}
-
-JSBool
-js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id)
-{
- JSScopeProperty **spp, *stored, *sprop;
- uint32 size;
-
- JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
- if (SCOPE_IS_SEALED(scope)) {
- ReportReadOnlyScope(cx, scope);
- return JS_FALSE;
- }
- METER(removes);
-
- spp = js_SearchScope(scope, id, JS_FALSE);
- stored = *spp;
- sprop = SPROP_CLEAR_COLLISION(stored);
- if (!sprop) {
- METER(uselessRemoves);
- return JS_TRUE;
- }
-
- /* Convert from a list to a hash so we can handle "middle deletes". */
- if (!scope->table && sprop != scope->lastProp) {
- if (!CreateScopeTable(scope)) {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
- spp = js_SearchScope(scope, id, JS_FALSE);
- stored = *spp;
- sprop = SPROP_CLEAR_COLLISION(stored);
- }
-
- /* First, if sprop is unshared and not cleared, free its slot number. */
- if (SPROP_HAS_VALID_SLOT(sprop, scope))
- js_FreeSlot(cx, scope->object, sprop->slot);
-
- /* Next, remove id by setting its entry to a removed or free sentinel. */
- if (SPROP_HAD_COLLISION(stored)) {
- JS_ASSERT(scope->table);
- *spp = SPROP_REMOVED;
- scope->removedCount++;
- } else {
- METER(removeFrees);
- if (scope->table)
- *spp = NULL;
- }
- scope->entryCount--;
- JS_RUNTIME_UNMETER(cx->runtime, liveScopeProps);
-
- /* Update scope->lastProp directly, or set its deferred update flag. */
- if (sprop == SCOPE_LAST_PROP(scope)) {
- do {
- SCOPE_REMOVE_LAST_PROP(scope);
- if (!SCOPE_HAD_MIDDLE_DELETE(scope))
- break;
- sprop = SCOPE_LAST_PROP(scope);
- } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
- } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
- SCOPE_SET_MIDDLE_DELETE(scope);
- }
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
-
- /* Last, consider shrinking scope's table if its load factor is <= .25. */
- size = SCOPE_CAPACITY(scope);
- if (size > MIN_SCOPE_SIZE && scope->entryCount <= size >> 2) {
- METER(shrinks);
- (void) ChangeScope(cx, scope, -1);
- }
-
- return JS_TRUE;
-}
-
-void
-js_ClearScope(JSContext *cx, JSScope *scope)
-{
- CHECK_ANCESTOR_LINE(scope, JS_TRUE);
-#ifdef DEBUG
- JS_LOCK_RUNTIME_VOID(cx->runtime,
- cx->runtime->liveScopeProps -= scope->entryCount);
-#endif
-
- if (scope->table)
- free(scope->table);
- SCOPE_CLR_MIDDLE_DELETE(scope);
- InitMinimalScope(scope);
-}
-
-#ifdef DEBUG_brendan
-
-#include <stdio.h>
-#include <math.h>
-
-uint32 js_nkids_max;
-uint32 js_nkids_sum;
-double js_nkids_sqsum;
-uint32 js_nkids_hist[11];
-
-static void
-MeterKidCount(uintN nkids)
-{
- if (nkids) {
- js_nkids_sum += nkids;
- js_nkids_sqsum += (double)nkids * nkids;
- if (nkids > js_nkids_max)
- js_nkids_max = nkids;
- }
- js_nkids_hist[JS_MIN(nkids, 10)]++;
-}
-
-static void
-MeterPropertyTree(JSScopeProperty *node)
-{
- uintN i, nkids;
- JSScopeProperty *kids, *kid;
- PropTreeKidsChunk *chunk;
-
- nkids = 0;
- kids = node->kids;
- if (kids) {
- if (KIDS_IS_CHUNKY(kids)) {
- for (chunk = KIDS_TO_CHUNK(kids); chunk; chunk = chunk->next) {
- for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
- kid = chunk->kids[i];
- if (!kid)
- break;
- MeterPropertyTree(kid);
- nkids++;
- }
- }
- } else {
- MeterPropertyTree(kids);
- nkids = 1;
- }
- }
-
- MeterKidCount(nkids);
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-js_MeterPropertyTree(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
- void *arg)
-{
- JSPropertyTreeEntry *entry = (JSPropertyTreeEntry *)hdr;
-
- MeterPropertyTree(entry->child);
- return JS_DHASH_NEXT;
-}
-
-#endif /* DEBUG_brendan */
-
-void
-js_SweepScopeProperties(JSRuntime *rt)
-{
- JSArena **ap, *a;
- JSScopeProperty *limit, *sprop, *parent, *kids, *kid;
- uintN liveCount;
- PropTreeKidsChunk *chunk, *nextChunk;
- uintN i;
-
-#ifdef DEBUG_brendan
- uint32 livePropCapacity = 0, totalLiveCount = 0;
- static FILE *logfp;
- if (!logfp)
- logfp = fopen("/tmp/proptree.stats", "a");
-
- MeterKidCount(rt->propertyTreeHash.entryCount);
- JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, NULL);
-
- {
- double mean = 0., var = 0., sigma = 0.;
- double nodesum = rt->livePropTreeNodes;
- double kidsum = js_nkids_sum;
- if (nodesum > 0 && kidsum >= 0) {
- mean = kidsum / nodesum;
- var = nodesum * js_nkids_sqsum - kidsum * kidsum;
- if (var < 0.0 || nodesum <= 1)
- var = 0.0;
- else
- var /= nodesum * (nodesum - 1);
-
- /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
- sigma = (var != 0.) ? sqrt(var) : 0.;
- }
-
- fprintf(logfp,
- "props %u nodes %g beta %g meankids %g sigma %g max %u",
- rt->liveScopeProps, nodesum, nodesum / rt->liveScopeProps,
- mean, sigma, js_nkids_max);
- }
-
- fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u",
- js_nkids_hist[0], js_nkids_hist[1],
- js_nkids_hist[2], js_nkids_hist[3],
- js_nkids_hist[4], js_nkids_hist[5],
- js_nkids_hist[6], js_nkids_hist[7],
- js_nkids_hist[8], js_nkids_hist[9],
- js_nkids_hist[10]);
- js_nkids_sum = js_nkids_max = 0;
- js_nkids_sqsum = 0;
- memset(js_nkids_hist, 0, sizeof js_nkids_hist);
-#endif
-
- ap = &rt->propertyArenaPool.first.next;
- while ((a = *ap) != NULL) {
- limit = (JSScopeProperty *) a->avail;
- liveCount = 0;
- for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) {
- /* If the id is null, sprop is already on the freelist. */
- if (sprop->id == JSVAL_NULL)
- continue;
-
- /* If the mark bit is set, sprop is alive, so we skip it. */
- if (sprop->flags & SPROP_MARK) {
- sprop->flags &= ~SPROP_MARK;
- liveCount++;
- continue;
- }
-
- /* Ok, sprop is garbage to collect: unlink it from its parent. */
- RemovePropertyTreeChild(rt, sprop);
-
- /* Take care to reparent all sprop's kids to their grandparent. */
- kids = sprop->kids;
- if (kids) {
- sprop->kids = NULL;
- parent = sprop->parent;
- if (KIDS_IS_CHUNKY(kids)) {
- chunk = KIDS_TO_CHUNK(kids);
- do {
- for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
- kid = chunk->kids[i];
- if (!kid)
- break;
- JS_ASSERT(kid->parent == sprop);
- InsertPropertyTreeChild(rt, parent, kid);
- }
- nextChunk = chunk->next;
- DestroyPropTreeKidsChunk(rt, chunk);
- } while ((chunk = nextChunk) != NULL);
- } else {
- kid = kids;
- InsertPropertyTreeChild(rt, parent, kid);
- }
- }
-
- /* Clear id so we know (above) that sprop is on the freelist. */
- sprop->id = JSVAL_NULL;
- FREENODE_INSERT(rt->propertyFreeList, sprop);
- JS_RUNTIME_UNMETER(rt, livePropTreeNodes);
- }
-
- /* If a contains no live properties, return it to the malloc heap. */
- if (liveCount == 0) {
- for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++)
- FREENODE_REMOVE(sprop);
- JS_ARENA_DESTROY(&rt->propertyArenaPool, a, ap);
- } else {
-#ifdef DEBUG_brendan
- livePropCapacity += limit - (JSScopeProperty *) a->base;
- totalLiveCount += liveCount;
-#endif
- ap = &a->next;
- }
- }
-
-#ifdef DEBUG_brendan
- fprintf(logfp, " arenautil %g%%\n",
- (totalLiveCount * 100.) / livePropCapacity);
- fflush(logfp);
-#endif
-}
-
-JSBool
-js_InitPropertyTree(JSRuntime *rt)
-{
- if (!JS_DHashTableInit(&rt->propertyTreeHash, &PropertyTreeHashOps, NULL,
- sizeof(JSPropertyTreeEntry), JS_DHASH_MIN_SIZE)) {
- rt->propertyTreeHash.ops = NULL;
- return JS_FALSE;
- }
- JS_InitArenaPool(&rt->propertyArenaPool, "properties",
- 256 * sizeof(JSScopeProperty), sizeof(void *));
- return JS_TRUE;
-}
-
-void
-js_FinishPropertyTree(JSRuntime *rt)
-{
- if (rt->propertyTreeHash.ops) {
- JS_DHashTableFinish(&rt->propertyTreeHash);
- rt->propertyTreeHash.ops = NULL;
- }
- JS_FinishArenaPool(&rt->propertyArenaPool);
-}
diff --git a/src/extension/script/js/jsscope.h b/src/extension/script/js/jsscope.h
deleted file mode 100644
index 4f66441b4..000000000
--- a/src/extension/script/js/jsscope.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsscope_h___
-#define jsscope_h___
-/*
- * JS symbol tables.
- */
-#include "jstypes.h"
-#include "jsobj.h"
-#include "jsprvtd.h"
-#include "jspubtd.h"
-
-#ifdef JS_THREADSAFE
-# include "jslock.h"
-#endif
-
-/*
- * Given P independent, non-unique properties each of size S words mapped by
- * all scopes in a runtime, construct a property tree of N nodes each of size
- * S+L words (L for tree linkage). A nominal L value is 2 for leftmost-child
- * and right-sibling links. We hope that the N < P by enough that the space
- * overhead of L, and the overhead of scope entries pointing at property tree
- * nodes, is worth it.
- *
- * The tree construction goes as follows. If any empty scope in the runtime
- * has a property X added to it, find or create a node under the tree root
- * labeled X, and set scope->lastProp to point at that node. If any non-empty
- * scope whose most recently added property is labeled Y has another property
- * labeled Z added, find or create a node for Z under the node that was added
- * for Y, and set scope->lastProp to point at that node.
- *
- * A property is labeled by its members' values: id, getter, setter, slot,
- * attributes, tiny or short id, and a field telling for..in order. Note that
- * labels are not unique in the tree, but they are unique among a node's kids
- * (barring rare and benign multi-threaded race condition outcomes, see below)
- * and along any ancestor line from the tree root to a given leaf node (except
- * for the hard case of duplicate formal parameters to a function).
- *
- * Thus the root of the tree represents all empty scopes, and the first ply
- * of the tree represents all scopes containing one property, etc. Each node
- * in the tree can stand for any number of scopes having the same ordered set
- * of properties, where that node was the last added to the scope. (We need
- * not store the root of the tree as a node, and do not -- all we need are
- * links to its kids.)
- *
- * Sidebar on for..in loop order: ECMA requires no particular order, but this
- * implementation has promised and delivered property definition order, and
- * compatibility is king. We could use an order number per property, which
- * would require a sort in js_Enumerate, and an entry order generation number
- * per scope. An order number beats a list, which should be doubly-linked for
- * O(1) delete. An even better scheme is to use a parent link in the property
- * tree, so that the ancestor line can be iterated from scope->lastProp when
- * filling in a JSIdArray from back to front. This parent link also helps the
- * GC to sweep properties iteratively.
- *
- * What if a property Y is deleted from a scope? If Y is the last property in
- * the scope, we simply adjust the scope's lastProp member after we remove the
- * scope's hash-table entry pointing at that property node. The parent link
- * mentioned in the for..in sidebar above makes this adjustment O(1). But if
- * Y comes between X and Z in the scope, then we might have to "fork" the tree
- * at X, leaving X->Y->Z in case other scopes have those properties added in
- * that order; and to finish the fork, we'd add a node labeled Z with the path
- * X->Z, if it doesn't exist. This could lead to lots of extra nodes, and to
- * O(n^2) growth when deleting lots of properties.
- *
- * Rather, for O(1) growth all around, we should share the path X->Y->Z among
- * scopes having those three properties added in that order, and among scopes
- * having only X->Z where Y was deleted. All such scopes have a lastProp that
- * points to the Z child of Y. But a scope in which Y was deleted does not
- * have a table entry for Y, and when iterating that scope by traversing the
- * ancestor line from Z, we will have to test for a table entry for each node,
- * skipping nodes that lack entries.
- *
- * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice.
- * Therefore we must fork in such a case, if not earlier. Because delete is
- * "bursty", we should not fork eagerly. Delaying a fork till we are at risk
- * of adding Y after it was deleted already requires a flag in the JSScope, to
- * wit, SCOPE_MIDDLE_DELETE.
- *
- * What about thread safety? If the property tree operations done by requests
- * are find-node and insert-node, then the only hazard is duplicate insertion.
- * This is harmless except for minor bloat. When all requests have ended or
- * been suspended, the GC is free to sweep the tree after marking all nodes
- * reachable from scopes, performing remove-node operations as needed. Note
- * also that the stable storage of the property nodes during active requests
- * permits the property cache (see jsinterp.h) to dereference JSScopeProperty
- * weak references safely.
- *
- * Is the property tree worth it compared to property storage in each table's
- * entries? To decide, we must find the relation <> between the words used
- * with a property tree and the words required without a tree.
- *
- * Model all scopes as one super-scope of capacity T entries (T a power of 2).
- * Let alpha be the load factor of this double hash-table. With the property
- * tree, each entry in the table is a word-sized pointer to a node that can be
- * shared by many scopes. But all such pointers are overhead compared to the
- * situation without the property tree, where the table stores property nodes
- * directly, as entries each of size S words. With the property tree, we need
- * L=2 extra words per node for siblings and kids pointers. Without the tree,
- * (1-alpha)*S*T words are wasted on free or removed sentinel-entries required
- * by double hashing.
- *
- * Therefore,
- *
- * (property tree) <> (no property tree)
- * N*(S+L) + T <> S*T
- * N*(S+L) + T <> P*S + (1-alpha)*S*T
- * N*(S+L) + alpha*T + (1-alpha)*T <> P*S + (1-alpha)*S*T
- *
- * Note that P is alpha*T by definition, so
- *
- * N*(S+L) + P + (1-alpha)*T <> P*S + (1-alpha)*S*T
- * N*(S+L) <> P*S - P + (1-alpha)*S*T - (1-alpha)*T
- * N*(S+L) <> (P + (1-alpha)*T) * (S-1)
- * N*(S+L) <> (P + (1-alpha)*P/alpha) * (S-1)
- * N*(S+L) <> P * (1/alpha) * (S-1)
- *
- * Let N = P*beta for a compression ratio beta, beta <= 1:
- *
- * P*beta*(S+L) <> P * (1/alpha) * (S-1)
- * beta*(S+L) <> (S-1)/alpha
- * beta <> (S-1)/((S+L)*alpha)
- *
- * For S = 6 (32-bit architectures) and L = 2, the property tree wins iff
- *
- * beta < 5/(8*alpha)
- *
- * We ensure that alpha <= .75, so the property tree wins if beta < .83_. An
- * average beta from recent Mozilla browser startups was around .6.
- *
- * Can we reduce L? Observe that the property tree degenerates into a list of
- * lists if at most one property Y follows X in all scopes. In or near such a
- * case, we waste a word on the right-sibling link outside of the root ply of
- * the tree. Note also that the root ply tends to be large, so O(n^2) growth
- * searching it is likely, indicating the need for hashing (but with increased
- * thread safety costs).
- *
- * If only K out of N nodes in the property tree have more than one child, we
- * could eliminate the sibling link and overlay a children list or hash-table
- * pointer on the leftmost-child link (which would then be either null or an
- * only-child link; the overlay could be tagged in the low bit of the pointer,
- * or flagged elsewhere in the property tree node, although such a flag must
- * not be considered when comparing node labels during tree search).
- *
- * For such a system, L = 1 + (K * averageChildrenTableSize) / N instead of 2.
- * If K << N, L approaches 1 and the property tree wins if beta < .95.
- *
- * We observe that fan-out below the root ply of the property tree appears to
- * have extremely low degree (see the MeterPropertyTree code that histograms
- * child-counts in jsscope.c), so instead of a hash-table we use a linked list
- * of child node pointer arrays ("kid chunks"). The details are isolated in
- * jsscope.c; others must treat JSScopeProperty.kids as opaque. We leave it
- * strongly typed for debug-ability of the common (null or one-kid) cases.
- *
- * One final twist (can you stand it?): the mean number of entries per scope
- * in Mozilla is < 5, with a large standard deviation (~8). Instead of always
- * allocating scope->table, we leave it null while initializing all the other
- * scope members as if it were non-null and minimal-length. Until a property
- * is added that crosses the threshold of 6 or more entries for hashing, or
- * until a "middle delete" occurs, we use linear search from scope->lastProp
- * to find a given id, and save on the space overhead of a hash table.
- */
-
-struct JSScope {
- JSObjectMap map; /* base class state */
- JSObject *object; /* object that owns this scope */
- uint16 flags; /* flags, see below */
- int16 hashShift; /* multiplicative hash shift */
- uint32 entryCount; /* number of entries in table */
- uint32 removedCount; /* removed entry sentinels in table */
- JSScopeProperty **table; /* table of ptrs to shared tree nodes */
- JSScopeProperty *lastProp; /* pointer to last property added */
-#ifdef JS_THREADSAFE
- JSContext *ownercx; /* creating context, NULL if shared */
- JSThinLock lock; /* binary semaphore protecting scope */
- union { /* union lockful and lock-free state: */
- jsrefcount count; /* lock entry count for reentrancy */
- JSScope *link; /* next link in rt->scopeSharingTodo */
- } u;
-#ifdef DEBUG
- const char *file[4]; /* file where lock was (re-)taken */
- unsigned int line[4]; /* line where lock was (re-)taken */
-#endif
-#endif
-};
-
-#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map)
-
-/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
-#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift)
-
-/* Scope flags and some macros to hide them from other files than jsscope.c. */
-#define SCOPE_MIDDLE_DELETE 0x0001
-#define SCOPE_SEALED 0x0002
-
-#define SCOPE_HAD_MIDDLE_DELETE(scope) ((scope)->flags & SCOPE_MIDDLE_DELETE)
-#define SCOPE_SET_MIDDLE_DELETE(scope) ((scope)->flags |= SCOPE_MIDDLE_DELETE)
-#define SCOPE_CLR_MIDDLE_DELETE(scope) ((scope)->flags &= ~SCOPE_MIDDLE_DELETE)
-
-#define SCOPE_IS_SEALED(scope) ((scope)->flags & SCOPE_SEALED)
-#define SCOPE_SET_SEALED(scope) ((scope)->flags |= SCOPE_SEALED)
-#if 0
-/*
- * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid
- * taking the lock if the object owns its scope and the scope is sealed.
- */
-#define SCOPE_CLR_SEALED(scope) ((scope)->flags &= ~SCOPE_SEALED)
-#endif
-
-/*
- * A little information hiding for scope->lastProp, in case it ever becomes
- * a tagged pointer again.
- */
-#define SCOPE_LAST_PROP(scope) ((scope)->lastProp)
-#define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \
- (scope)->lastProp->parent)
-
-struct JSScopeProperty {
- jsid id; /* int-tagged jsval/untagged JSAtom* */
- JSPropertyOp getter; /* getter and setter hooks or objects */
- JSPropertyOp setter;
- uint32 slot; /* index in obj->slots vector */
- uint8 attrs; /* attributes, see jsapi.h JSPROP_* */
- uint8 flags; /* flags, see below for defines */
- int16 shortid; /* tinyid, or local arg/var index */
- JSScopeProperty *parent; /* parent node, reverse for..in order */
- JSScopeProperty *kids; /* null, single child, or a tagged ptr
- to many-kids data structure */
-};
-
-/* JSScopeProperty pointer tag bit indicating a collision. */
-#define SPROP_COLLISION ((jsuword)1)
-#define SPROP_REMOVED ((JSScopeProperty *) SPROP_COLLISION)
-
-/* Macros to get and set sprop pointer values and collision flags. */
-#define SPROP_IS_FREE(sprop) ((sprop) == NULL)
-#define SPROP_IS_REMOVED(sprop) ((sprop) == SPROP_REMOVED)
-#define SPROP_IS_LIVE(sprop) ((sprop) > SPROP_REMOVED)
-#define SPROP_FLAG_COLLISION(spp,sprop) (*(spp) = (JSScopeProperty *) \
- ((jsuword)(sprop) | SPROP_COLLISION))
-#define SPROP_HAD_COLLISION(sprop) ((jsuword)(sprop) & SPROP_COLLISION)
-#define SPROP_FETCH(spp) SPROP_CLEAR_COLLISION(*(spp))
-
-#define SPROP_CLEAR_COLLISION(sprop) \
- ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION))
-
-#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop) \
- (*(spp) = (JSScopeProperty *) ((jsuword)(sprop) \
- | SPROP_HAD_COLLISION(*(spp))))
-
-/* Bits stored in sprop->flags. */
-#define SPROP_MARK 0x01
-#define SPROP_IS_DUPLICATE 0x02
-#define SPROP_IS_ALIAS 0x04
-#define SPROP_HAS_SHORTID 0x08
-
-/*
- * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather
- * than id when calling sprop's getter or setter.
- */
-#define SPROP_USERID(sprop) \
- (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \
- : ID_TO_VALUE((sprop)->id))
-
-#define SPROP_INVALID_SLOT 0xffffffff
-
-#define SPROP_HAS_VALID_SLOT(sprop, scope) \
- ((sprop)->slot < (scope)->map.freeslot)
-
-#define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp) \
- (!(getter) || \
- (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
-#define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp) \
- (!(setter) || \
- (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
-
-#define SPROP_GET(cx,sprop,obj,obj2,vp) \
- (((sprop)->attrs & JSPROP_GETTER) \
- ? js_InternalGetOrSet(cx, obj, (sprop)->id, \
- OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \
- 0, 0, vp) \
- : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp))
-
-#define SPROP_SET(cx,sprop,obj,obj2,vp) \
- (((sprop)->attrs & JSPROP_SETTER) \
- ? js_InternalGetOrSet(cx, obj, (sprop)->id, \
- OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE, \
- 1, vp, vp) \
- : ((sprop)->attrs & JSPROP_GETTER) \
- ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \
- JSMSG_GETTER_ONLY, NULL), JS_FALSE) \
- : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp))
-
-/* Macro for common expression to test for shared permanent attributes. */
-#define SPROP_IS_SHARED_PERMANENT(sprop) \
- ((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0)
-
-extern JSScope *
-js_GetMutableScope(JSContext *cx, JSObject *obj);
-
-extern JSScope *
-js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
- JSObject *obj);
-
-extern void
-js_DestroyScope(JSContext *cx, JSScope *scope);
-
-#define ID_TO_VALUE(id) (((id) & JSVAL_INT) ? id : ATOM_KEY((JSAtom *)(id)))
-#define HASH_ID(id) (((id) & JSVAL_INT) \
- ? (jsatomid) JSVAL_TO_INT(id) \
- : ((JSAtom *)id)->number)
-
-extern JS_FRIEND_API(JSScopeProperty **)
-js_SearchScope(JSScope *scope, jsid id, JSBool adding);
-
-#define SCOPE_GET_PROPERTY(scope, id) \
- SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE))
-
-#define SCOPE_HAS_PROPERTY(scope, sprop) \
- (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop))
-
-extern JSScopeProperty *
-js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
- JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
- uintN attrs, uintN flags, intN shortid);
-
-extern JSScopeProperty *
-js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,
- JSScopeProperty *sprop, uintN attrs, uintN mask,
- JSPropertyOp getter, JSPropertyOp setter);
-
-extern JSBool
-js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id);
-
-extern void
-js_ClearScope(JSContext *cx, JSScope *scope);
-
-#define MARK_SCOPE_PROPERTY(sprop) ((sprop)->flags |= SPROP_MARK)
-
-extern void
-js_SweepScopeProperties(JSRuntime *rt);
-
-extern JSBool
-js_InitPropertyTree(JSRuntime *rt);
-
-extern void
-js_FinishPropertyTree(JSRuntime *rt);
-
-#endif /* jsscope_h___ */
diff --git a/src/extension/script/js/jsscript.c b/src/extension/script/js/jsscript.c
deleted file mode 100644
index 504cbbd6d..000000000
--- a/src/extension/script/js/jsscript.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS script operations.
- */
-#include "jsstddef.h"
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsatom.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsdbgapi.h"
-#include "jsemit.h"
-#include "jsfun.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsopcode.h"
-#include "jsscript.h"
-#if JS_HAS_XDR
-#include "jsxdrapi.h"
-#endif
-
-#if JS_HAS_SCRIPT_OBJECT
-
-#if JS_HAS_TOSOURCE
-static JSBool
-script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSScript *script;
- size_t i, j, k, n;
- char buf[16];
- jschar *s, *t;
- uint32 indent;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
- script = (JSScript *) JS_GetPrivate(cx, obj);
-
- /* Let n count the source string length, j the "front porch" length. */
- j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name);
- n = j + 2;
- if (!script) {
- /* Let k count the constructor argument string length. */
- k = 0;
- s = NULL; /* quell GCC overwarning */
- } else {
- indent = 0;
- if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
- return JS_FALSE;
- str = JS_DecompileScript(cx, script, "Script.prototype.toSource",
- (uintN)indent);
- if (!str)
- return JS_FALSE;
- str = js_QuoteString(cx, str, '\'');
- if (!str)
- return JS_FALSE;
- s = JSSTRING_CHARS(str);
- k = JSSTRING_LENGTH(str);
- n += k;
- }
-
- /* Allocate the source string and copy into it. */
- t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
- if (!t)
- return JS_FALSE;
- for (i = 0; i < j; i++)
- t[i] = buf[i];
- for (j = 0; j < k; i++, j++)
- t[i] = s[j];
- t[i++] = ')';
- t[i++] = ')';
- t[i] = 0;
-
- /* Create and return a JS string for t. */
- str = JS_NewUCString(cx, t, n);
- if (!str) {
- JS_free(cx, t);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif /* JS_HAS_TOSOURCE */
-
-static JSBool
-script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSScript *script;
- uint32 indent;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
- script = (JSScript *) JS_GetPrivate(cx, obj);
- if (!script) {
- *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
- return JS_TRUE;
- }
-
- indent = 0;
- if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
- return JS_FALSE;
- str = JS_DecompileScript(cx, script, "Script.prototype.toString",
- (uintN)indent);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSScript *oldscript, *script;
- JSString *str;
- JSStackFrame *fp, *caller;
- JSObject *scopeobj;
- const char *file;
- uintN line;
- JSPrincipals *principals;
-
- /* Make sure obj is a Script object. */
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
-
- /* If no args, leave private undefined and return early. */
- if (argc == 0)
- goto out;
-
- /* Otherwise, the first arg is the script source to compile. */
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
-
- /* Compile using the caller's scope chain, which js_Invoke passes to fp. */
- fp = cx->fp;
- caller = JS_GetScriptedCaller(cx, fp);
- JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain);
-
- scopeobj = NULL;
- if (argc >= 2) {
- if (!js_ValueToObject(cx, argv[1], &scopeobj))
- return JS_FALSE;
- argv[1] = OBJECT_TO_JSVAL(scopeobj);
- }
- if (caller) {
- if (!scopeobj)
- scopeobj = caller->scopeChain;
-
- file = caller->script->filename;
- line = js_PCToLineNumber(cx, caller->script, caller->pc);
- principals = JS_EvalFramePrincipals(cx, fp, caller);
- } else {
- file = NULL;
- line = 0;
- principals = NULL;
- }
-
- /* XXXbe set only for the compiler, which does not currently test it */
- fp->flags |= JSFRAME_EVAL;
-
- /* Compile the new script using the caller's scope chain, a la eval(). */
- script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
- JSSTRING_CHARS(str),
- JSSTRING_LENGTH(str),
- file, line);
- if (!script)
- return JS_FALSE;
-
- /* Swap script for obj's old script, if any. */
- oldscript = (JSScript *) JS_GetPrivate(cx, obj);
- if (!JS_SetPrivate(cx, obj, script)) {
- js_DestroyScript(cx, script);
- return JS_FALSE;
- }
- if (oldscript)
- js_DestroyScript(cx, oldscript);
-
- script->object = obj;
-out:
- /* Return the object. */
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
-}
-
-static JSBool
-script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSScript *script;
- JSObject *scopeobj, *parent;
- JSStackFrame *fp, *caller;
-
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
- script = (JSScript *) JS_GetPrivate(cx, obj);
- if (!script)
- return JS_TRUE;
-
- scopeobj = NULL;
- if (argc) {
- if (!js_ValueToObject(cx, argv[0], &scopeobj))
- return JS_FALSE;
- argv[0] = OBJECT_TO_JSVAL(scopeobj);
- }
-
- /*
- * Emulate eval() by using caller's this, var object, sharp array, etc.,
- * all propagated by js_Execute via a non-null fourth (down) argument to
- * js_Execute. If there is no scripted caller, js_Execute uses its second
- * (chain) argument to set the exec frame's varobj, thisp, and scopeChain.
- *
- * Unlike eval, which the compiler detects, Script.prototype.exec may be
- * called from a lightweight function, or even from native code (in which
- * case fp->varobj and fp->scopeChain are null). If exec is called from
- * a lightweight function, we will need to get a Call object representing
- * its frame, to act as the var object and scope chain head.
- */
- fp = cx->fp;
- caller = JS_GetScriptedCaller(cx, fp);
- if (caller && !caller->varobj) {
- /* Called from a lightweight function. */
- JS_ASSERT(caller->fun && !(caller->fun->flags & JSFUN_HEAVYWEIGHT));
-
- /* Scope chain links from Call object to callee's parent. */
- parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(caller->argv[-2]));
- if (!js_GetCallObject(cx, caller, parent))
- return JS_FALSE;
- }
-
- if (!scopeobj) {
- /* No scope object passed in: try to use the caller's scope chain. */
- if (caller) {
- /*
- * Load caller->scopeChain after the conditional js_GetCallObject
- * call above, which resets scopeChain as well as varobj.
- */
- scopeobj = caller->scopeChain;
- } else {
- /*
- * Called from native code, so we don't know what scope object to
- * use. We could use parent (see above), but Script.prototype.exec
- * might be a shared/sealed "superglobal" method. A more general
- * approach would use cx->globalObject, which will be the same as
- * exec.__parent__ in the non-superglobal case. In the superglobal
- * case it's the right object: the global, not the superglobal.
- */
- scopeobj = cx->globalObject;
- }
- }
-
- return js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
-}
-
-#if JS_HAS_XDR
-
-static JSBool
-XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale)
-{
- jsval value;
- jsatomid index;
-
- if (xdr->mode == JSXDR_ENCODE)
- value = ATOM_KEY(ALE_ATOM(ale));
-
- index = ALE_INDEX(ale);
- if (!JS_XDRUint32(xdr, &index))
- return JS_FALSE;
- ALE_SET_INDEX(ale, index);
-
- if (!JS_XDRValue(xdr, &value))
- return JS_FALSE;
-
- if (xdr->mode == JSXDR_DECODE) {
- if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0)))
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-static JSBool
-XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
-{
- uint32 length;
- uintN i;
- JSBool ok;
-
- if (xdr->mode == JSXDR_ENCODE)
- length = map->length;
-
- if (!JS_XDRUint32(xdr, &length))
- return JS_FALSE;
-
- if (xdr->mode == JSXDR_DECODE) {
- JSContext *cx;
- void *mark;
- JSAtomList al;
- JSAtomListElement *ale;
-
- cx = xdr->cx;
- mark = JS_ARENA_MARK(&cx->tempPool);
- ATOM_LIST_INIT(&al);
- for (i = 0; i < length; i++) {
- JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
- if (!ale ||
- !XDRAtomListElement(xdr, ale)) {
- if (!ale)
- JS_ReportOutOfMemory(cx);
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return JS_FALSE;
- }
- ALE_SET_NEXT(ale, al.list);
- al.count++;
- al.list = ale;
- }
- ok = js_InitAtomMap(cx, map, &al);
- JS_ARENA_RELEASE(&cx->tempPool, mark);
- return ok;
- }
-
- if (xdr->mode == JSXDR_ENCODE) {
- JSAtomListElement ale;
-
- for (i = 0; i < map->length; i++) {
- ALE_SET_ATOM(&ale, map->vector[i]);
- ALE_SET_INDEX(&ale, i);
- if (!XDRAtomListElement(xdr, &ale))
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-JSBool
-js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
-{
- JSContext *cx;
- JSScript *script, *newscript;
- uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes;
- uint32 prologLength, version;
- JSBool filenameWasSaved;
- jssrcnote *notes, *sn;
-
- cx = xdr->cx;
- script = *scriptp;
- nsrcnotes = ntrynotes = 0;
- filenameWasSaved = JS_FALSE;
- notes = NULL;
-
- /*
- * Encode prologLength and version after script->length (_2 or greater),
- * but decode both new (>= _2) and old, prolog&version-free (_1) scripts.
- * Version _3 supports principals serialization. Version _4 reorders the
- * nsrcnotes and ntrynotes fields to come before everything except magic,
- * length, prologLength, and version, so that srcnote and trynote storage
- * can be allocated as part of the JSScript (along with bytecode storage).
- */
- if (xdr->mode == JSXDR_ENCODE)
- magic = JSXDR_MAGIC_SCRIPT_CURRENT;
- if (!JS_XDRUint32(xdr, &magic))
- return JS_FALSE;
- if (magic != JSXDR_MAGIC_SCRIPT_4 &&
- magic != JSXDR_MAGIC_SCRIPT_3 &&
- magic != JSXDR_MAGIC_SCRIPT_2 &&
- magic != JSXDR_MAGIC_SCRIPT_1) {
- if (!hasMagic) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_SCRIPT_MAGIC);
- return JS_FALSE;
- }
- *hasMagic = JS_FALSE;
- return JS_TRUE;
- }
- if (hasMagic)
- *hasMagic = JS_TRUE;
-
- if (xdr->mode == JSXDR_ENCODE) {
- length = script->length;
- prologLength = PTRDIFF(script->main, script->code, jsbytecode);
- version = (int32)script->version;
- lineno = (uint32)script->lineno;
- depth = (uint32)script->depth;
-
- /* Count the srcnotes, keeping notes pointing at the first one. */
- notes = SCRIPT_NOTES(script);
- for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
- continue;
- nsrcnotes = PTRDIFF(sn, notes, jssrcnote);
- nsrcnotes++; /* room for the terminator */
-
- /* Count the trynotes. */
- if (script->trynotes) {
- while (script->trynotes[ntrynotes].catchStart)
- ntrynotes++;
- ntrynotes++; /* room for the end marker */
- }
- }
-
- if (!JS_XDRUint32(xdr, &length))
- return JS_FALSE;
- if (magic >= JSXDR_MAGIC_SCRIPT_2) {
- if (!JS_XDRUint32(xdr, &prologLength))
- return JS_FALSE;
- if (!JS_XDRUint32(xdr, &version))
- return JS_FALSE;
-
- /* To fuse allocations, we need srcnote and trynote counts early. */
- if (magic >= JSXDR_MAGIC_SCRIPT_4) {
- if (!JS_XDRUint32(xdr, &nsrcnotes))
- return JS_FALSE;
- if (!JS_XDRUint32(xdr, &ntrynotes))
- return JS_FALSE;
- }
- }
-
- if (xdr->mode == JSXDR_DECODE) {
- script = js_NewScript(cx, length, nsrcnotes, ntrynotes);
- if (!script)
- return JS_FALSE;
- if (magic >= JSXDR_MAGIC_SCRIPT_2) {
- script->main += prologLength;
- script->version = (JSVersion) version;
-
- /* If we know nsrcnotes, we allocated space for notes in script. */
- if (magic >= JSXDR_MAGIC_SCRIPT_4)
- notes = SCRIPT_NOTES(script);
- }
- *scriptp = script;
- }
-
- /*
- * Control hereafter must goto error on failure, in order for the DECODE
- * case to destroy script and conditionally free notes, which if non-null
- * in the (DECODE and version < _4) case must point at a temporary vector
- * allocated just below.
- */
- if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) ||
- !XDRAtomMap(xdr, &script->atomMap)) {
- goto error;
- }
-
- if (magic < JSXDR_MAGIC_SCRIPT_4) {
- if (!JS_XDRUint32(xdr, &nsrcnotes))
- goto error;
- if (xdr->mode == JSXDR_DECODE) {
- notes = (jssrcnote *) JS_malloc(cx, nsrcnotes * sizeof(jssrcnote));
- if (!notes)
- goto error;
- }
- }
-
- if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) ||
- !JS_XDRCStringOrNull(xdr, (char **)&script->filename) ||
- !JS_XDRUint32(xdr, &lineno) ||
- !JS_XDRUint32(xdr, &depth) ||
- (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) {
- goto error;
- }
-
- /* Script principals transcoding support comes with versions >= _3. */
- if (magic >= JSXDR_MAGIC_SCRIPT_3) {
- JSPrincipals *principals;
- uint32 encodeable;
-
- if (xdr->mode == JSXDR_ENCODE) {
- principals = script->principals;
- encodeable = (cx->runtime->principalsTranscoder != NULL);
- if (!JS_XDRUint32(xdr, &encodeable))
- goto error;
- if (encodeable &&
- !cx->runtime->principalsTranscoder(xdr, &principals)) {
- goto error;
- }
- } else {
- if (!JS_XDRUint32(xdr, &encodeable))
- goto error;
- if (encodeable) {
- if (!cx->runtime->principalsTranscoder) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_CANT_DECODE_PRINCIPALS);
- goto error;
- }
- if (!cx->runtime->principalsTranscoder(xdr, &principals))
- goto error;
- script->principals = principals;
- }
- }
- }
-
- if (xdr->mode == JSXDR_DECODE) {
- const char *filename = script->filename;
- if (filename) {
- filename = js_SaveScriptFilename(cx, filename);
- if (!filename)
- goto error;
- JS_free(cx, (void *) script->filename);
- script->filename = filename;
- filenameWasSaved = JS_TRUE;
- }
- script->lineno = (uintN)lineno;
- script->depth = (uintN)depth;
-
- if (magic < JSXDR_MAGIC_SCRIPT_4) {
- /*
- * Argh, we have to reallocate script, copy notes into the extra
- * space after the bytecodes, and free the temporary notes vector.
- * First, add enough slop to nsrcnotes so we can align the address
- * after the srcnotes of the first trynote.
- */
- uint32 osrcnotes = nsrcnotes;
-
- if (ntrynotes)
- nsrcnotes += JSTRYNOTE_ALIGNMASK;
- newscript = (JSScript *) JS_realloc(cx, script,
- sizeof(JSScript) +
- length * sizeof(jsbytecode) +
- nsrcnotes * sizeof(jssrcnote) +
- ntrynotes * sizeof(JSTryNote));
- if (!newscript)
- goto error;
-
- *scriptp = script = newscript;
- script->code = (jsbytecode *)(script + 1);
- script->main = script->code + prologLength;
- memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote));
- JS_free(cx, (void *) notes);
- notes = NULL;
- if (ntrynotes) {
- script->trynotes = (JSTryNote *)
- ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &
- ~(jsword)JSTRYNOTE_ALIGNMASK);
- }
- }
- }
-
- while (ntrynotes) {
- JSTryNote *tn = &script->trynotes[--ntrynotes];
- uint32 start = (uint32) tn->start,
- catchLength = (uint32) tn->length,
- catchStart = (uint32) tn->catchStart;
-
- if (!JS_XDRUint32(xdr, &start) ||
- !JS_XDRUint32(xdr, &catchLength) ||
- !JS_XDRUint32(xdr, &catchStart)) {
- goto error;
- }
- tn->start = (ptrdiff_t) start;
- tn->length = (ptrdiff_t) catchLength;
- tn->catchStart = (ptrdiff_t) catchStart;
- }
- return JS_TRUE;
-
- error:
- if (xdr->mode == JSXDR_DECODE) {
- if (script->filename && !filenameWasSaved) {
- JS_free(cx, (void *) script->filename);
- script->filename = NULL;
- }
- if (notes && magic < JSXDR_MAGIC_SCRIPT_4)
- JS_free(cx, (void *) notes);
- js_DestroyScript(cx, script);
- *scriptp = NULL;
- }
- return JS_FALSE;
-}
-
-#if JS_HAS_XDR_FREEZE_THAW
-/*
- * These cannot be exposed to web content, and chrome does not need them, so
- * we take them out of the Mozilla client altogether. Fortunately, there is
- * no way to serialize a native function (see fun_xdrObject in jsfun.c).
- */
-
-static JSBool
-script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSXDRState *xdr;
- JSScript *script;
- JSBool ok, hasMagic;
- uint32 len;
- void *buf;
- JSString *str;
-
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
- script = (JSScript *) JS_GetPrivate(cx, obj);
- if (!script)
- return JS_TRUE;
-
- /* create new XDR */
- xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
- if (!xdr)
- return JS_FALSE;
-
- /* write */
- ok = js_XDRScript(xdr, &script, &hasMagic);
- if (!ok)
- goto out;
- if (!hasMagic) {
- *rval = JSVAL_VOID;
- goto out;
- }
-
- buf = JS_XDRMemGetData(xdr, &len);
- if (!buf) {
- ok = JS_FALSE;
- goto out;
- }
-
- JS_ASSERT((jsword)buf % sizeof(jschar) == 0);
- len /= sizeof(jschar);
- str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
- if (!str) {
- ok = JS_FALSE;
- goto out;
- }
-
-#if IS_BIG_ENDIAN
- {
- jschar *chars;
- uint32 i;
-
- /* Swap bytes in Unichars to keep frozen strings machine-independent. */
- chars = JS_GetStringChars(str);
- for (i = 0; i < len; i++)
- chars[i] = JSXDR_SWAB16(chars[i]);
- }
-#endif
- *rval = STRING_TO_JSVAL(str);
-
-out:
- JS_XDRDestroy(xdr);
- return ok;
-}
-
-static JSBool
-script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSXDRState *xdr;
- JSString *str;
- void *buf;
- uint32 len;
- JSScript *script, *oldscript;
- JSBool ok, hasMagic;
-
- if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
- return JS_FALSE;
-
- if (argc == 0)
- return JS_TRUE;
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
-
- /* create new XDR */
- xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
- if (!xdr)
- return JS_FALSE;
-
- buf = JS_GetStringChars(str);
- len = JS_GetStringLength(str);
-#if IS_BIG_ENDIAN
- {
- jschar *from, *to;
- uint32 i;
-
- /* Swap bytes in Unichars to keep frozen strings machine-independent. */
- from = (jschar *)buf;
- to = (jschar *) JS_malloc(cx, len * sizeof(jschar));
- if (!to) {
- JS_XDRDestroy(xdr);
- return JS_FALSE;
- }
- for (i = 0; i < len; i++)
- to[i] = JSXDR_SWAB16(from[i]);
- buf = (char *)to;
- }
-#endif
- len *= sizeof(jschar);
- JS_XDRMemSetData(xdr, buf, len);
-
- /* XXXbe should magic mismatch be error, or false return value? */
- ok = js_XDRScript(xdr, &script, &hasMagic);
- if (!ok)
- goto out;
- if (!hasMagic) {
- *rval = JSVAL_FALSE;
- goto out;
- }
-
- /* Swap script for obj's old script, if any. */
- oldscript = (JSScript *) JS_GetPrivate(cx, obj);
- ok = JS_SetPrivate(cx, obj, script);
- if (!ok) {
- JS_free(cx, script);
- goto out;
- }
- if (oldscript)
- js_DestroyScript(cx, oldscript);
-
- script->object = obj;
- js_CallNewScriptHook(cx, script, NULL);
-
-out:
- /*
- * We reset the buffer to be NULL so that it doesn't free the chars
- * memory owned by str (argv[0]).
- */
- JS_XDRMemSetData(xdr, NULL, 0);
- JS_XDRDestroy(xdr);
-#if IS_BIG_ENDIAN
- JS_free(cx, buf);
-#endif
- *rval = JSVAL_TRUE;
- return ok;
-}
-
-static const char js_thaw_str[] = "thaw";
-
-#endif /* JS_HAS_XDR_FREEZE_THAW */
-#endif /* JS_HAS_XDR */
-
-static JSFunctionSpec script_methods[] = {
-#if JS_HAS_TOSOURCE
- {js_toSource_str, script_toSource, 0,0,0},
-#endif
- {js_toString_str, script_toString, 0,0,0},
- {"compile", script_compile, 2,0,0},
- {"exec", script_exec, 1,0,0},
-#if JS_HAS_XDR_FREEZE_THAW
- {"freeze", script_freeze, 0,0,0},
- {js_thaw_str, script_thaw, 1,0,0},
-#endif /* JS_HAS_XDR_FREEZE_THAW */
- {0,0,0,0,0}
-};
-
-#endif /* JS_HAS_SCRIPT_OBJECT */
-
-static void
-script_finalize(JSContext *cx, JSObject *obj)
-{
- JSScript *script;
-
- script = (JSScript *) JS_GetPrivate(cx, obj);
- if (script)
- js_DestroyScript(cx, script);
-}
-
-static JSBool
-script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-#if JS_HAS_SCRIPT_OBJECT
- return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
-#else
- return JS_FALSE;
-#endif
-}
-
-static uint32
-script_mark(JSContext *cx, JSObject *obj, void *arg)
-{
- JSScript *script;
-
- script = (JSScript *) JS_GetPrivate(cx, obj);
- if (script)
- js_MarkScript(cx, script, arg);
- return 0;
-}
-
-JS_FRIEND_DATA(JSClass) js_ScriptClass = {
- js_Script_str,
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize,
- NULL, NULL, script_call, NULL,/*XXXbe xdr*/
- NULL, NULL, script_mark, 0
-};
-
-#if JS_HAS_SCRIPT_OBJECT
-
-static JSBool
-Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- /* If not constructing, replace obj with a new Script object. */
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- }
- return script_compile(cx, obj, argc, argv, rval);
-}
-
-#if JS_HAS_XDR_FREEZE_THAW
-
-static JSBool
-script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
- if (!obj)
- return JS_FALSE;
- if (!script_thaw(cx, obj, argc, argv, rval))
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(obj);
- return JS_TRUE;
-}
-
-static JSFunctionSpec script_static_methods[] = {
- {js_thaw_str, script_static_thaw, 1,0,0},
- {0,0,0,0,0}
-};
-
-#else /* !JS_HAS_XDR_FREEZE_THAW */
-
-#define script_static_methods NULL
-
-#endif /* !JS_HAS_XDR_FREEZE_THAW */
-
-JSObject *
-js_InitScriptClass(JSContext *cx, JSObject *obj)
-{
- return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,
- NULL, script_methods, NULL, script_static_methods);
-}
-
-#endif /* JS_HAS_SCRIPT_OBJECT */
-
-/*
- * Shared script filename management.
- */
-static JSHashTable *script_filename_table;
-#ifdef JS_THREADSAFE
-static JSLock *script_filename_table_lock;
-#endif
-
-JS_STATIC_DLL_CALLBACK(int)
-js_compare_strings(const void *k1, const void *k2)
-{
- return strcmp(k1, k2) == 0;
-}
-
-/* Shared with jsatom.c to save code space. */
-extern void * JS_DLL_CALLBACK
-js_alloc_table_space(void *priv, size_t size);
-
-extern void JS_DLL_CALLBACK
-js_free_table_space(void *priv, void *item);
-
-/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */
-typedef struct ScriptFilenameEntry {
- JSHashEntry *next; /* hash chain linkage */
- JSHashNumber keyHash; /* key hash function result */
- const void *key; /* ptr to filename, below */
- JSPackedBool mark; /* mark flag, for GC */
- char filename[3]; /* two or more bytes, NUL-terminated */
-} ScriptFilenameEntry;
-
-JS_STATIC_DLL_CALLBACK(JSHashEntry *)
-js_alloc_entry(void *priv, const void *key)
-{
- size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1;
-
- return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-js_free_entry(void *priv, JSHashEntry *he, uintN flag)
-{
- if (flag != HT_FREE_ENTRY)
- return;
- free(he);
-}
-
-static JSHashAllocOps table_alloc_ops = {
- js_alloc_table_space, js_free_table_space,
- js_alloc_entry, js_free_entry
-};
-
-JSBool
-js_InitScriptGlobals()
-{
-#ifdef JS_THREADSAFE
- /* Must come through here once in primordial thread to init safely! */
- if (!script_filename_table_lock) {
- script_filename_table_lock = JS_NEW_LOCK();
- if (!script_filename_table_lock)
- return JS_FALSE;
- }
-#endif
- if (!script_filename_table) {
- JS_ACQUIRE_LOCK(script_filename_table_lock);
- if (!script_filename_table) {
- script_filename_table =
- JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL,
- &table_alloc_ops, NULL);
- }
- JS_RELEASE_LOCK(script_filename_table_lock);
- if (!script_filename_table)
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-void
-js_FreeScriptGlobals()
-{
- if (script_filename_table) {
- JS_HashTableDestroy(script_filename_table);
- script_filename_table = NULL;
- }
-#ifdef JS_THREADSAFE
- if (script_filename_table_lock) {
- JS_DESTROY_LOCK(script_filename_table_lock);
- script_filename_table_lock = NULL;
- }
-#endif
-}
-
-#ifdef DEBUG_brendan
-size_t sft_savings = 0;
-#endif
-
-const char *
-js_SaveScriptFilename(JSContext *cx, const char *filename)
-{
- JSHashTable *table;
- JSHashNumber hash;
- JSHashEntry **hep;
- ScriptFilenameEntry *sfe;
-
- JS_ACQUIRE_LOCK(script_filename_table_lock);
- table = script_filename_table;
- hash = JS_HashString(filename);
- hep = JS_HashTableRawLookup(table, hash, filename);
- sfe = (ScriptFilenameEntry *) *hep;
-#ifdef DEBUG_brendan
- if (sfe)
- sft_savings += strlen(sfe->filename);
-#endif
- if (!sfe) {
- sfe = (ScriptFilenameEntry *)
- JS_HashTableRawAdd(table, hep, hash, filename, NULL);
- if (sfe) {
- sfe->key = strcpy(sfe->filename, filename);
- JS_ASSERT(!sfe->mark);
- }
- }
- JS_RELEASE_LOCK(script_filename_table_lock);
- if (!sfe) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
- return sfe->filename;
-}
-
-void
-js_MarkScriptFilename(const char *filename)
-{
- ScriptFilenameEntry *sfe;
-
- /*
- * Back up from filename by its offset within its hash table entry.
- * The sfe->key member, redundant given sfe->filename but required by
- * the old jshash.c code, here gives us a useful sanity check. This
- * assertion will very likely botch if someone tries to mark a string
- * that wasn't allocated as an sfe->filename.
- */
- sfe = (ScriptFilenameEntry *)
- (filename - offsetof(ScriptFilenameEntry, filename));
- JS_ASSERT(sfe->key == sfe->filename);
- sfe->mark = JS_TRUE;
-}
-
-JS_STATIC_DLL_CALLBACK(intN)
-js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg)
-{
- ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
-
- if (!sfe->mark)
- return HT_ENUMERATE_REMOVE;
- sfe->mark = JS_FALSE;
- return HT_ENUMERATE_NEXT;
-}
-
-void
-js_SweepScriptFilenames(JSRuntime *rt)
-{
- JS_HashTableEnumerateEntries(script_filename_table,
- js_script_filename_sweeper,
- rt);
-#ifdef DEBUG_brendan
- printf("script filename table savings so far: %u\n", sft_savings);
-#endif
-}
-
-JSScript *
-js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 ntrynotes)
-{
- JSScript *script;
-
- /* Round up source note count to align script->trynotes for its type. */
- if (ntrynotes)
- nsrcnotes += JSTRYNOTE_ALIGNMASK;
- script = (JSScript *) JS_malloc(cx,
- sizeof(JSScript) +
- length * sizeof(jsbytecode) +
- nsrcnotes * sizeof(jssrcnote) +
- ntrynotes * sizeof(JSTryNote));
- if (!script)
- return NULL;
- memset(script, 0, sizeof(JSScript));
- script->code = script->main = (jsbytecode *)(script + 1);
- script->length = length;
- script->version = cx->version;
- if (ntrynotes) {
- script->trynotes = (JSTryNote *)
- ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &
- ~(jsword)JSTRYNOTE_ALIGNMASK);
- }
- return script;
-}
-
-JS_FRIEND_API(JSScript *)
-js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun)
-{
- uint32 mainLength, prologLength, nsrcnotes, ntrynotes;
- JSScript *script;
- const char *filename;
-
- mainLength = CG_OFFSET(cg);
- prologLength = CG_PROLOG_OFFSET(cg);
- CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes);
- CG_COUNT_FINAL_TRYNOTES(cg, ntrynotes);
- script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, ntrynotes);
- if (!script)
- return NULL;
-
- /* Now that we have script, error control flow must go to label bad. */
- script->main += prologLength;
- memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
- memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));
- if (!js_InitAtomMap(cx, &script->atomMap, &cg->atomList))
- goto bad;
-
- filename = cg->filename;
- if (filename) {
- script->filename = js_SaveScriptFilename(cx, filename);
- if (!script->filename)
- goto bad;
- }
- script->lineno = cg->firstLine;
- script->depth = cg->maxStackDepth;
- if (cg->principals) {
- script->principals = cg->principals;
- JSPRINCIPALS_HOLD(cx, script->principals);
- }
-
- if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script)))
- goto bad;
- if (script->trynotes)
- js_FinishTakingTryNotes(cx, cg, script->trynotes);
-
- /* Tell the debugger about this compiled script. */
- js_CallNewScriptHook(cx, script, fun);
- return script;
-
-bad:
- js_DestroyScript(cx, script);
- return NULL;
-}
-
-JS_FRIEND_API(void)
-js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
-{
- JSRuntime *rt;
- JSNewScriptHook hook;
-
- rt = cx->runtime;
- hook = rt->newScriptHook;
- if (hook) {
- /*
- * We use a dummy stack frame to protect the script from a GC caused
- * by debugger-hook execution.
- *
- * XXX We really need a way to manage local roots and such more
- * XXX automatically, at which point we can remove this one-off hack
- * XXX and others within the engine. See bug 40757 for discussion.
- */
- JSStackFrame dummy;
-
- memset(&dummy, 0, sizeof dummy);
- dummy.down = cx->fp;
- dummy.script = script;
- cx->fp = &dummy;
-
- hook(cx, script->filename, script->lineno, script, fun,
- rt->newScriptHookData);
-
- cx->fp = dummy.down;
- }
-}
-
-void
-js_DestroyScript(JSContext *cx, JSScript *script)
-{
- JSRuntime *rt;
- JSDestroyScriptHook hook;
-
- rt = cx->runtime;
- hook = rt->destroyScriptHook;
- if (hook)
- hook(cx, script, rt->destroyScriptHookData);
-
- JS_ClearScriptTraps(cx, script);
- js_FreeAtomMap(cx, &script->atomMap);
- if (script->principals)
- JSPRINCIPALS_DROP(cx, script->principals);
- JS_free(cx, script);
-}
-
-void
-js_MarkScript(JSContext *cx, JSScript *script, void *arg)
-{
- JSAtomMap *map;
- uintN i, length;
- JSAtom **vector;
-
- map = &script->atomMap;
- length = map->length;
- vector = map->vector;
- for (i = 0; i < length; i++)
- GC_MARK_ATOM(cx, vector[i], arg);
-
- if (script->filename)
- js_MarkScriptFilename(script->filename);
-}
-
-jssrcnote *
-js_GetSrcNote(JSScript *script, jsbytecode *pc)
-{
- jssrcnote *sn;
- ptrdiff_t offset, target;
-
- target = PTRDIFF(pc, script->code, jsbytecode);
- if ((uint32)target >= script->length)
- return NULL;
- offset = 0;
- for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
- offset += SN_DELTA(sn);
- if (offset == target && SN_IS_GETTABLE(sn))
- return sn;
- }
- return NULL;
-}
-
-uintN
-js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
-{
- JSAtom *atom;
- JSFunction *fun;
- uintN lineno;
- ptrdiff_t offset, target;
- jssrcnote *sn;
- JSSrcNoteType type;
-
- /*
- * Special case: function definition needs no line number note because
- * the function's script contains its starting line number.
- */
- if (*pc == JSOP_DEFFUN) {
- atom = GET_ATOM(cx, script, pc);
- fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
- return fun->script->lineno;
- }
-
- /*
- * General case: walk through source notes accumulating their deltas,
- * keeping track of line-number notes, until we pass the note for pc's
- * offset within script->code.
- */
- lineno = script->lineno;
- offset = 0;
- target = PTRDIFF(pc, script->code, jsbytecode);
- for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
- offset += SN_DELTA(sn);
- type = (JSSrcNoteType) SN_TYPE(sn);
- if (type == SRC_SETLINE) {
- if (offset <= target)
- lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
- } else if (type == SRC_NEWLINE) {
- if (offset <= target)
- lineno++;
- }
- if (offset > target)
- break;
- }
- return lineno;
-}
-
-jsbytecode *
-js_LineNumberToPC(JSScript *script, uintN target)
-{
- ptrdiff_t offset;
- uintN lineno;
- jssrcnote *sn;
- JSSrcNoteType type;
-
- offset = 0;
- lineno = script->lineno;
- for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
- if (lineno >= target)
- break;
- offset += SN_DELTA(sn);
- type = (JSSrcNoteType) SN_TYPE(sn);
- if (type == SRC_SETLINE) {
- lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
- } else if (type == SRC_NEWLINE) {
- lineno++;
- }
- }
- return script->code + offset;
-}
-
-uintN
-js_GetScriptLineExtent(JSScript *script)
-{
- uintN lineno;
- jssrcnote *sn;
- JSSrcNoteType type;
-
- lineno = script->lineno;
- for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
- type = (JSSrcNoteType) SN_TYPE(sn);
- if (type == SRC_SETLINE) {
- lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
- } else if (type == SRC_NEWLINE) {
- lineno++;
- }
- }
- return 1 + lineno - script->lineno;
-}
diff --git a/src/extension/script/js/jsscript.h b/src/extension/script/js/jsscript.h
deleted file mode 100644
index ffcc40de7..000000000
--- a/src/extension/script/js/jsscript.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsscript_h___
-#define jsscript_h___
-/*
- * JS script descriptor.
- */
-#include "jsatom.h"
-#include "jsprvtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * Exception handling runtime information.
- *
- * All fields except length are code offsets, relative to the beginning of
- * the script. If script->trynotes is not null, it points to a vector of
- * these structs terminated by one with catchStart == 0.
- */
-struct JSTryNote {
- ptrdiff_t start; /* start of try statement */
- ptrdiff_t length; /* count of try statement bytecodes */
- ptrdiff_t catchStart; /* start of catch block (0 if end) */
-};
-
-#define JSTRYNOTE_GRAIN sizeof(ptrdiff_t)
-#define JSTRYNOTE_ALIGNMASK (JSTRYNOTE_GRAIN - 1)
-
-struct JSScript {
- jsbytecode *code; /* bytecodes and their immediate operands */
- uint32 length; /* length of code vector */
- jsbytecode *main; /* main entry point, after predef'ing prolog */
- JSVersion version; /* JS version under which script was compiled */
- JSAtomMap atomMap; /* maps immediate index to literal struct */
- const char *filename; /* source filename or null */
- uintN lineno; /* base line number of script */
- uintN depth; /* maximum stack depth in slots */
- JSTryNote *trynotes; /* exception table for this script */
- JSPrincipals *principals; /* principals for this script */
- JSObject *object; /* optional Script-class object wrapper */
-};
-
-/* No need to store script->notes now that it is allocated right after code. */
-#define SCRIPT_NOTES(script) ((jssrcnote*)((script)->code+(script)->length))
-
-#define SCRIPT_FIND_CATCH_START(script, pc, catchpc) \
- JS_BEGIN_MACRO \
- JSTryNote *tn_ = (script)->trynotes; \
- jsbytecode *catchpc_ = NULL; \
- if (tn_) { \
- ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode); \
- if (off_ >= 0) { \
- while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length) \
- ++tn_; \
- if (tn_->catchStart) \
- catchpc_ = (script)->main + tn_->catchStart; \
- } \
- } \
- catchpc = catchpc_; \
- JS_END_MACRO
-
-extern JS_FRIEND_DATA(JSClass) js_ScriptClass;
-
-extern JSObject *
-js_InitScriptClass(JSContext *cx, JSObject *obj);
-
-extern JSBool
-js_InitScriptGlobals();
-
-extern void
-js_FreeScriptGlobals();
-
-extern const char *
-js_SaveScriptFilename(JSContext *cx, const char *filename);
-
-extern void
-js_MarkScriptFilename(const char *filename);
-
-extern void
-js_SweepScriptFilenames(JSRuntime *rt);
-
-/*
- * Two successively less primitive ways to make a new JSScript. The first
- * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
- * js_NewScriptFromCG, calls this optional debugger hook.
- *
- * The js_NewScript function can't know whether the script it creates belongs
- * to a function, or is top-level or eval code, but the debugger wants access
- * to the newly made script's function, if any -- so callers of js_NewScript
- * are responsible for notifying the debugger after successfully creating any
- * kind (function or other) of new JSScript.
- */
-extern JSScript *
-js_NewScript(JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength);
-
-extern JS_FRIEND_API(JSScript *)
-js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun);
-
-/*
- * New-script-hook calling is factored from js_NewScriptFromCG so that it
- * and callers of js_XDRScript can share this code. In the case of callers
- * of js_XDRScript, the hook should be invoked only after successful decode
- * of any owning function (the fun parameter) or script object (null fun).
- */
-extern JS_FRIEND_API(void)
-js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
-
-extern void
-js_DestroyScript(JSContext *cx, JSScript *script);
-
-extern void
-js_MarkScript(JSContext *cx, JSScript *script, void *arg);
-
-extern jssrcnote *
-js_GetSrcNote(JSScript *script, jsbytecode *pc);
-
-/* XXX need cx to lock function objects declared by prolog bytecodes. */
-extern uintN
-js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
-
-extern jsbytecode *
-js_LineNumberToPC(JSScript *script, uintN lineno);
-
-extern uintN
-js_GetScriptLineExtent(JSScript *script);
-
-/*
- * If magic is non-null, js_XDRScript succeeds on magic number mismatch but
- * returns false in *magic; it reflects a match via a true *magic out param.
- * If magic is null, js_XDRScript returns false on bad magic number errors,
- * which it reports.
- *
- * NB: callers must call js_CallNewScriptHook after successful JSXDR_DECODE
- * and subsequent set-up of owning function or script object, if any.
- */
-extern JSBool
-js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic);
-
-JS_END_EXTERN_C
-
-#endif /* jsscript_h___ */
diff --git a/src/extension/script/js/jsshell.msg b/src/extension/script/js/jsshell.msg
deleted file mode 100644
index 4b811ac01..000000000
--- a/src/extension/script/js/jsshell.msg
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- Error messages for JSShell. See js.msg for format.
-*/
-
-MSG_DEF(JSSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
-MSG_DEF(JSSMSG_CANT_OPEN, 1, 2, JSEXN_NONE, "can't open {0}: {1}")
-MSG_DEF(JSSMSG_TRAP_USAGE, 2, 0, JSEXN_NONE, "usage: trap [fun] [pc] expr")
-MSG_DEF(JSSMSG_LINE2PC_USAGE, 3, 0, JSEXN_NONE, "usage: line2pc [fun] line")
-MSG_DEF(JSSMSG_FILE_SCRIPTS_ONLY, 4, 0, JSEXN_NONE, "only works on JS scripts read from files")
-MSG_DEF(JSSMSG_UNEXPECTED_EOF, 5, 1, JSEXN_NONE, "unexpected EOF in {0}")
-MSG_DEF(JSSMSG_DOEXP_USAGE, 6, 0, JSEXN_NONE, "usage: doexp obj id")
diff --git a/src/extension/script/js/jsstddef.h b/src/extension/script/js/jsstddef.h
deleted file mode 100644
index 0d87b0c0c..000000000
--- a/src/extension/script/js/jsstddef.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * stddef inclusion here to first declare ptrdif as a signed long instead of a
- * signed int.
- */
-
-#ifdef _WINDOWS
-# ifndef XP_WIN
-# define XP_WIN
-# endif
-#if defined(_WIN32) || defined(WIN32)
-# ifndef XP_WIN32
-# define XP_WIN32
-# endif
-#else
-# ifndef XP_WIN16
-# define XP_WIN16
-# endif
-#endif
-#endif
-
-#ifdef XP_WIN16
-#ifndef _PTRDIFF_T_DEFINED
-typedef long ptrdiff_t;
-
-/*
- * The Win16 compiler treats pointer differences as 16-bit signed values.
- * This macro allows us to treat them as 17-bit signed values, stored in
- * a 32-bit type.
- */
-#define PTRDIFF(p1, p2, type) \
- ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type))
-
-#define _PTRDIFF_T_DEFINED
-#endif /*_PTRDIFF_T_DEFINED*/
-#else /*WIN16*/
-
-#define PTRDIFF(p1, p2, type) \
- ((p1) - (p2))
-
-#endif
-
-#include <stddef.h>
-
-
diff --git a/src/extension/script/js/jsstr.c b/src/extension/script/js/jsstr.c
deleted file mode 100644
index e143ab8df..000000000
--- a/src/extension/script/js/jsstr.c
+++ /dev/null
@@ -1,4502 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * JS string type implementation.
- *
- * In order to avoid unnecessary js_LockGCThing/js_UnlockGCThing calls, these
- * native methods store strings (possibly newborn) converted from their 'this'
- * parameter and arguments on the stack: 'this' conversions at argv[-1], arg
- * conversions at their index (argv[0], argv[1]). This is a legitimate method
- * of rooting things that might lose their newborn root due to subsequent GC
- * allocations in the same native method.
- */
-#include "jsstddef.h"
-#include <stdlib.h>
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jshash.h" /* Added by JSIFY */
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jsarray.h"
-#include "jsatom.h"
-#include "jsbool.h"
-#include "jscntxt.h"
-#include "jsconfig.h"
-#include "jsgc.h"
-#include "jsinterp.h"
-#include "jslock.h"
-#include "jsnum.h"
-#include "jsobj.h"
-#include "jsopcode.h"
-#include "jsregexp.h"
-#include "jsstr.h"
-
-#if JS_HAS_REPLACE_LAMBDA
-#include "jsinterp.h"
-#endif
-
-#define JSSTRDEP_RECURSION_LIMIT 100
-
-size_t
-js_MinimizeDependentStrings(JSString *str, int level, JSString **basep)
-{
- JSString *base;
- size_t start, length;
-
- JS_ASSERT(JSSTRING_IS_DEPENDENT(str));
- base = JSSTRDEP_BASE(str);
- start = JSSTRDEP_START(str);
- if (JSSTRING_IS_DEPENDENT(base)) {
- if (level < JSSTRDEP_RECURSION_LIMIT) {
- start += js_MinimizeDependentStrings(base, level + 1, &base);
- } else {
- do {
- start += JSSTRDEP_START(base);
- base = JSSTRDEP_BASE(base);
- } while (JSSTRING_IS_DEPENDENT(base));
- }
- if (start == 0) {
- JS_ASSERT(JSSTRING_IS_PREFIX(str));
- JSPREFIX_SET_BASE(str, base);
- } else if (start <= JSSTRDEP_START_MASK) {
- length = JSSTRDEP_LENGTH(str);
- JSSTRDEP_SET_START_AND_LENGTH(str, start, length);
- JSSTRDEP_SET_BASE(str, base);
- }
- }
- *basep = base;
- return start;
-}
-
-jschar *
-js_GetDependentStringChars(JSString *str)
-{
- size_t start;
- JSString *base;
-
- start = js_MinimizeDependentStrings(str, 0, &base);
- JS_ASSERT(!JSSTRING_IS_DEPENDENT(base));
- JS_ASSERT(start < base->length);
- return base->chars + start;
-}
-
-jschar *
-js_GetStringChars(JSString *str)
-{
- if (JSSTRING_IS_DEPENDENT(str) && !js_UndependString(NULL, str))
- return NULL;
-
- *js_GetGCThingFlags(str) &= ~GCF_MUTABLE;
- return str->chars;
-}
-
-JSString *
-js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
-{
- size_t rn, ln, lrdist, n;
- jschar *rs, *ls, *s;
- JSDependentString *ldep; /* non-null if left should become dependent */
- JSString *str;
-
- if (JSSTRING_IS_DEPENDENT(right)) {
- rn = JSSTRDEP_LENGTH(right);
- rs = JSSTRDEP_CHARS(right);
- } else {
- rn = right->length;
- rs = right->chars;
- }
- if (rn == 0)
- return left;
-
- if (JSSTRING_IS_DEPENDENT(left) ||
- !(*js_GetGCThingFlags(left) & GCF_MUTABLE)) {
- /* We must copy if left does not own a buffer to realloc. */
- ln = JSSTRING_LENGTH(left);
- if (ln == 0)
- return right;
- ls = JSSTRING_CHARS(left);
- s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar));
- if (!s)
- return NULL;
- js_strncpy(s, ls, ln);
- ldep = NULL;
- } else {
- /* We can realloc left's space and make it depend on our result. */
- ln = left->length;
- if (ln == 0)
- return right;
- ls = left->chars;
- s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));
- if (!s)
- return NULL;
-
- /* Take care: right could depend on left! */
- lrdist = (size_t)(rs - ls);
- if (lrdist < ln)
- rs = s + lrdist;
- left->chars = ls = s;
- ldep = JSSTRDEP(left);
- }
-
- js_strncpy(s + ln, rs, rn);
- n = ln + rn;
- s[n] = 0;
- str = js_NewString(cx, s, n, GCF_MUTABLE);
- if (!str) {
- /* Out of memory: clean up any space we (re-)allocated. */
- if (!ldep) {
- JS_free(cx, s);
- } else {
- s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar));
- if (s)
- left->chars = s;
- }
- } else {
- /* Morph left into a dependent prefix if we realloc'd its buffer. */
- if (ldep) {
- JSPREFIX_SET_LENGTH(ldep, ln);
- JSPREFIX_SET_BASE(ldep, str);
-#ifdef DEBUG
- {
- JSRuntime *rt = cx->runtime;
- JS_RUNTIME_METER(rt, liveDependentStrings);
- JS_RUNTIME_METER(rt, totalDependentStrings);
- JS_LOCK_RUNTIME_VOID(rt,
- (rt->strdepLengthSum += (double)ln,
- rt->strdepLengthSquaredSum += (double)ln * (double)ln));
- }
-#endif
- }
- }
-
- return str;
-}
-
-/*
- * May be called with null cx by js_GetStringChars, above; and by the jslock.c
- * MAKE_STRING_IMMUTABLE file-local macro.
- */
-const jschar *
-js_UndependString(JSContext *cx, JSString *str)
-{
- size_t n, size;
- jschar *s;
-
- if (JSSTRING_IS_DEPENDENT(str)) {
- n = JSSTRDEP_LENGTH(str);
- size = (n + 1) * sizeof(jschar);
- s = (jschar *) (cx ? JS_malloc(cx, size) : malloc(size));
- if (!s)
- return NULL;
-
- js_strncpy(s, JSSTRDEP_CHARS(str), n);
- s[n] = 0;
- str->length = n;
- str->chars = s;
-
-#ifdef DEBUG
- if (cx) {
- JSRuntime *rt = cx->runtime;
- JS_RUNTIME_UNMETER(rt, liveDependentStrings);
- JS_RUNTIME_UNMETER(rt, totalDependentStrings);
- JS_LOCK_RUNTIME_VOID(rt,
- (rt->strdepLengthSum -= (double)n,
- rt->strdepLengthSquaredSum -= (double)n * (double)n));
- }
-#endif
- }
-
- return str->chars;
-}
-
-/*
- * Forward declarations for URI encode/decode and helper routines
- */
-static JSBool
-str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-static JSBool
-str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-static JSBool
-str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-static JSBool
-str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-static int
-OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char);
-
-static uint32
-Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length);
-
-/*
- * Contributions from the String class to the set of methods defined for the
- * global object. escape and unescape used to be defined in the Mocha library,
- * but as ECMA decided to spec them, they've been moved to the core engine
- * and made ECMA-compliant. (Incomplete escapes are interpreted as literal
- * characters by unescape.)
- */
-
-/*
- * Stuff to emulate the old libmocha escape, which took a second argument
- * giving the type of escape to perform. Retained for compatibility, and
- * copied here to avoid reliance on net.h, mkparse.c/NET_EscapeBytes.
- */
-
-#define URL_XALPHAS ((uint8) 1)
-#define URL_XPALPHAS ((uint8) 2)
-#define URL_PATH ((uint8) 4)
-
-static const uint8 urlCharType[256] =
-/* Bit 0 xalpha -- the alphas
- * Bit 1 xpalpha -- as xalpha but
- * converts spaces to plus and plus to %20
- * Bit 2 ... path -- as xalphas but doesn't escape '/'
- */
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
- 0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */
- 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
- 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
- 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */
- 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */
- 0, };
-
-/* This matches the ECMA escape set when mask is 7 (default.) */
-
-#define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask))
-
-/* See ECMA-262 15.1.2.4. */
-JSBool
-js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- size_t i, ni, length, newlength;
- const jschar *chars;
- jschar *newchars;
- jschar ch;
- jsint mask;
- jsdouble d;
- const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
- if (argc > 1) {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- if (!JSDOUBLE_IS_FINITE(d) ||
- (mask = (jsint)d) != d ||
- mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
- {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask);
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_STRING_MASK, numBuf);
- return JS_FALSE;
- }
- }
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str);
-
- chars = JSSTRING_CHARS(str);
- length = newlength = JSSTRING_LENGTH(str);
-
- /* Take a first pass and see how big the result string will need to be. */
- for (i = 0; i < length; i++) {
- if ((ch = chars[i]) < 128 && IS_OK(ch, mask))
- continue;
- if (ch < 256) {
- if (mask == URL_XPALPHAS && ch == ' ')
- continue; /* The character will be encoded as '+' */
- newlength += 2; /* The character will be encoded as %XX */
- } else {
- newlength += 5; /* The character will be encoded as %uXXXX */
- }
- }
-
- newchars = (jschar *) JS_malloc(cx, (newlength + 1) * sizeof(jschar));
- if (!newchars)
- return JS_FALSE;
- for (i = 0, ni = 0; i < length; i++) {
- if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
- newchars[ni++] = ch;
- } else if (ch < 256) {
- if (mask == URL_XPALPHAS && ch == ' ') {
- newchars[ni++] = '+'; /* convert spaces to pluses */
- } else {
- newchars[ni++] = '%';
- newchars[ni++] = digits[ch >> 4];
- newchars[ni++] = digits[ch & 0xF];
- }
- } else {
- newchars[ni++] = '%';
- newchars[ni++] = 'u';
- newchars[ni++] = digits[ch >> 12];
- newchars[ni++] = digits[(ch & 0xF00) >> 8];
- newchars[ni++] = digits[(ch & 0xF0) >> 4];
- newchars[ni++] = digits[ch & 0xF];
- }
- }
- JS_ASSERT(ni == newlength);
- newchars[newlength] = 0;
-
- str = js_NewString(cx, newchars, newlength, 0);
- if (!str) {
- JS_free(cx, newchars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#undef IS_OK
-
-/* See ECMA-262 15.1.2.5 */
-static JSBool
-str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- size_t i, ni, length;
- const jschar *chars;
- jschar *newchars;
- jschar ch;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str);
-
- chars = JSSTRING_CHARS(str);
- length = JSSTRING_LENGTH(str);
-
- /* Don't bother allocating less space for the new string. */
- newchars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!newchars)
- return JS_FALSE;
- ni = i = 0;
- while (i < length) {
- ch = chars[i++];
- if (ch == '%') {
- if (i + 1 < length &&
- JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
- {
- ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]);
- i += 2;
- } else if (i + 4 < length && chars[i] == 'u' &&
- JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) &&
- JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4]))
- {
- ch = (((((JS7_UNHEX(chars[i + 1]) << 4)
- + JS7_UNHEX(chars[i + 2])) << 4)
- + JS7_UNHEX(chars[i + 3])) << 4)
- + JS7_UNHEX(chars[i + 4]);
- i += 5;
- }
- }
- newchars[ni++] = ch;
- }
- newchars[ni] = 0;
-
- str = js_NewString(cx, newchars, ni, 0);
- if (!str) {
- JS_free(cx, newchars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-#if JS_HAS_UNEVAL
-static JSBool
-str_uneval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToSource(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif
-
-const char js_escape_str[] = "escape";
-const char js_unescape_str[] = "unescape";
-#if JS_HAS_UNEVAL
-const char js_uneval_str[] = "uneval";
-#endif
-const char js_decodeURI_str[] = "decodeURI";
-const char js_encodeURI_str[] = "encodeURI";
-const char js_decodeURIComponent_str[] = "decodeURIComponent";
-const char js_encodeURIComponent_str[] = "encodeURIComponent";
-
-static JSFunctionSpec string_functions[] = {
- {js_escape_str, js_str_escape, 1,0,0},
- {js_unescape_str, str_unescape, 1,0,0},
-#if JS_HAS_UNEVAL
- {js_uneval_str, str_uneval, 1,0,0},
-#endif
- {js_decodeURI_str, str_decodeURI, 1,0,0},
- {js_encodeURI_str, str_encodeURI, 1,0,0},
- {js_decodeURIComponent_str, str_decodeURI_Component, 1,0,0},
- {js_encodeURIComponent_str, str_encodeURI_Component, 1,0,0},
-
- {0,0,0,0,0}
-};
-
-jschar js_empty_ucstr[] = {0};
-JSSubString js_EmptySubString = {0, js_empty_ucstr};
-
-enum string_tinyid {
- STRING_LENGTH = -1
-};
-
-static JSPropertySpec string_props[] = {
- {js_length_str, STRING_LENGTH,
- JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0},
- {0,0,0,0,0}
-};
-
-static JSBool
-str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
- JSString *str;
- jsint slot;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- slot = JSVAL_TO_INT(id);
- if (slot == STRING_LENGTH)
- *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));
- return JS_TRUE;
-}
-
-#define STRING_ELEMENT_ATTRS (JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT)
-
-static JSBool
-str_enumerate(JSContext *cx, JSObject *obj)
-{
- JSString *str, *str1;
- size_t i, length;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- length = JSSTRING_LENGTH(str);
- for (i = 0; i < length; i++) {
- str1 = js_NewDependentString(cx, str, i, 1, 0);
- if (!str1)
- return JS_FALSE;
- if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(i),
- STRING_TO_JSVAL(str1), NULL, NULL,
- STRING_ELEMENT_ATTRS, NULL)) {
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-static JSBool
-str_resolve(JSContext *cx, JSObject *obj, jsval id)
-{
- JSString *str, *str1;
- jsint slot;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- slot = JSVAL_TO_INT(id);
- if ((size_t)slot < JSSTRING_LENGTH(str)) {
- str1 = js_NewDependentString(cx, str, (size_t)slot, 1, 0);
- if (!str1)
- return JS_FALSE;
- if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(slot),
- STRING_TO_JSVAL(str1), NULL, NULL,
- STRING_ELEMENT_ATTRS, NULL)) {
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-static JSClass string_class = {
- js_String_str,
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, str_getProperty, JS_PropertyStub,
- str_enumerate, str_resolve, JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-#if JS_HAS_TOSOURCE
-
-/*
- * String.prototype.quote is generic (as are most string methods), unlike
- * toSource, toString, and valueOf.
- */
-static JSBool
-str_quote(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- str = js_QuoteString(cx, str, '"');
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-str_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
- JSString *str;
- size_t i, j, k, n;
- char buf[16];
- jschar *s, *t;
-
- if (!JS_InstanceOf(cx, obj, &string_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (!JSVAL_IS_STRING(v))
- return js_obj_toSource(cx, obj, argc, argv, rval);
- str = js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
- if (!str)
- return JS_FALSE;
- j = JS_snprintf(buf, sizeof buf, "(new %s(", string_class.name);
- s = JSSTRING_CHARS(str);
- k = JSSTRING_LENGTH(str);
- n = j + k + 2;
- t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
- if (!t)
- return JS_FALSE;
- for (i = 0; i < j; i++)
- t[i] = buf[i];
- for (j = 0; j < k; i++, j++)
- t[i] = s[j];
- t[i++] = ')';
- t[i++] = ')';
- t[i] = 0;
- str = js_NewString(cx, t, n, 0);
- if (!str) {
- JS_free(cx, t);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-#endif /* JS_HAS_TOSOURCE */
-
-static JSBool
-str_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- jsval v;
-
- if (!JS_InstanceOf(cx, obj, &string_class, argv))
- return JS_FALSE;
- v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- if (!JSVAL_IS_STRING(v))
- return js_obj_toString(cx, obj, argc, argv, rval);
- *rval = v;
- return JS_TRUE;
-}
-
-static JSBool
-str_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- if (!JS_InstanceOf(cx, obj, &string_class, argv))
- return JS_FALSE;
- *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
- return JS_TRUE;
-}
-
-/*
- * Java-like string native methods.
- */
-static JSBool
-str_substring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
- jsdouble d;
- jsdouble length, begin, end;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (argc != 0) {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- length = JSSTRING_LENGTH(str);
- begin = js_DoubleToInteger(d);
- if (begin < 0)
- begin = 0;
- else if (begin > length)
- begin = length;
-
- if (argc == 1) {
- end = length;
- } else {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- end = js_DoubleToInteger(d);
- if (end < 0)
- end = 0;
- else if (end > length)
- end = length;
- if (end < begin) {
- if (cx->version != JSVERSION_1_2) {
- /* XXX emulate old JDK1.0 java.lang.String.substring. */
- jsdouble tmp = begin;
- begin = end;
- end = tmp;
- } else {
- end = begin;
- }
- }
- }
-
- str = js_NewDependentString(cx, str, (size_t)begin,
- (size_t)(end - begin), 0);
- if (!str)
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-str_toLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
- size_t i, n;
- jschar *s, *news;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- n = JSSTRING_LENGTH(str);
- news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
- if (!news)
- return JS_FALSE;
- s = JSSTRING_CHARS(str);
- for (i = 0; i < n; i++)
- news[i] = JS_TOLOWER(s[i]);
- news[n] = 0;
- str = js_NewString(cx, news, n, 0);
- if (!str) {
- JS_free(cx, news);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-str_toLocaleLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- /*
- * Forcefully ignore the first (or any) argument and return toLowerCase(),
- * ECMA has reserved that argument, presumably for defining the locale.
- */
- if (cx->localeCallbacks && cx->localeCallbacks->localeToLowerCase) {
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- return cx->localeCallbacks->localeToLowerCase(cx, str, rval);
- }
- return str_toLowerCase(cx, obj, 0, argv, rval);
-}
-
-static JSBool
-str_toUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
- size_t i, n;
- jschar *s, *news;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- n = JSSTRING_LENGTH(str);
- news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
- if (!news)
- return JS_FALSE;
- s = JSSTRING_CHARS(str);
- for (i = 0; i < n; i++)
- news[i] = JS_TOUPPER(s[i]);
- news[n] = 0;
- str = js_NewString(cx, news, n, 0);
- if (!str) {
- JS_free(cx, news);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-str_toLocaleUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- /*
- * Forcefully ignore the first (or any) argument and return toUpperCase(),
- * ECMA has reserved that argument, presumbaly for defining the locale.
- */
- if (cx->localeCallbacks && cx->localeCallbacks->localeToUpperCase) {
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- return cx->localeCallbacks->localeToUpperCase(cx, str, rval);
- }
- return str_toUpperCase(cx, obj, 0, argv, rval);
-}
-
-static JSBool
-str_localeCompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str, *thatStr;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (argc == 0) {
- *rval = JSVAL_ZERO;
- } else {
- thatStr = js_ValueToString(cx, argv[0]);
- if (!thatStr)
- return JS_FALSE;
- if (cx->localeCallbacks && cx->localeCallbacks->localeCompare)
- return cx->localeCallbacks->localeCompare(cx, str, thatStr, rval);
- *rval = INT_TO_JSVAL(js_CompareStrings(str, thatStr));
- }
- return JS_TRUE;
-}
-
-static JSBool
-str_charAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsdouble d;
- size_t index;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (argc == 0) {
- d = 0.0;
- } else {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- }
-
- if (d < 0 || JSSTRING_LENGTH(str) <= d) {
- *rval = JS_GetEmptyStringValue(cx);
- } else {
- index = (size_t)d;
- str = js_NewDependentString(cx, str, index, 1, 0);
- if (!str)
- return JS_FALSE;
- *rval = STRING_TO_JSVAL(str);
- }
- return JS_TRUE;
-}
-
-static JSBool
-str_charCodeAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
- jsdouble d;
- size_t index;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (argc == 0) {
- d = 0.0;
- } else {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- }
-
- if (d < 0 || JSSTRING_LENGTH(str) <= d) {
- *rval = JS_GetNaNValue(cx);
- } else {
- index = (size_t)d;
- *rval = INT_TO_JSVAL((jsint) JSSTRING_CHARS(str)[index]);
- }
- return JS_TRUE;
-}
-
-jsint
-js_BoyerMooreHorspool(const jschar *text, jsint textlen,
- const jschar *pat, jsint patlen,
- jsint start)
-{
- jsint i, j, k, m;
- uint8 skip[BMH_CHARSET_SIZE];
- jschar c;
-
- JS_ASSERT(0 < patlen && patlen <= BMH_PATLEN_MAX);
- for (i = 0; i < BMH_CHARSET_SIZE; i++)
- skip[i] = (uint8)patlen;
- m = patlen - 1;
- for (i = 0; i < m; i++) {
- c = pat[i];
- if (c >= BMH_CHARSET_SIZE)
- return BMH_BAD_PATTERN;
- skip[c] = (uint8)(m - i);
- }
- for (k = start + m;
- k < textlen;
- k += ((c = text[k]) >= BMH_CHARSET_SIZE) ? patlen : skip[c]) {
- for (i = k, j = m; ; i--, j--) {
- if (j < 0)
- return i + 1;
- if (text[i] != pat[j])
- break;
- }
- }
- return -1;
-}
-
-static JSBool
-str_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str, *str2;
- jsint i, j, index, textlen, patlen;
- const jschar *text, *pat;
- jsdouble d;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
- text = JSSTRING_CHARS(str);
- textlen = (jsint) JSSTRING_LENGTH(str);
-
- str2 = js_ValueToString(cx, argv[0]);
- if (!str2)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str2);
- pat = JSSTRING_CHARS(str2);
- patlen = (jsint) JSSTRING_LENGTH(str2);
-
- if (argc > 1) {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- d = js_DoubleToInteger(d);
- if (d < 0)
- i = 0;
- else if (d > textlen)
- i = textlen;
- else
- i = (jsint)d;
- } else {
- i = 0;
- }
- if (patlen == 0) {
- *rval = INT_TO_JSVAL(i);
- return JS_TRUE;
- }
-
- /* XXX tune the BMH threshold (512) */
- if ((jsuint)(patlen - 2) <= BMH_PATLEN_MAX - 2 && textlen >= 512) {
- index = js_BoyerMooreHorspool(text, textlen, pat, patlen, i);
- if (index != BMH_BAD_PATTERN)
- goto out;
- }
-
- index = -1;
- j = 0;
- while (i + j < textlen) {
- if (text[i + j] == pat[j]) {
- if (++j == patlen) {
- index = i;
- break;
- }
- } else {
- i++;
- j = 0;
- }
- }
-
-out:
- *rval = INT_TO_JSVAL(index);
- return JS_TRUE;
-}
-
-static JSBool
-str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str, *str2;
- const jschar *text, *pat;
- jsint i, j, textlen, patlen;
- jsdouble d;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
- text = JSSTRING_CHARS(str);
- textlen = (jsint) JSSTRING_LENGTH(str);
-
- str2 = js_ValueToString(cx, argv[0]);
- if (!str2)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str2);
- pat = JSSTRING_CHARS(str2);
- patlen = (jsint) JSSTRING_LENGTH(str2);
-
- if (argc > 1) {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- if (JSDOUBLE_IS_NaN(d)) {
- i = textlen;
- } else {
- d = js_DoubleToInteger(d);
- if (d < 0)
- i = 0;
- else if (d > textlen - patlen)
- i = textlen - patlen;
- else
- i = (jsint)d;
- }
- } else {
- i = textlen;
- }
-
- if (patlen == 0) {
- *rval = INT_TO_JSVAL(i);
- return JS_TRUE;
- }
-
- j = 0;
- while (i >= 0) {
- /* Don't assume that text is NUL-terminated: it could be dependent. */
- if (i + j < textlen && text[i + j] == pat[j]) {
- if (++j == patlen)
- break;
- } else {
- i--;
- j = 0;
- }
- }
- *rval = INT_TO_JSVAL(i);
- return JS_TRUE;
-}
-
-/*
- * Perl-inspired string functions.
- */
-#if JS_HAS_REGEXPS
-typedef struct GlobData {
- uintN flags; /* inout: mode and flag bits, see below */
- uintN optarg; /* in: index of optional flags argument */
- JSString *str; /* out: 'this' parameter object as string */
- JSRegExp *regexp; /* out: regexp parameter object private data */
-} GlobData;
-
-/*
- * Mode and flag bit definitions for match_or_replace's GlobData.flags field.
- */
-#define MODE_MATCH 0x00 /* in: return match array on success */
-#define MODE_REPLACE 0x01 /* in: match and replace */
-#define MODE_SEARCH 0x02 /* in: search only, return match index or -1 */
-#define GET_MODE(f) ((f) & 0x03)
-#define FORCE_FLAT 0x04 /* in: force flat (non-regexp) string match */
-#define KEEP_REGEXP 0x08 /* inout: keep GlobData.regexp alive for caller
- of match_or_replace; if set on input
- but clear on output, regexp ownership
- does not pass to caller */
-#define GLOBAL_REGEXP 0x10 /* out: regexp had the 'g' flag */
-
-static JSBool
-match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- JSBool (*glob)(JSContext *cx, jsint count, GlobData *data),
- GlobData *data, jsval *rval)
-{
- JSString *str, *src, *opt;
- JSObject *reobj;
- JSRegExp *re;
- size_t index, length;
- JSBool ok, test;
- jsint count;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
- data->str = str;
-
- if (JSVAL_IS_REGEXP(cx, argv[0])) {
- reobj = JSVAL_TO_OBJECT(argv[0]);
- re = (JSRegExp *) JS_GetPrivate(cx, reobj);
- } else {
- src = js_ValueToString(cx, argv[0]);
- if (!src)
- return JS_FALSE;
- if (data->optarg < argc) {
- argv[0] = STRING_TO_JSVAL(src);
- opt = js_ValueToString(cx, argv[data->optarg]);
- if (!opt)
- return JS_FALSE;
- } else {
- opt = NULL;
- }
- re = js_NewRegExpOpt(cx, NULL, src, opt,
- (data->flags & FORCE_FLAT) != 0);
- if (!re)
- return JS_FALSE;
- reobj = NULL;
- }
- data->regexp = re;
-
- if (re->flags & JSREG_GLOB)
- data->flags |= GLOBAL_REGEXP;
- index = 0;
- if (GET_MODE(data->flags) == MODE_SEARCH) {
- ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval);
- if (ok) {
- *rval = (*rval == JSVAL_TRUE)
- ? INT_TO_JSVAL(cx->regExpStatics.leftContext.length)
- : INT_TO_JSVAL(-1);
- }
- } else if (data->flags & GLOBAL_REGEXP) {
- if (reobj) {
- /* Set the lastIndex property's reserved slot to 0. */
- ok = js_SetLastIndex(cx, reobj, 0);
- if (!ok)
- return JS_FALSE;
- } else {
- ok = JS_TRUE;
- }
- length = JSSTRING_LENGTH(str);
- for (count = 0; index <= length; count++) {
- ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval);
- if (!ok || *rval != JSVAL_TRUE)
- break;
- ok = glob(cx, count, data);
- if (!ok)
- break;
- if (cx->regExpStatics.lastMatch.length == 0) {
- if (index == length)
- break;
- index++;
- }
- }
- } else {
- if (GET_MODE(data->flags) == MODE_REPLACE) {
- test = JS_TRUE;
- } else {
- /*
- * MODE_MATCH implies str_match is being called from a script or a
- * scripted function. If the caller cares only about testing null
- * vs. non-null return value, optimize away the array object that
- * would normally be returned in *rval.
- */
- JS_ASSERT(*cx->fp->down->pc == JSOP_CALL ||
- *cx->fp->down->pc == JSOP_NEW);
- JS_ASSERT(js_CodeSpec[*cx->fp->down->pc].length == 3);
- switch (cx->fp->down->pc[3]) {
- case JSOP_POP:
- case JSOP_IFEQ:
- case JSOP_IFNE:
- case JSOP_IFEQX:
- case JSOP_IFNEX:
- test = JS_TRUE;
- break;
- default:
- test = JS_FALSE;
- break;
- }
- }
- ok = js_ExecuteRegExp(cx, re, str, &index, test, rval);
- }
-
- if (reobj) {
- /* Tell our caller that it doesn't need to destroy data->regexp. */
- data->flags &= ~KEEP_REGEXP;
- } else if (!(data->flags & KEEP_REGEXP)) {
- /* Caller didn't want to keep data->regexp, so null and destroy it. */
- data->regexp = NULL;
- js_DestroyRegExp(cx, re);
- }
- return ok;
-}
-
-typedef struct MatchData {
- GlobData base;
- jsval *arrayval; /* NB: local root pointer */
-} MatchData;
-
-static JSBool
-match_glob(JSContext *cx, jsint count, GlobData *data)
-{
- MatchData *mdata;
- JSObject *arrayobj;
- JSSubString *matchsub;
- JSString *matchstr;
- jsval v;
-
- mdata = (MatchData *)data;
- arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval);
- if (!arrayobj) {
- arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);
- if (!arrayobj)
- return JS_FALSE;
- *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj);
- }
- matchsub = &cx->regExpStatics.lastMatch;
- matchstr = js_NewStringCopyN(cx, matchsub->chars, matchsub->length, 0);
- if (!matchstr)
- return JS_FALSE;
- v = STRING_TO_JSVAL(matchstr);
- return js_SetProperty(cx, arrayobj, INT_TO_JSVAL(count), &v);
-}
-
-static JSBool
-str_match(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- MatchData mdata;
- JSBool ok;
-
- mdata.base.flags = MODE_MATCH;
- mdata.base.optarg = 1;
- mdata.arrayval = &argv[2];
- *mdata.arrayval = JSVAL_NULL;
- ok = match_or_replace(cx, obj, argc, argv, match_glob, &mdata.base, rval);
- if (ok && !JSVAL_IS_NULL(*mdata.arrayval))
- *rval = *mdata.arrayval;
- return ok;
-}
-
-static JSBool
-str_search(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- GlobData data;
-
- data.flags = MODE_SEARCH;
- data.optarg = 1;
- return match_or_replace(cx, obj, argc, argv, NULL, &data, rval);
-}
-
-typedef struct ReplaceData {
- GlobData base; /* base struct state */
- JSObject *lambda; /* replacement function object or null */
- JSString *repstr; /* replacement string */
- jschar *dollar; /* null or pointer to first $ in repstr */
- jschar *dollarEnd; /* limit pointer for js_strchr_limit */
- jschar *chars; /* result chars, null initially */
- size_t length; /* result length, 0 initially */
- jsint index; /* index in result of next replacement */
- jsint leftIndex; /* left context index in base.str->chars */
- JSSubString dollarStr; /* for "$$" interpret_dollar result */
-} ReplaceData;
-
-static JSSubString *
-interpret_dollar(JSContext *cx, jschar *dp, ReplaceData *rdata, size_t *skip)
-{
- JSRegExpStatics *res;
- jschar dc, *cp;
- uintN num, tmp;
- JSString *str;
-
- JS_ASSERT(*dp == '$');
-
- /*
- * Allow a real backslash (literal "\\" before "$1") to escape "$1", e.g.
- * Do this only for versions strictly less than ECMAv3.
- */
- if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) {
- if (dp > JSSTRING_CHARS(rdata->repstr) && dp[-1] == '\\')
- return NULL;
- }
-
- /* Interpret all Perl match-induced dollar variables. */
- res = &cx->regExpStatics;
- dc = dp[1];
- if (JS7_ISDEC(dc)) {
- if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) {
- if (dc == '0')
- return NULL;
-
- /* Check for overflow to avoid gobbling arbitrary decimal digits. */
- num = 0;
- cp = dp;
- while ((dc = *++cp) != 0 && JS7_ISDEC(dc)) {
- tmp = 10 * num + JS7_UNDEC(dc);
- if (tmp < num)
- break;
- num = tmp;
- }
- } else { /* ECMA 3, 1-9 or 01-99 */
- num = JS7_UNDEC(dc);
- if (num > res->parenCount)
- return NULL;
- cp = dp + 2;
- dc = *cp;
- if ((dc != 0) && JS7_ISDEC(dc)) {
- tmp = 10 * num + JS7_UNDEC(dc);
- if (tmp <= res->parenCount) {
- cp++;
- num = tmp;
- }
- }
- if (num == 0)
- return NULL;
- }
- /* Adjust num from 1 $n-origin to 0 array-index-origin. */
- num--;
- *skip = cp - dp;
- return REGEXP_PAREN_SUBSTRING(res, num);
- }
-
- *skip = 2;
- switch (dc) {
- case '$':
- rdata->dollarStr.chars = dp;
- rdata->dollarStr.length = 1;
- return &rdata->dollarStr;
- case '&':
- return &res->lastMatch;
- case '+':
- return &res->lastParen;
- case '`':
- if (cx->version == JSVERSION_1_2) {
- /*
- * JS1.2 imitated the Perl4 bug where left context at each step
- * in an iterative use of a global regexp started from last match,
- * not from the start of the target string. But Perl4 does start
- * $` at the beginning of the target string when it is used in a
- * substitution, so we emulate that special case here.
- */
- str = rdata->base.str;
- res->leftContext.chars = JSSTRING_CHARS(str);
- res->leftContext.length = res->lastMatch.chars
- - JSSTRING_CHARS(str);
- }
- return &res->leftContext;
- case '\'':
- return &res->rightContext;
- }
- return NULL;
-}
-
-static JSBool
-find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
-{
- JSString *repstr;
- size_t replen, skip;
- jschar *dp, *ep;
- JSSubString *sub;
-#if JS_HAS_REPLACE_LAMBDA
- JSObject *lambda;
-
- lambda = rdata->lambda;
- if (lambda) {
- uintN argc, i, j, m, n, p;
- jsval *sp, *oldsp, rval;
- void *mark;
- JSStackFrame *fp;
- JSBool ok;
-
- /*
- * Save the rightContext from the current regexp, since it
- * gets stuck at the end of the replacement string and may
- * be clobbered by a RegExp usage in the lambda function.
- */
- JSSubString saveRightContext = cx->regExpStatics.rightContext;
-
- /*
- * In the lambda case, not only do we find the replacement string's
- * length, we compute repstr and return it via rdata for use within
- * do_replace. The lambda is called with arguments ($&, $1, $2, ...,
- * index, input), i.e., all the properties of a regexp match array.
- * For $&, etc., we must create string jsvals from cx->regExpStatics.
- * We grab up stack space to keep the newborn strings GC-rooted.
- */
- p = rdata->base.regexp->parenCount;
- argc = 1 + p + 2;
- sp = js_AllocStack(cx, 2 + argc, &mark);
- if (!sp)
- return JS_FALSE;
-
- /* Push lambda and its 'this' parameter. */
- *sp++ = OBJECT_TO_JSVAL(lambda);
- *sp++ = OBJECT_TO_JSVAL(OBJ_GET_PARENT(cx, lambda));
-
-#define PUSH_REGEXP_STATIC(sub) \
- JS_BEGIN_MACRO \
- JSString *str = js_NewStringCopyN(cx, \
- cx->regExpStatics.sub.chars, \
- cx->regExpStatics.sub.length, \
- 0); \
- if (!str) { \
- ok = JS_FALSE; \
- goto lambda_out; \
- } \
- *sp++ = STRING_TO_JSVAL(str); \
- JS_END_MACRO
-
- /* Push $&, $1, $2, ... */
- PUSH_REGEXP_STATIC(lastMatch);
- i = 0;
- m = cx->regExpStatics.parenCount;
- n = JS_MIN(m, 9);
- for (j = 0; i < n; i++, j++)
- PUSH_REGEXP_STATIC(parens[j]);
- for (j = 0; i < m; i++, j++)
- PUSH_REGEXP_STATIC(moreParens[j]);
-
-#undef PUSH_REGEXP_STATIC
-
- /* Make sure to push undefined for any unmatched parens. */
- for (; i < p; i++)
- *sp++ = JSVAL_VOID;
-
- /* Push match index and input string. */
- *sp++ = INT_TO_JSVAL((jsint)cx->regExpStatics.leftContext.length);
- *sp++ = STRING_TO_JSVAL(rdata->base.str);
-
- /* Lift current frame to include the args and do the call. */
- fp = cx->fp;
- oldsp = fp->sp;
- fp->sp = sp;
- ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
- rval = fp->sp[-1];
- fp->sp = oldsp;
-
- if (ok) {
- /*
- * NB: we count on the newborn string root to hold any string
- * created by this js_ValueToString that would otherwise be GC-
- * able, until we use rdata->repstr in do_replace.
- */
- repstr = js_ValueToString(cx, rval);
- if (!repstr) {
- ok = JS_FALSE;
- } else {
- rdata->repstr = repstr;
- *sizep = JSSTRING_LENGTH(repstr);
- }
- }
-
- lambda_out:
- js_FreeStack(cx, mark);
- cx->regExpStatics.rightContext = saveRightContext;
- return ok;
- }
-#endif /* JS_HAS_REPLACE_LAMBDA */
-
- repstr = rdata->repstr;
- replen = JSSTRING_LENGTH(repstr);
- for (dp = rdata->dollar, ep = rdata->dollarEnd; dp;
- dp = js_strchr_limit(dp, '$', ep)) {
- sub = interpret_dollar(cx, dp, rdata, &skip);
- if (sub) {
- replen += sub->length - skip;
- dp += skip;
- }
- else
- dp++;
- }
- *sizep = replen;
- return JS_TRUE;
-}
-
-static void
-do_replace(JSContext *cx, ReplaceData *rdata, jschar *chars)
-{
- JSString *repstr;
- jschar *bp, *cp, *dp, *ep;
- size_t len, skip;
- JSSubString *sub;
-
- repstr = rdata->repstr;
- bp = cp = JSSTRING_CHARS(repstr);
- for (dp = rdata->dollar, ep = rdata->dollarEnd; dp;
- dp = js_strchr_limit(dp, '$', ep)) {
- len = dp - cp;
- js_strncpy(chars, cp, len);
- chars += len;
- cp = dp;
- sub = interpret_dollar(cx, dp, rdata, &skip);
- if (sub) {
- len = sub->length;
- js_strncpy(chars, sub->chars, len);
- chars += len;
- cp += skip;
- dp += skip;
- } else {
- dp++;
- }
- }
- js_strncpy(chars, cp, JSSTRING_LENGTH(repstr) - (cp - bp));
-}
-
-static JSBool
-replace_glob(JSContext *cx, jsint count, GlobData *data)
-{
- ReplaceData *rdata;
- JSString *str;
- size_t leftoff, leftlen, replen, growth;
- const jschar *left;
- jschar *chars;
-
- rdata = (ReplaceData *)data;
- str = data->str;
- leftoff = rdata->leftIndex;
- left = JSSTRING_CHARS(str) + leftoff;
- leftlen = cx->regExpStatics.lastMatch.chars - left;
- rdata->leftIndex = cx->regExpStatics.lastMatch.chars - JSSTRING_CHARS(str);
- rdata->leftIndex += cx->regExpStatics.lastMatch.length;
- if (!find_replen(cx, rdata, &replen))
- return JS_FALSE;
- growth = leftlen + replen;
- chars = (jschar *)
- (rdata->chars
- ? JS_realloc(cx, rdata->chars, (rdata->length + growth + 1)
- * sizeof(jschar))
- : JS_malloc(cx, (growth + 1) * sizeof(jschar)));
- if (!chars) {
- JS_free(cx, rdata->chars);
- rdata->chars = NULL;
- return JS_FALSE;
- }
- rdata->chars = chars;
- rdata->length += growth;
- chars += rdata->index;
- rdata->index += growth;
- js_strncpy(chars, left, leftlen);
- chars += leftlen;
- do_replace(cx, rdata, chars);
- return JS_TRUE;
-}
-
-static JSBool
-str_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSObject *lambda;
- JSString *repstr, *str;
- ReplaceData rdata;
- JSBool ok;
- jschar *chars;
- size_t leftlen, rightlen, length;
-
-#if JS_HAS_REPLACE_LAMBDA
- if (JS_TypeOfValue(cx, argv[1]) == JSTYPE_FUNCTION) {
- lambda = JSVAL_TO_OBJECT(argv[1]);
- repstr = NULL;
- } else
-#endif
- {
- if (!JS_ConvertValue(cx, argv[1], JSTYPE_STRING, &argv[1]))
- return JS_FALSE;
- repstr = JSVAL_TO_STRING(argv[1]);
- lambda = NULL;
- }
-
- /*
- * For ECMA Edition 3, the first argument is to be converted to a string
- * to match in a "flat" sense (without regular expression metachars having
- * special meanings) UNLESS the first arg is a RegExp object.
- */
- rdata.base.flags = MODE_REPLACE | KEEP_REGEXP;
- if (cx->version == JSVERSION_DEFAULT || cx->version > JSVERSION_1_4)
- rdata.base.flags |= FORCE_FLAT;
- rdata.base.optarg = 2;
-
- rdata.lambda = lambda;
- rdata.repstr = repstr;
- if (repstr) {
- rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr);
- rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$',
- rdata.dollarEnd);
- } else {
- rdata.dollar = rdata.dollarEnd = NULL;
- }
- rdata.chars = NULL;
- rdata.length = 0;
- rdata.index = 0;
- rdata.leftIndex = 0;
-
- ok = match_or_replace(cx, obj, argc, argv, replace_glob, &rdata.base, rval);
- if (!ok)
- return JS_FALSE;
-
- if (!rdata.chars) {
- if ((rdata.base.flags & GLOBAL_REGEXP) || *rval != JSVAL_TRUE) {
- /* Didn't match even once. */
- *rval = STRING_TO_JSVAL(rdata.base.str);
- goto out;
- }
- leftlen = cx->regExpStatics.leftContext.length;
- ok = find_replen(cx, &rdata, &length);
- if (!ok)
- goto out;
- length += leftlen;
- chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!chars) {
- ok = JS_FALSE;
- goto out;
- }
- js_strncpy(chars, cx->regExpStatics.leftContext.chars, leftlen);
- do_replace(cx, &rdata, chars + leftlen);
- rdata.chars = chars;
- rdata.length = length;
- }
-
- rightlen = cx->regExpStatics.rightContext.length;
- length = rdata.length + rightlen;
- chars = (jschar *)
- JS_realloc(cx, rdata.chars, (length + 1) * sizeof(jschar));
- if (!chars) {
- JS_free(cx, rdata.chars);
- ok = JS_FALSE;
- goto out;
- }
- js_strncpy(chars + rdata.length, cx->regExpStatics.rightContext.chars,
- rightlen);
- chars[length] = 0;
-
- str = js_NewString(cx, chars, length, 0);
- if (!str) {
- JS_free(cx, chars);
- ok = JS_FALSE;
- goto out;
- }
- *rval = STRING_TO_JSVAL(str);
-
-out:
- /* If KEEP_REGEXP is still set, it's our job to destroy regexp now. */
- if (rdata.base.flags & KEEP_REGEXP)
- js_DestroyRegExp(cx, rdata.base.regexp);
- return ok;
-}
-#endif /* JS_HAS_REGEXPS */
-
-/*
- * Subroutine used by str_split to find the next split point in str, starting
- * at offset *ip and looking either for the separator substring given by sep,
- * or for the next re match. In the re case, return the matched separator in
- * *sep, and the possibly updated offset in *ip.
- *
- * Return -2 on error, -1 on end of string, >= 0 for a valid index of the next
- * separator occurrence if found, or str->length if no separator is found.
- */
-static jsint
-find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip,
- JSSubString *sep)
-{
- jsint i, j, k;
- jschar *chars;
- size_t length;
-
- /*
- * Stop if past end of string. If at end of string, we will compare the
- * null char stored there (by js_NewString*) to sep->chars[j] in the while
- * loop at the end of this function, so that
- *
- * "ab,".split(',') => ["ab", ""]
- *
- * and the resulting array converts back to the string "ab," for symmetry.
- * However, we ape Perl and do this only if there is a sufficiently large
- * limit argument (see str_split).
- */
- i = *ip;
- if ((size_t)i > JSSTRING_LENGTH(str))
- return -1;
-
- /*
- * Perl4 special case for str.split(' '), only if the user has selected
- * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s.
- * Strange but true, apparently modeled after awk.
- *
- * NB: we set sep->length to the length of the w/s run, so we must test
- * sep->chars[1] == 0 to make sure sep is just one space.
- */
- chars = JSSTRING_CHARS(str);
- length = JSSTRING_LENGTH(str);
- if (cx->version == JSVERSION_1_2 &&
- !re && *sep->chars == ' ' && sep->chars[1] == 0) {
-
- /* Skip leading whitespace if at front of str. */
- if (i == 0) {
- while (JS_ISSPACE(chars[i]))
- i++;
- *ip = i;
- }
-
- /* Don't delimit whitespace at end of string. */
- if ((size_t)i == length)
- return -1;
-
- /* Skip over the non-whitespace chars. */
- while ((size_t)i < length && !JS_ISSPACE(chars[i]))
- i++;
-
- /* Now skip the next run of whitespace. */
- j = i;
- while ((size_t)j < length && JS_ISSPACE(chars[j]))
- j++;
-
- /* Update sep->length to count delimiter chars. */
- sep->length = (size_t)(j - i);
- return i;
- }
-
-#if JS_HAS_REGEXPS
- /*
- * Match a regular expression against the separator at or above index i.
- * Call js_ExecuteRegExp with true for the test argument. On successful
- * match, get the separator from cx->regExpStatics.lastMatch.
- */
- if (re) {
- size_t index;
- jsval rval;
-
- again:
- /* JS1.2 deviated from Perl by never matching at end of string. */
- index = (size_t)i;
- if (!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &rval))
- return -2;
- if (rval != JSVAL_TRUE) {
- /* Mismatch: ensure our caller advances i past end of string. */
- sep->length = 1;
- return length;
- }
- i = (jsint)index;
- *sep = cx->regExpStatics.lastMatch;
- if (sep->length == 0) {
- /*
- * Empty string match: never split on an empty match at the start
- * of a find_split cycle. Same rule as for an empty global match
- * in match_or_replace.
- */
- if (i == *ip) {
- /*
- * "Bump-along" to avoid sticking at an empty match, but don't
- * bump past end of string -- our caller must do that by adding
- * sep->length to our return value.
- */
- if ((size_t)i == length) {
- if (cx->version == JSVERSION_1_2) {
- sep->length = 1;
- return i;
- }
- return -1;
- }
- i++;
- goto again;
- }
- }
- JS_ASSERT((size_t)i >= sep->length);
- return i - sep->length;
- }
-#endif /* JS_HAS_REGEXPS */
-
- /*
- * Deviate from ECMA by never splitting an empty string by any separator
- * string into a non-empty array (an array of length 1 that contains the
- * empty string).
- */
- if (!JSVERSION_IS_ECMA(cx->version) && length == 0)
- return -1;
-
- /*
- * Special case: if sep is the empty string, split str into one character
- * substrings. Let our caller worry about whether to split once at end of
- * string into an empty substring.
- *
- * For 1.2 compatibility, at the end of the string, we return the length as
- * the result, and set the separator length to 1 -- this allows the caller
- * to include an additional null string at the end of the substring list.
- */
- if (sep->length == 0) {
- if (cx->version == JSVERSION_1_2) {
- if ((size_t)i == length) {
- sep->length = 1;
- return i;
- }
- return i + 1;
- }
- return ((size_t)i == length) ? -1 : i + 1;
- }
-
- /*
- * Now that we know sep is non-empty, search starting at i in str for an
- * occurrence of all of sep's chars. If we find them, return the index of
- * the first separator char. Otherwise, return length.
- */
- j = 0;
- while ((size_t)(k = i + j) < length) {
- if (chars[k] == sep->chars[j]) {
- if ((size_t)++j == sep->length)
- return i;
- } else {
- i++;
- j = 0;
- }
- }
- return k;
-}
-
-static JSBool
-str_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str, *sub;
- JSObject *arrayobj;
- jsval v;
- JSBool ok, limited;
- JSRegExp *re;
- JSSubString *sep, tmp;
- jsdouble d;
- jsint i, j;
- uint32 len, limit;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);
- if (!arrayobj)
- return JS_FALSE;
- *rval = OBJECT_TO_JSVAL(arrayobj);
-
- if (argc == 0) {
- v = STRING_TO_JSVAL(str);
- ok = JS_SetElement(cx, arrayobj, 0, &v);
- } else {
-#if JS_HAS_REGEXPS
- if (JSVAL_IS_REGEXP(cx, argv[0])) {
- re = (JSRegExp *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
- sep = &tmp;
-
- /* Set a magic value so we can detect a successful re match. */
- sep->chars = NULL;
- } else
-#endif
- {
- JSString *str2 = js_ValueToString(cx, argv[0]);
- if (!str2)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(str2);
-
- /*
- * Point sep at a local copy of str2's header because find_split
- * will modify sep->length.
- */
- tmp.length = JSSTRING_LENGTH(str2);
- tmp.chars = JSSTRING_CHARS(str2);
- sep = &tmp;
- re = NULL;
- }
-
- /* Use the second argument as the split limit, if given. */
- limited = (argc > 1) && !JSVAL_IS_VOID(argv[1]);
- limit = 0; /* Avoid warning. */
- if (limited) {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
-
- /* Clamp limit between 0 and 1 + string length. */
- if (!js_DoubleToECMAUint32(cx, d, &limit))
- return JS_FALSE;
- if (limit > JSSTRING_LENGTH(str))
- limit = 1 + JSSTRING_LENGTH(str);
- }
-
- len = i = 0;
- while ((j = find_split(cx, str, re, &i, sep)) >= 0) {
- if (limited && len >= limit)
- break;
- sub = js_NewDependentString(cx, str, i, (size_t)(j - i), 0);
- if (!sub)
- return JS_FALSE;
- v = STRING_TO_JSVAL(sub);
- if (!JS_SetElement(cx, arrayobj, len, &v))
- return JS_FALSE;
- len++;
-#if JS_HAS_REGEXPS
- /*
- * Imitate perl's feature of including parenthesized substrings
- * that matched part of the delimiter in the new array, after the
- * split substring that was delimited.
- */
- if (re && sep->chars) {
- uintN num;
- JSSubString *parsub;
-
- for (num = 0; num < cx->regExpStatics.parenCount; num++) {
- if (limited && len >= limit)
- break;
- parsub = REGEXP_PAREN_SUBSTRING(&cx->regExpStatics, num);
- sub = js_NewStringCopyN(cx, parsub->chars, parsub->length,
- 0);
- if (!sub)
- return JS_FALSE;
- v = STRING_TO_JSVAL(sub);
- if (!JS_SetElement(cx, arrayobj, len, &v))
- return JS_FALSE;
- len++;
- }
- sep->chars = NULL;
- }
-#endif
- i = j + sep->length;
- if (!JSVERSION_IS_ECMA(cx->version)) {
- /*
- * Deviate from ECMA to imitate Perl, which omits a final
- * split unless a limit argument is given and big enough.
- */
- if (!limited && (size_t)i == JSSTRING_LENGTH(str))
- break;
- }
- }
- ok = (j != -2);
- }
- return ok;
-}
-
-#if JS_HAS_PERL_SUBSTR
-static JSBool
-str_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsdouble d;
- jsdouble length, begin, end;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
-
- if (argc != 0) {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- length = JSSTRING_LENGTH(str);
- begin = js_DoubleToInteger(d);
- if (begin < 0) {
- begin += length;
- if (begin < 0)
- begin = 0;
- } else if (begin > length) {
- begin = length;
- }
-
- if (argc == 1) {
- end = length;
- } else {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- end = js_DoubleToInteger(d);
- if (end < 0)
- end = 0;
- end += begin;
- if (end > length)
- end = length;
- }
-
- str = js_NewDependentString(cx, str, (size_t)begin,
- (size_t)(end - begin), 0);
- if (!str)
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif /* JS_HAS_PERL_SUBSTR */
-
-#if JS_HAS_SEQUENCE_OPS
-/*
- * Python-esque sequence operations.
- */
-static JSBool
-str_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str, *str2;
- uintN i;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- for (i = 0; i < argc; i++) {
- str2 = js_ValueToString(cx, argv[i]);
- if (!str2)
- return JS_FALSE;
- argv[i] = STRING_TO_JSVAL(str2);
-
- str = js_ConcatStrings(cx, str, str2);
- if (!str)
- return JS_FALSE;
- }
-
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-str_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- jsdouble d;
- jsdouble length, begin, end;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (argc != 0) {
- if (!js_ValueToNumber(cx, argv[0], &d))
- return JS_FALSE;
- length = JSSTRING_LENGTH(str);
- begin = js_DoubleToInteger(d);
- if (begin < 0) {
- begin += length;
- if (begin < 0)
- begin = 0;
- } else if (begin > length) {
- begin = length;
- }
-
- if (argc == 1) {
- end = length;
- } else {
- if (!js_ValueToNumber(cx, argv[1], &d))
- return JS_FALSE;
- end = js_DoubleToInteger(d);
- if (end < 0) {
- end += length;
- if (end < 0)
- end = 0;
- } else if (end > length) {
- end = length;
- }
- if (end < begin)
- end = begin;
- }
-
- str = js_NewDependentString(cx, str, (size_t)begin,
- (size_t)(end - begin), 0);
- if (!str)
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-#endif /* JS_HAS_SEQUENCE_OPS */
-
-#if JS_HAS_STR_HTML_HELPERS
-/*
- * HTML composition aids.
- */
-static JSBool
-tagify(JSContext *cx, JSObject *obj, jsval *argv,
- const char *begin, const jschar *param, const char *end,
- jsval *rval)
-{
- JSString *str;
- jschar *tagbuf;
- size_t beglen, endlen, parlen, taglen;
- size_t i, j;
-
- str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
- if (!str)
- return JS_FALSE;
- argv[-1] = STRING_TO_JSVAL(str);
-
- if (!end)
- end = begin;
-
- beglen = strlen(begin);
- taglen = 1 + beglen + 1; /* '<begin' + '>' */
- parlen = 0; /* Avoid warning. */
- if (param) {
- parlen = js_strlen(param);
- taglen += 2 + parlen + 1; /* '="param"' */
- }
- endlen = strlen(end);
- taglen += JSSTRING_LENGTH(str) + 2 + endlen + 1; /* 'str</end>' */
-
- tagbuf = (jschar *) JS_malloc(cx, (taglen + 1) * sizeof(jschar));
- if (!tagbuf)
- return JS_FALSE;
-
- j = 0;
- tagbuf[j++] = '<';
- for (i = 0; i < beglen; i++)
- tagbuf[j++] = (jschar)begin[i];
- if (param) {
- tagbuf[j++] = '=';
- tagbuf[j++] = '"';
- js_strncpy(&tagbuf[j], param, parlen);
- j += parlen;
- tagbuf[j++] = '"';
- }
- tagbuf[j++] = '>';
- js_strncpy(&tagbuf[j], JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
- j += JSSTRING_LENGTH(str);
- tagbuf[j++] = '<';
- tagbuf[j++] = '/';
- for (i = 0; i < endlen; i++)
- tagbuf[j++] = (jschar)end[i];
- tagbuf[j++] = '>';
- JS_ASSERT(j == taglen);
- tagbuf[j] = 0;
-
- str = js_NewString(cx, tagbuf, taglen, 0);
- if (!str) {
- free((char *)tagbuf);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSBool
-tagify_value(JSContext *cx, JSObject *obj, jsval *argv,
- const char *begin, const char *end,
- jsval *rval)
-{
- JSString *param;
-
- param = js_ValueToString(cx, argv[0]);
- if (!param)
- return JS_FALSE;
- argv[0] = STRING_TO_JSVAL(param);
- return tagify(cx, obj, argv, begin, JSSTRING_CHARS(param), end, rval);
-}
-
-static JSBool
-str_bold(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "b", NULL, NULL, rval);
-}
-
-static JSBool
-str_italics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "i", NULL, NULL, rval);
-}
-
-static JSBool
-str_fixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "tt", NULL, NULL, rval);
-}
-
-static JSBool
-str_fontsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify_value(cx, obj, argv, "font size", "font", rval);
-}
-
-static JSBool
-str_fontcolor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- return tagify_value(cx, obj, argv, "font color", "font", rval);
-}
-
-static JSBool
-str_link(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify_value(cx, obj, argv, "a href", "a", rval);
-}
-
-static JSBool
-str_anchor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify_value(cx, obj, argv, "a name", "a", rval);
-}
-
-static JSBool
-str_strike(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "strike", NULL, NULL, rval);
-}
-
-static JSBool
-str_small(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "small", NULL, NULL, rval);
-}
-
-static JSBool
-str_big(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "big", NULL, NULL, rval);
-}
-
-static JSBool
-str_blink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "blink", NULL, NULL, rval);
-}
-
-static JSBool
-str_sup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "sup", NULL, NULL, rval);
-}
-
-static JSBool
-str_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- return tagify(cx, obj, argv, "sub", NULL, NULL, rval);
-}
-#endif /* JS_HAS_STR_HTML_HELPERS */
-
-static JSFunctionSpec string_methods[] = {
-#if JS_HAS_TOSOURCE
- {"quote", str_quote, 0,0,0},
- {js_toSource_str, str_toSource, 0,0,0},
-#endif
-
- /* Java-like methods. */
- {js_toString_str, str_toString, 0,0,0},
- {js_valueOf_str, str_valueOf, 0,0,0},
- {"substring", str_substring, 2,0,0},
- {"toLowerCase", str_toLowerCase, 0,0,0},
- {"toUpperCase", str_toUpperCase, 0,0,0},
- {"charAt", str_charAt, 1,0,0},
- {"charCodeAt", str_charCodeAt, 1,0,0},
- {"indexOf", str_indexOf, 1,0,0},
- {"lastIndexOf", str_lastIndexOf, 1,0,0},
- {"toLocaleLowerCase", str_toLocaleLowerCase, 0,0,0},
- {"toLocaleUpperCase", str_toLocaleUpperCase, 0,0,0},
- {"localeCompare", str_localeCompare, 1,0,0},
-
- /* Perl-ish methods (search is actually Python-esque). */
-#if JS_HAS_REGEXPS
- {"match", str_match, 1,0,2},
- {"search", str_search, 1,0,0},
- {"replace", str_replace, 2,0,0},
- {"split", str_split, 2,0,0},
-#endif
-#if JS_HAS_PERL_SUBSTR
- {"substr", str_substr, 2,0,0},
-#endif
-
- /* Python-esque sequence methods. */
-#if JS_HAS_SEQUENCE_OPS
- {"concat", str_concat, 0,0,0},
- {"slice", str_slice, 0,0,0},
-#endif
-
- /* HTML string methods. */
-#if JS_HAS_STR_HTML_HELPERS
- {"bold", str_bold, 0,0,0},
- {"italics", str_italics, 0,0,0},
- {"fixed", str_fixed, 0,0,0},
- {"fontsize", str_fontsize, 1,0,0},
- {"fontcolor", str_fontcolor, 1,0,0},
- {"link", str_link, 1,0,0},
- {"anchor", str_anchor, 1,0,0},
- {"strike", str_strike, 0,0,0},
- {"small", str_small, 0,0,0},
- {"big", str_big, 0,0,0},
- {"blink", str_blink, 0,0,0},
- {"sup", str_sup, 0,0,0},
- {"sub", str_sub, 0,0,0},
-#endif
-
- {0,0,0,0,0}
-};
-
-static JSBool
-String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
-
- if (argc > 0) {
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- } else {
- str = cx->runtime->emptyString;
- }
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
- }
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str));
- return JS_TRUE;
-}
-
-static JSBool
-str_fromCharCode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- jschar *chars;
- uintN i;
- uint16 code;
- JSString *str;
-
- chars = (jschar *) JS_malloc(cx, (argc + 1) * sizeof(jschar));
- if (!chars)
- return JS_FALSE;
- for (i = 0; i < argc; i++) {
- if (!js_ValueToUint16(cx, argv[i], &code)) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- chars[i] = (jschar)code;
- }
- chars[i] = 0;
- str = js_NewString(cx, chars, argc, 0);
- if (!str) {
- JS_free(cx, chars);
- return JS_FALSE;
- }
- *rval = STRING_TO_JSVAL(str);
- return JS_TRUE;
-}
-
-static JSFunctionSpec string_static_methods[] = {
- {"fromCharCode", str_fromCharCode, 1,0,0},
- {0,0,0,0,0}
-};
-
-static JSHashTable *deflated_string_cache;
-#ifdef DEBUG
-static uint32 deflated_string_cache_bytes;
-#endif
-#ifdef JS_THREADSAFE
-static JSLock *deflated_string_cache_lock;
-#endif
-
-JSBool
-js_InitStringGlobals(void)
-{
-#ifdef JS_THREADSAFE
- /* Must come through here once in primordial thread to init safely! */
- if (!deflated_string_cache_lock) {
- deflated_string_cache_lock = JS_NEW_LOCK();
- if (!deflated_string_cache_lock)
- return JS_FALSE;
- }
-#endif
- return JS_TRUE;
-}
-
-void
-js_FreeStringGlobals()
-{
- if (deflated_string_cache) {
- JS_HashTableDestroy(deflated_string_cache);
- deflated_string_cache = NULL;
- }
-#ifdef JS_THREADSAFE
- if (deflated_string_cache_lock) {
- JS_DESTROY_LOCK(deflated_string_cache_lock);
- deflated_string_cache_lock = NULL;
- }
-#endif
-}
-
-JSBool
-js_InitRuntimeStringState(JSContext *cx)
-{
- JSRuntime *rt;
- JSString *empty;
-
- rt = cx->runtime;
- JS_ASSERT(!rt->emptyString);
-
- /* Make a permanently locked empty string. */
- empty = js_NewStringCopyN(cx, js_empty_ucstr, 0, GCF_LOCK);
- if (!empty)
- return JS_FALSE;
-
- /* Atomize it for scripts that use '' + x to convert x to string. */
- if (!js_AtomizeString(cx, empty, ATOM_PINNED))
- return JS_FALSE;
-
- rt->emptyString = empty;
- return JS_TRUE;
-}
-
-void
-js_FinishRuntimeStringState(JSContext *cx)
-{
- JSRuntime *rt = cx->runtime;
-
- js_UnlockGCThingRT(rt, rt->emptyString);
- rt->emptyString = NULL;
-}
-
-JSObject *
-js_InitStringClass(JSContext *cx, JSObject *obj)
-{
- JSObject *proto;
-
- /* Define the escape, unescape functions in the global object. */
- if (!JS_DefineFunctions(cx, obj, string_functions))
- return NULL;
-
- proto = JS_InitClass(cx, obj, NULL, &string_class, String, 1,
- string_props, string_methods,
- NULL, string_static_methods);
- if (!proto)
- return NULL;
- OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE,
- STRING_TO_JSVAL(cx->runtime->emptyString));
- return proto;
-}
-
-JSString *
-js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag)
-{
- JSString *str;
-
- if (length > JSSTRING_LENGTH_MASK) {
- JS_ReportOutOfMemory(cx);
- return NULL;
- }
-
- str = (JSString *) js_AllocGCThing(cx, gcflag | GCX_STRING);
- if (!str)
- return NULL;
- str->length = length;
- str->chars = chars;
-#ifdef DEBUG
- {
- JSRuntime *rt = cx->runtime;
- JS_RUNTIME_METER(rt, liveStrings);
- JS_RUNTIME_METER(rt, totalStrings);
- JS_LOCK_RUNTIME_VOID(rt,
- (rt->lengthSum += (double)length,
- rt->lengthSquaredSum += (double)length * (double)length));
- }
-#endif
- return str;
-}
-
-JSString *
-js_NewDependentString(JSContext *cx, JSString *base, size_t start,
- size_t length, uintN gcflag)
-{
- JSDependentString *ds;
-
- if (length == 0)
- return cx->runtime->emptyString;
-
- if (start > JSSTRDEP_START_MASK ||
- (start != 0 && length > JSSTRDEP_LENGTH_MASK)) {
- return js_NewStringCopyN(cx, JSSTRING_CHARS(base) + start, length,
- gcflag);
- }
-
- ds = (JSDependentString *) js_AllocGCThing(cx, gcflag | GCX_MUTABLE_STRING);
- if (!ds)
- return NULL;
- if (start == 0) {
- JSPREFIX_SET_LENGTH(ds, length);
- JSPREFIX_SET_BASE(ds, base);
- } else {
- JSSTRDEP_SET_START_AND_LENGTH(ds, start, length);
- JSSTRDEP_SET_BASE(ds, base);
- }
-#ifdef DEBUG
- {
- JSRuntime *rt = cx->runtime;
- JS_RUNTIME_METER(rt, liveDependentStrings);
- JS_RUNTIME_METER(rt, totalDependentStrings);
- JS_RUNTIME_METER(rt, liveStrings);
- JS_RUNTIME_METER(rt, totalStrings);
- JS_LOCK_RUNTIME_VOID(rt,
- (rt->strdepLengthSum += (double)length,
- rt->strdepLengthSquaredSum += (double)length * (double)length));
- JS_LOCK_RUNTIME_VOID(rt,
- (rt->lengthSum += (double)length,
- rt->lengthSquaredSum += (double)length * (double)length));
- }
-#endif
- return (JSString *)ds;
-}
-
-#ifdef DEBUG
-#include <math.h>
-
-void printJSStringStats(JSRuntime *rt) {
- double mean = 0., var = 0., sigma = 0.;
- jsrefcount count = rt->totalStrings;
- if (count > 0 && rt->lengthSum >= 0) {
- mean = rt->lengthSum / count;
- var = count * rt->lengthSquaredSum - rt->lengthSum * rt->lengthSum;
- if (var < 0.0 || count <= 1)
- var = 0.0;
- else
- var /= count * (count - 1);
-
- /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
- sigma = (var != 0.) ? sqrt(var) : 0.;
- }
- fprintf(stderr, "%lu total strings, mean length %g (sigma %g)\n",
- (unsigned long)count, mean, sigma);
-
- mean = var = sigma = 0.;
- count = rt->totalDependentStrings;
- if (count > 0 && rt->strdepLengthSum >= 0) {
- mean = rt->strdepLengthSum / count;
- var = count * rt->strdepLengthSquaredSum
- - rt->strdepLengthSum * rt->strdepLengthSum;
- if (var < 0.0 || count <= 1)
- var = 0.0;
- else
- var /= count * (count - 1);
-
- /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
- sigma = (var != 0.) ? sqrt(var) : 0.;
- }
- fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n",
- (unsigned long)count, mean, sigma);
-}
-#endif
-
-JSString *
-js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag)
-{
- jschar *news;
- JSString *str;
-
- news = (jschar *)JS_malloc(cx, (n + 1) * sizeof(jschar));
- if (!news)
- return NULL;
- js_strncpy(news, s, n);
- news[n] = 0;
- str = js_NewString(cx, news, n, gcflag);
- if (!str)
- JS_free(cx, news);
- return str;
-}
-
-JSString *
-js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag)
-{
- size_t n, m;
- jschar *news;
- JSString *str;
-
- n = js_strlen(s);
- m = (n + 1) * sizeof(jschar);
- news = (jschar *) JS_malloc(cx, m);
- if (!news)
- return NULL;
- memcpy(news, s, m);
- str = js_NewString(cx, news, n, gcflag);
- if (!str)
- JS_free(cx, news);
- return str;
-}
-
-JS_STATIC_DLL_CALLBACK(JSHashNumber)
-js_hash_string_pointer(const void *key)
-{
- return (JSHashNumber)key >> JSVAL_TAGBITS;
-}
-
-void
-js_PurgeDeflatedStringCache(JSString *str)
-{
- JSHashNumber hash;
- JSHashEntry *he, **hep;
-
- if (!deflated_string_cache)
- return;
-
- hash = js_hash_string_pointer(str);
- JS_ACQUIRE_LOCK(deflated_string_cache_lock);
- hep = JS_HashTableRawLookup(deflated_string_cache, hash, str);
- he = *hep;
- if (he) {
-#ifdef DEBUG
- deflated_string_cache_bytes -= JSSTRING_LENGTH(str);
-#endif
- free(he->value);
- JS_HashTableRawRemove(deflated_string_cache, hep, he);
- }
- JS_RELEASE_LOCK(deflated_string_cache_lock);
-}
-
-void
-js_FinalizeString(JSContext *cx, JSString *str)
-{
- js_FinalizeStringRT(cx->runtime, str);
-}
-
-void
-js_FinalizeStringRT(JSRuntime *rt, JSString *str)
-{
- JSBool valid;
-
- JS_RUNTIME_UNMETER(rt, liveStrings);
- if (JSSTRING_IS_DEPENDENT(str)) {
- /* If JSSTRFLAG_DEPENDENT is set, this string must be valid. */
- JS_ASSERT(JSSTRDEP_BASE(str));
- JS_RUNTIME_UNMETER(rt, liveDependentStrings);
- valid = JS_TRUE;
- } else {
- /* A stillborn string has null chars, so is not valid. */
- valid = (str->chars != NULL);
- if (valid)
- free(str->chars);
- }
- if (valid) {
- js_PurgeDeflatedStringCache(str);
- str->chars = NULL;
- }
- str->length = 0;
-}
-
-JSObject *
-js_StringToObject(JSContext *cx, JSString *str)
-{
- JSObject *obj;
-
- obj = js_NewObject(cx, &string_class, NULL, NULL);
- if (!obj)
- return NULL;
- OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str));
- return obj;
-}
-
-JSString *
-js_ValueToString(JSContext *cx, jsval v)
-{
- JSObject *obj;
- JSString *str;
-
- if (JSVAL_IS_OBJECT(v)) {
- obj = JSVAL_TO_OBJECT(v);
- if (!obj)
- return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
- if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v))
- return NULL;
- }
- if (JSVAL_IS_STRING(v)) {
- str = JSVAL_TO_STRING(v);
- } else if (JSVAL_IS_INT(v)) {
- str = js_NumberToString(cx, JSVAL_TO_INT(v));
- } else if (JSVAL_IS_DOUBLE(v)) {
- str = js_NumberToString(cx, *JSVAL_TO_DOUBLE(v));
- } else if (JSVAL_IS_BOOLEAN(v)) {
- str = js_BooleanToString(cx, JSVAL_TO_BOOLEAN(v));
- } else {
- str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
- }
- return str;
-}
-
-JSString *
-js_ValueToSource(JSContext *cx, jsval v)
-{
- if (JSVAL_IS_STRING(v))
- return js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
- if (JSVAL_IS_PRIMITIVE(v)) {
- /* Special case to preserve negative zero, _contra_ toString. */
- if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_NEGZERO(*JSVAL_TO_DOUBLE(v))) {
- /* NB: _ucNstr rather than _ucstr to indicate non-terminated. */
- static const jschar js_negzero_ucNstr[] = {'-', '0'};
-
- return js_NewStringCopyN(cx, js_negzero_ucNstr, 2, 0);
- }
- } else {
- if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v),
- cx->runtime->atomState.toSourceAtom,
- 0, NULL, &v)) {
- return NULL;
- }
- }
- return js_ValueToString(cx, v);
-}
-
-JSHashNumber
-js_HashString(JSString *str)
-{
- JSHashNumber h;
- const jschar *s;
- size_t n;
-
- h = 0;
- for (s = JSSTRING_CHARS(str), n = JSSTRING_LENGTH(str); n; s++, n--)
- h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s;
- return h;
-}
-
-intN
-js_CompareStrings(JSString *str1, JSString *str2)
-{
- size_t l1, l2, n, i;
- const jschar *s1, *s2;
- intN cmp;
-
- l1 = JSSTRING_LENGTH(str1), l2 = JSSTRING_LENGTH(str2);
- s1 = JSSTRING_CHARS(str1), s2 = JSSTRING_CHARS(str2);
- n = JS_MIN(l1, l2);
- for (i = 0; i < n; i++) {
- cmp = s1[i] - s2[i];
- if (cmp != 0)
- return cmp;
- }
- return (intN)(l1 - l2);
-}
-
-size_t
-js_strlen(const jschar *s)
-{
- const jschar *t;
-
- for (t = s; *t != 0; t++)
- continue;
- return (size_t)(t - s);
-}
-
-jschar *
-js_strchr(const jschar *s, jschar c)
-{
- while (*s != 0) {
- if (*s == c)
- return (jschar *)s;
- s++;
- }
- return NULL;
-}
-
-jschar *
-js_strchr_limit(const jschar *s, jschar c, const jschar *limit)
-{
- while (s < limit) {
- if (*s == c)
- return (jschar *)s;
- s++;
- }
- return NULL;
-}
-
-const jschar *
-js_SkipWhiteSpace(const jschar *s)
-{
- /* JS_ISSPACE is false on a null. */
- while (JS_ISSPACE(*s))
- s++;
- return s;
-}
-
-#define INFLATE_STRING_BODY \
- for (i = 0; i < length; i++) \
- chars[i] = (unsigned char) bytes[i]; \
- chars[i] = 0;
-
-void
-js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length)
-{
- size_t i;
-
- INFLATE_STRING_BODY
-}
-
-jschar *
-js_InflateString(JSContext *cx, const char *bytes, size_t length)
-{
- jschar *chars;
- size_t i;
-
- chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
- if (!chars)
- return NULL;
-
- INFLATE_STRING_BODY
-
- return chars;
-}
-
-/*
- * May be called with null cx by js_GetStringBytes, see below.
- */
-char *
-js_DeflateString(JSContext *cx, const jschar *chars, size_t length)
-{
- size_t i, size;
- char *bytes;
-
- size = (length + 1) * sizeof(char);
- bytes = (char *) (cx ? JS_malloc(cx, size) : malloc(size));
- if (!bytes)
- return NULL;
- for (i = 0; i < length; i++)
- bytes[i] = (char) chars[i];
- bytes[i] = 0;
- return bytes;
-}
-
-static JSHashTable *
-GetDeflatedStringCache(void)
-{
- JSHashTable *cache;
-
- cache = deflated_string_cache;
- if (!cache) {
- cache = JS_NewHashTable(8, js_hash_string_pointer,
- JS_CompareValues, JS_CompareValues,
- NULL, NULL);
- deflated_string_cache = cache;
- }
- return cache;
-}
-
-JSBool
-js_SetStringBytes(JSString *str, char *bytes, size_t length)
-{
- JSHashTable *cache;
- JSBool ok;
- JSHashNumber hash;
- JSHashEntry **hep;
-
- JS_ACQUIRE_LOCK(deflated_string_cache_lock);
-
- cache = GetDeflatedStringCache();
- if (!cache) {
- ok = JS_FALSE;
- } else {
- hash = js_hash_string_pointer(str);
- hep = JS_HashTableRawLookup(cache, hash, str);
- JS_ASSERT(*hep == NULL);
- ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL;
-#ifdef DEBUG
- if (ok)
- deflated_string_cache_bytes += length;
-#endif
- }
-
- JS_RELEASE_LOCK(deflated_string_cache_lock);
- return ok;
-}
-
-char *
-js_GetStringBytes(JSString *str)
-{
- JSHashTable *cache;
- char *bytes;
- JSHashNumber hash;
- JSHashEntry *he, **hep;
-
- JS_ACQUIRE_LOCK(deflated_string_cache_lock);
-
- cache = GetDeflatedStringCache();
- if (!cache) {
- bytes = NULL;
- } else {
- hash = js_hash_string_pointer(str);
- hep = JS_HashTableRawLookup(cache, hash, str);
- he = *hep;
- if (he) {
- bytes = (char *) he->value;
-
- /* Try to catch failure to JS_ShutDown between runtime epochs. */
- JS_ASSERT((*bytes == '\0' && JSSTRING_LENGTH(str) == 0) ||
- *bytes == (char) JSSTRING_CHARS(str)[0]);
- } else {
- bytes = js_DeflateString(NULL, JSSTRING_CHARS(str),
- JSSTRING_LENGTH(str));
- if (bytes) {
- if (JS_HashTableRawAdd(cache, hep, hash, str, bytes)) {
-#ifdef DEBUG
- deflated_string_cache_bytes += JSSTRING_LENGTH(str);
-#endif
- } else {
- free(bytes);
- bytes = NULL;
- }
- }
- }
- }
-
- JS_RELEASE_LOCK(deflated_string_cache_lock);
- return bytes;
-}
-
-/*
- * From java.lang.Character.java:
- *
- * The character properties are currently encoded into 32 bits in the
- * following manner:
- *
- * 10 bits signed offset used for converting case
- * 1 bit if 1, adding the signed offset converts the character to
- * lowercase
- * 1 bit if 1, subtracting the signed offset converts the character to
- * uppercase
- * 1 bit if 1, character has a titlecase equivalent (possibly itself)
- * 3 bits 0 may not be part of an identifier
- * 1 ignorable control; may continue a Unicode identifier or JS
- * identifier
- * 2 may continue a JS identifier but not a Unicode identifier
- * (unused)
- * 3 may continue a Unicode identifier or JS identifier
- * 4 is a JS whitespace character
- * 5 may start or continue a JS identifier;
- * may continue but not start a Unicode identifier (_)
- * 6 may start or continue a JS identifier but not a Unicode
- * identifier ($)
- * 7 may start or continue a Unicode identifier or JS identifier
- * Thus:
- * 5, 6, 7 may start a JS identifier
- * 1, 2, 3, 5, 6, 7 may continue a JS identifier
- * 7 may start a Unicode identifier
- * 1, 3, 5, 7 may continue a Unicode identifier
- * 1 is ignorable within an identifier
- * 4 is JS whitespace
- * 2 bits 0 this character has no numeric property
- * 1 adding the digit offset to the character code and then
- * masking with 0x1F will produce the desired numeric value
- * 2 this character has a "strange" numeric value
- * 3 a JS supradecimal digit: adding the digit offset to the
- * character code, then masking with 0x1F, then adding 10
- * will produce the desired numeric value
- * 5 bits digit offset
- * 4 bits reserved for future use
- * 5 bits character type
- */
-
-/* The X table has 1024 entries for a total of 1024 bytes. */
-
-const uint8 js_X[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000 */
- 8, 9, 10, 11, 12, 13, 14, 15, /* 0x0200 */
- 16, 17, 18, 19, 20, 21, 22, 23, /* 0x0400 */
- 24, 25, 26, 27, 28, 28, 28, 28, /* 0x0600 */
- 28, 28, 28, 28, 29, 30, 31, 32, /* 0x0800 */
- 33, 34, 35, 36, 37, 38, 39, 40, /* 0x0A00 */
- 41, 42, 43, 44, 45, 46, 28, 28, /* 0x0C00 */
- 47, 48, 49, 50, 51, 52, 53, 28, /* 0x0E00 */
- 28, 28, 54, 55, 56, 57, 58, 59, /* 0x1000 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1200 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1400 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1600 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1800 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1A00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1C00 */
- 60, 60, 61, 62, 63, 64, 65, 66, /* 0x1E00 */
- 67, 68, 69, 70, 71, 72, 73, 74, /* 0x2000 */
- 75, 75, 75, 76, 77, 78, 28, 28, /* 0x2200 */
- 79, 80, 81, 82, 83, 83, 84, 85, /* 0x2400 */
- 86, 85, 28, 28, 87, 88, 89, 28, /* 0x2600 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2800 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2A00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2C00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2E00 */
- 90, 91, 92, 93, 94, 56, 95, 28, /* 0x3000 */
- 96, 97, 98, 99, 83, 100, 83, 101, /* 0x3200 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3400 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3600 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3800 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3A00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3C00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3E00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4000 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4200 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4400 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4600 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4800 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4A00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4C00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x4E00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5A00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5C00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5E00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6A00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6C00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6E00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7A00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7C00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7E00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8A00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8C00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8E00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9A00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9C00 */
- 56, 56, 56, 56, 56, 56, 102, 28, /* 0x9E00 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA000 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA200 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA400 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA600 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA800 */
- 28, 28, 28, 28, 28, 28, 28, 28, /* 0xAA00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAC00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAE00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBA00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBC00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBE00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC400 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC600 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC800 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCA00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCC00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCE00 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD000 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD200 */
- 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD400 */
- 56, 56, 56, 56, 56, 56, 103, 28, /* 0xD600 */
-104, 104, 104, 104, 104, 104, 104, 104, /* 0xD800 */
-104, 104, 104, 104, 104, 104, 104, 104, /* 0xDA00 */
-104, 104, 104, 104, 104, 104, 104, 104, /* 0xDC00 */
-104, 104, 104, 104, 104, 104, 104, 104, /* 0xDE00 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xE000 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xE200 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xE400 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xE600 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xE800 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xEA00 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xEC00 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xEE00 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xF000 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xF200 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xF400 */
-105, 105, 105, 105, 105, 105, 105, 105, /* 0xF600 */
-105, 105, 105, 105, 56, 56, 56, 56, /* 0xF800 */
-106, 28, 28, 28, 107, 108, 109, 110, /* 0xFA00 */
- 56, 56, 56, 56, 111, 112, 113, 114, /* 0xFC00 */
-115, 116, 56, 117, 118, 119, 120, 121 /* 0xFE00 */
-};
-
-/* The Y table has 7808 entries for a total of 7808 bytes. */
-
-const uint8 js_Y[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
- 0, 1, 1, 1, 1, 1, 0, 0, /* 0 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
- 2, 3, 3, 3, 4, 3, 3, 3, /* 0 */
- 5, 6, 3, 7, 3, 8, 3, 3, /* 0 */
- 9, 9, 9, 9, 9, 9, 9, 9, /* 0 */
- 9, 9, 3, 3, 7, 7, 7, 3, /* 0 */
- 3, 10, 10, 10, 10, 10, 10, 10, /* 1 */
- 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */
- 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */
- 10, 10, 10, 5, 3, 6, 11, 12, /* 1 */
- 11, 13, 13, 13, 13, 13, 13, 13, /* 1 */
- 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */
- 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */
- 13, 13, 13, 5, 7, 6, 7, 0, /* 1 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
- 2, 3, 4, 4, 4, 4, 15, 15, /* 2 */
- 11, 15, 16, 5, 7, 8, 15, 11, /* 2 */
- 15, 7, 17, 17, 11, 16, 15, 3, /* 2 */
- 11, 18, 16, 6, 19, 19, 19, 3, /* 2 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */
- 20, 20, 20, 20, 20, 20, 20, 7, /* 3 */
- 20, 20, 20, 20, 20, 20, 20, 16, /* 3 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */
- 21, 21, 21, 21, 21, 21, 21, 7, /* 3 */
- 21, 21, 21, 21, 21, 21, 21, 22, /* 3 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */
- 25, 26, 23, 24, 23, 24, 23, 24, /* 4 */
- 16, 23, 24, 23, 24, 23, 24, 23, /* 4 */
- 24, 23, 24, 23, 24, 23, 24, 23, /* 5 */
- 24, 16, 23, 24, 23, 24, 23, 24, /* 5 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */
- 27, 23, 24, 23, 24, 23, 24, 28, /* 5 */
- 16, 29, 23, 24, 23, 24, 30, 23, /* 6 */
- 24, 31, 31, 23, 24, 16, 32, 32, /* 6 */
- 33, 23, 24, 31, 34, 16, 35, 36, /* 6 */
- 23, 24, 16, 16, 35, 37, 16, 38, /* 6 */
- 23, 24, 23, 24, 23, 24, 38, 23, /* 6 */
- 24, 39, 40, 16, 23, 24, 39, 23, /* 6 */
- 24, 41, 41, 23, 24, 23, 24, 42, /* 6 */
- 23, 24, 16, 40, 23, 24, 40, 40, /* 6 */
- 40, 40, 40, 40, 43, 44, 45, 43, /* 7 */
- 44, 45, 43, 44, 45, 23, 24, 23, /* 7 */
- 24, 23, 24, 23, 24, 23, 24, 23, /* 7 */
- 24, 23, 24, 23, 24, 16, 23, 24, /* 7 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */
- 16, 43, 44, 45, 23, 24, 46, 46, /* 7 */
- 46, 46, 23, 24, 23, 24, 23, 24, /* 7 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */
- 16, 16, 16, 47, 48, 16, 49, 49, /* 9 */
- 50, 50, 16, 51, 16, 16, 16, 16, /* 9 */
- 49, 16, 16, 52, 16, 16, 16, 16, /* 9 */
- 53, 54, 16, 16, 16, 16, 16, 54, /* 9 */
- 16, 16, 55, 16, 16, 16, 16, 16, /* 9 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 9 */
- 16, 16, 16, 56, 16, 16, 16, 16, /* 10 */
- 56, 16, 57, 57, 16, 16, 16, 16, /* 10 */
- 16, 16, 58, 16, 16, 16, 16, 16, /* 10 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */
- 16, 46, 46, 46, 46, 46, 46, 46, /* 10 */
- 59, 59, 59, 59, 59, 59, 59, 59, /* 10 */
- 59, 11, 11, 59, 59, 59, 59, 59, /* 10 */
- 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */
- 11, 11, 11, 11, 11, 11, 11, 11, /* 11 */
- 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */
- 11, 11, 11, 11, 11, 11, 11, 46, /* 11 */
- 59, 59, 59, 59, 59, 11, 11, 11, /* 11 */
- 11, 11, 46, 46, 46, 46, 46, 46, /* 11 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */
- 60, 60, 60, 60, 60, 60, 46, 46, /* 13 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */
- 60, 60, 46, 46, 46, 46, 46, 46, /* 13 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */
- 46, 46, 46, 46, 3, 3, 46, 46, /* 13 */
- 46, 46, 59, 46, 46, 46, 3, 46, /* 13 */
- 46, 46, 46, 46, 11, 11, 61, 3, /* 14 */
- 62, 62, 62, 46, 63, 46, 64, 64, /* 14 */
- 16, 20, 20, 20, 20, 20, 20, 20, /* 14 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 14 */
- 20, 20, 46, 20, 20, 20, 20, 20, /* 14 */
- 20, 20, 20, 20, 65, 66, 66, 66, /* 14 */
- 16, 21, 21, 21, 21, 21, 21, 21, /* 14 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 14 */
- 21, 21, 16, 21, 21, 21, 21, 21, /* 15 */
- 21, 21, 21, 21, 67, 68, 68, 46, /* 15 */
- 69, 70, 38, 38, 38, 71, 72, 46, /* 15 */
- 46, 46, 38, 46, 38, 46, 38, 46, /* 15 */
- 38, 46, 23, 24, 23, 24, 23, 24, /* 15 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 15 */
- 73, 74, 16, 40, 46, 46, 46, 46, /* 15 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 15 */
- 46, 75, 75, 75, 75, 75, 75, 75, /* 16 */
- 75, 75, 75, 75, 75, 46, 75, 75, /* 16 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */
- 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */
- 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */
- 46, 74, 74, 74, 74, 74, 74, 74, /* 17 */
- 74, 74, 74, 74, 74, 46, 74, 74, /* 17 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */
- 23, 24, 15, 60, 60, 60, 60, 46, /* 18 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */
- 40, 23, 24, 23, 24, 46, 46, 23, /* 19 */
- 24, 46, 46, 23, 24, 46, 46, 46, /* 19 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */
- 23, 24, 23, 24, 46, 46, 23, 24, /* 19 */
- 23, 24, 23, 24, 23, 24, 46, 46, /* 19 */
- 23, 24, 46, 46, 46, 46, 46, 46, /* 19 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */
- 46, 76, 76, 76, 76, 76, 76, 76, /* 20 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 20 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */
- 76, 76, 76, 76, 76, 76, 76, 46, /* 21 */
- 46, 59, 3, 3, 3, 3, 3, 3, /* 21 */
- 46, 77, 77, 77, 77, 77, 77, 77, /* 21 */
- 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */
- 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */
- 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */
- 77, 77, 77, 77, 77, 77, 77, 16, /* 22 */
- 46, 3, 46, 46, 46, 46, 46, 46, /* 22 */
- 46, 60, 60, 60, 60, 60, 60, 60, /* 22 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */
- 60, 60, 46, 60, 60, 60, 60, 60, /* 22 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */
- 60, 60, 46, 60, 60, 60, 3, 60, /* 22 */
- 3, 60, 60, 3, 60, 46, 46, 46, /* 23 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */
- 40, 40, 40, 46, 46, 46, 46, 46, /* 23 */
- 40, 40, 40, 3, 3, 46, 46, 46, /* 23 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */
- 46, 46, 46, 46, 3, 46, 46, 46, /* 24 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */
- 46, 46, 46, 3, 46, 46, 46, 3, /* 24 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 24 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */
- 40, 40, 40, 46, 46, 46, 46, 46, /* 24 */
- 59, 40, 40, 40, 40, 40, 40, 40, /* 25 */
- 40, 40, 40, 60, 60, 60, 60, 60, /* 25 */
- 60, 60, 60, 46, 46, 46, 46, 46, /* 25 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 25 */
- 78, 78, 78, 78, 78, 78, 78, 78, /* 25 */
- 78, 78, 3, 3, 3, 3, 46, 46, /* 25 */
- 60, 40, 40, 40, 40, 40, 40, 40, /* 25 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 25 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */
- 46, 46, 40, 40, 40, 40, 40, 46, /* 26 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 27 */
- 40, 40, 40, 40, 40, 40, 40, 46, /* 27 */
- 40, 40, 40, 40, 3, 40, 60, 60, /* 27 */
- 60, 60, 60, 60, 60, 79, 79, 60, /* 27 */
- 60, 60, 60, 60, 60, 59, 59, 60, /* 27 */
- 60, 15, 60, 60, 60, 60, 46, 46, /* 27 */
- 9, 9, 9, 9, 9, 9, 9, 9, /* 27 */
- 9, 9, 46, 46, 46, 46, 46, 46, /* 27 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */
- 46, 60, 60, 80, 46, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */
- 40, 40, 46, 46, 60, 40, 80, 80, /* 29 */
- 80, 60, 60, 60, 60, 60, 60, 60, /* 30 */
- 60, 80, 80, 80, 80, 60, 46, 46, /* 30 */
- 15, 60, 60, 60, 60, 46, 46, 46, /* 30 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 30 */
- 40, 40, 60, 60, 3, 3, 81, 81, /* 30 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 30 */
- 3, 46, 46, 46, 46, 46, 46, 46, /* 30 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 30 */
- 46, 60, 80, 80, 46, 40, 40, 40, /* 31 */
- 40, 40, 40, 40, 40, 46, 46, 40, /* 31 */
- 40, 46, 46, 40, 40, 40, 40, 40, /* 31 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 31 */
- 40, 46, 40, 46, 46, 46, 40, 40, /* 31 */
- 40, 40, 46, 46, 60, 46, 80, 80, /* 31 */
- 80, 60, 60, 60, 60, 46, 46, 80, /* 32 */
- 80, 46, 46, 80, 80, 60, 46, 46, /* 32 */
- 46, 46, 46, 46, 46, 46, 46, 80, /* 32 */
- 46, 46, 46, 46, 40, 40, 46, 40, /* 32 */
- 40, 40, 60, 60, 46, 46, 81, 81, /* 32 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 32 */
- 40, 40, 4, 4, 82, 82, 82, 82, /* 32 */
- 19, 83, 15, 46, 46, 46, 46, 46, /* 32 */
- 46, 46, 60, 46, 46, 40, 40, 40, /* 33 */
- 40, 40, 40, 46, 46, 46, 46, 40, /* 33 */
- 40, 46, 46, 40, 40, 40, 40, 40, /* 33 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 33 */
- 40, 46, 40, 40, 46, 40, 40, 46, /* 33 */
- 40, 40, 46, 46, 60, 46, 80, 80, /* 33 */
- 80, 60, 60, 46, 46, 46, 46, 60, /* 34 */
- 60, 46, 46, 60, 60, 60, 46, 46, /* 34 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */
- 46, 40, 40, 40, 40, 46, 40, 46, /* 34 */
- 46, 46, 46, 46, 46, 46, 81, 81, /* 34 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 34 */
- 60, 60, 40, 40, 40, 46, 46, 46, /* 34 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */
- 46, 60, 60, 80, 46, 40, 40, 40, /* 35 */
- 40, 40, 40, 40, 46, 40, 46, 40, /* 35 */
- 40, 40, 46, 40, 40, 40, 40, 40, /* 35 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 35 */
- 40, 46, 40, 40, 46, 40, 40, 40, /* 35 */
- 40, 40, 46, 46, 60, 40, 80, 80, /* 35 */
- 80, 60, 60, 60, 60, 60, 46, 60, /* 36 */
- 60, 80, 46, 80, 80, 60, 46, 46, /* 36 */
- 15, 46, 46, 46, 46, 46, 46, 46, /* 36 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */
- 40, 46, 46, 46, 46, 46, 81, 81, /* 36 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 36 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */
- 46, 60, 80, 80, 46, 40, 40, 40, /* 37 */
- 40, 40, 40, 40, 40, 46, 46, 40, /* 37 */
- 40, 46, 46, 40, 40, 40, 40, 40, /* 37 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 37 */
- 40, 46, 40, 40, 46, 46, 40, 40, /* 37 */
- 40, 40, 46, 46, 60, 40, 80, 60, /* 37 */
- 80, 60, 60, 60, 46, 46, 46, 80, /* 38 */
- 80, 46, 46, 80, 80, 60, 46, 46, /* 38 */
- 46, 46, 46, 46, 46, 46, 60, 80, /* 38 */
- 46, 46, 46, 46, 40, 40, 46, 40, /* 38 */
- 40, 40, 46, 46, 46, 46, 81, 81, /* 38 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 38 */
- 15, 46, 46, 46, 46, 46, 46, 46, /* 38 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 38 */
- 46, 46, 60, 80, 46, 40, 40, 40, /* 39 */
- 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */
- 40, 46, 40, 40, 40, 40, 46, 46, /* 39 */
- 46, 40, 40, 46, 40, 46, 40, 40, /* 39 */
- 46, 46, 46, 40, 40, 46, 46, 46, /* 39 */
- 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */
- 40, 40, 40, 40, 40, 40, 46, 40, /* 39 */
- 40, 40, 46, 46, 46, 46, 80, 80, /* 39 */
- 60, 80, 80, 46, 46, 46, 80, 80, /* 40 */
- 80, 46, 80, 80, 80, 60, 46, 46, /* 40 */
- 46, 46, 46, 46, 46, 46, 46, 80, /* 40 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */
- 46, 46, 46, 46, 46, 46, 46, 81, /* 40 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 40 */
- 84, 19, 19, 46, 46, 46, 46, 46, /* 40 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */
- 46, 80, 80, 80, 46, 40, 40, 40, /* 41 */
- 40, 40, 40, 40, 40, 46, 40, 40, /* 41 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */
- 40, 40, 40, 40, 46, 40, 40, 40, /* 41 */
- 40, 40, 46, 46, 46, 46, 60, 60, /* 41 */
- 60, 80, 80, 80, 80, 46, 60, 60, /* 42 */
- 60, 46, 60, 60, 60, 60, 46, 46, /* 42 */
- 46, 46, 46, 46, 46, 60, 60, 46, /* 42 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */
- 40, 40, 46, 46, 46, 46, 81, 81, /* 42 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 42 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */
- 46, 46, 80, 80, 46, 40, 40, 40, /* 43 */
- 40, 40, 40, 40, 40, 46, 40, 40, /* 43 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */
- 40, 40, 40, 40, 46, 40, 40, 40, /* 43 */
- 40, 40, 46, 46, 46, 46, 80, 60, /* 43 */
- 80, 80, 80, 80, 80, 46, 60, 80, /* 44 */
- 80, 46, 80, 80, 60, 60, 46, 46, /* 44 */
- 46, 46, 46, 46, 46, 80, 80, 46, /* 44 */
- 46, 46, 46, 46, 46, 46, 40, 46, /* 44 */
- 40, 40, 46, 46, 46, 46, 81, 81, /* 44 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 44 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */
- 46, 46, 80, 80, 46, 40, 40, 40, /* 45 */
- 40, 40, 40, 40, 40, 46, 40, 40, /* 45 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */
- 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */
- 40, 40, 46, 46, 46, 46, 80, 80, /* 45 */
- 80, 60, 60, 60, 46, 46, 80, 80, /* 46 */
- 80, 46, 80, 80, 80, 60, 46, 46, /* 46 */
- 46, 46, 46, 46, 46, 46, 46, 80, /* 46 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */
- 40, 40, 46, 46, 46, 46, 81, 81, /* 46 */
- 81, 81, 81, 81, 81, 81, 81, 81, /* 46 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 47 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */
- 40, 40, 40, 40, 40, 40, 40, 3, /* 47 */
- 40, 60, 40, 40, 60, 60, 60, 60, /* 47 */
- 60, 60, 60, 46, 46, 46, 46, 4, /* 47 */
- 40, 40, 40, 40, 40, 40, 59, 60, /* 48 */
- 60, 60, 60, 60, 60, 60, 60, 15, /* 48 */
- 9, 9, 9, 9, 9, 9, 9, 9, /* 48 */
- 9, 9, 3, 3, 46, 46, 46, 46, /* 48 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */
- 46, 40, 40, 46, 40, 46, 46, 40, /* 49 */
- 40, 46, 40, 46, 46, 40, 46, 46, /* 49 */
- 46, 46, 46, 46, 40, 40, 40, 40, /* 49 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 49 */
- 46, 40, 40, 40, 46, 40, 46, 40, /* 49 */
- 46, 46, 40, 40, 46, 40, 40, 3, /* 49 */
- 40, 60, 40, 40, 60, 60, 60, 60, /* 49 */
- 60, 60, 46, 60, 60, 40, 46, 46, /* 49 */
- 40, 40, 40, 40, 40, 46, 59, 46, /* 50 */
- 60, 60, 60, 60, 60, 60, 46, 46, /* 50 */
- 9, 9, 9, 9, 9, 9, 9, 9, /* 50 */
- 9, 9, 46, 46, 40, 40, 46, 46, /* 50 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */
- 15, 15, 15, 15, 3, 3, 3, 3, /* 51 */
- 3, 3, 3, 3, 3, 3, 3, 3, /* 51 */
- 3, 3, 3, 15, 15, 15, 15, 15, /* 51 */
- 60, 60, 15, 15, 15, 15, 15, 15, /* 51 */
- 78, 78, 78, 78, 78, 78, 78, 78, /* 51 */
- 78, 78, 85, 85, 85, 85, 85, 85, /* 51 */
- 85, 85, 85, 85, 15, 60, 15, 60, /* 51 */
- 15, 60, 5, 6, 5, 6, 80, 80, /* 51 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 52 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */
- 40, 40, 46, 46, 46, 46, 46, 46, /* 52 */
- 46, 60, 60, 60, 60, 60, 60, 60, /* 52 */
- 60, 60, 60, 60, 60, 60, 60, 80, /* 52 */
- 60, 60, 60, 60, 60, 3, 60, 60, /* 53 */
- 60, 60, 60, 60, 46, 46, 46, 46, /* 53 */
- 60, 60, 60, 60, 60, 60, 46, 60, /* 53 */
- 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 53 */
- 60, 60, 60, 60, 60, 60, 46, 46, /* 53 */
- 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */
- 46, 60, 46, 46, 46, 46, 46, 46, /* 53 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */
- 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */
- 76, 76, 76, 76, 76, 76, 46, 46, /* 55 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 55 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */
- 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */
- 16, 16, 16, 16, 16, 16, 16, 46, /* 55 */
- 46, 46, 46, 3, 46, 46, 46, 46, /* 55 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 46, 46, 46, 46, 46, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 46, 46, 46, 46, 46, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */
- 40, 40, 46, 46, 46, 46, 46, 46, /* 59 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 16, 16, /* 61 */
- 16, 16, 16, 16, 46, 46, 46, 46, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */
- 23, 24, 46, 46, 46, 46, 46, 46, /* 62 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */
- 86, 86, 86, 86, 86, 86, 46, 46, /* 63 */
- 87, 87, 87, 87, 87, 87, 46, 46, /* 63 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */
- 86, 86, 86, 86, 86, 86, 46, 46, /* 64 */
- 87, 87, 87, 87, 87, 87, 46, 46, /* 64 */
- 16, 86, 16, 86, 16, 86, 16, 86, /* 64 */
- 46, 87, 46, 87, 46, 87, 46, 87, /* 64 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 64 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 64 */
- 88, 88, 89, 89, 89, 89, 90, 90, /* 64 */
- 91, 91, 92, 92, 93, 93, 46, 46, /* 64 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */
- 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */
- 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */
- 86, 86, 16, 94, 16, 46, 16, 16, /* 65 */
- 87, 87, 95, 95, 96, 11, 38, 11, /* 65 */
- 11, 11, 16, 94, 16, 46, 16, 16, /* 66 */
- 97, 97, 97, 97, 96, 11, 11, 11, /* 66 */
- 86, 86, 16, 16, 46, 46, 16, 16, /* 66 */
- 87, 87, 98, 98, 46, 11, 11, 11, /* 66 */
- 86, 86, 16, 16, 16, 99, 16, 16, /* 66 */
- 87, 87, 100, 100, 101, 11, 11, 11, /* 66 */
- 46, 46, 16, 94, 16, 46, 16, 16, /* 66 */
-102, 102, 103, 103, 96, 11, 11, 46, /* 66 */
- 2, 2, 2, 2, 2, 2, 2, 2, /* 67 */
- 2, 2, 2, 2, 104, 104, 104, 104, /* 67 */
- 8, 8, 8, 8, 8, 8, 3, 3, /* 67 */
- 5, 6, 5, 5, 5, 6, 5, 5, /* 67 */
- 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */
-105, 106, 104, 104, 104, 104, 104, 46, /* 67 */
- 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */
- 3, 5, 6, 3, 3, 3, 3, 12, /* 67 */
- 12, 3, 3, 3, 7, 5, 6, 46, /* 68 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */
- 46, 46, 104, 104, 104, 104, 104, 104, /* 68 */
- 17, 46, 46, 46, 17, 17, 17, 17, /* 68 */
- 17, 17, 7, 7, 7, 5, 6, 16, /* 68 */
-107, 107, 107, 107, 107, 107, 107, 107, /* 69 */
-107, 107, 7, 7, 7, 5, 6, 46, /* 69 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */
- 4, 4, 4, 4, 4, 4, 4, 4, /* 69 */
- 4, 4, 4, 4, 46, 46, 46, 46, /* 69 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */
- 60, 60, 60, 60, 60, 60, 60, 60, /* 70 */
- 60, 60, 60, 60, 60, 79, 79, 79, /* 70 */
- 79, 60, 46, 46, 46, 46, 46, 46, /* 70 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */
- 15, 15, 38, 15, 15, 15, 15, 38, /* 71 */
- 15, 15, 16, 38, 38, 38, 16, 16, /* 71 */
- 38, 38, 38, 16, 15, 38, 15, 15, /* 71 */
- 38, 38, 38, 38, 38, 38, 15, 15, /* 71 */
- 15, 15, 15, 15, 38, 15, 38, 15, /* 71 */
- 38, 15, 38, 38, 38, 38, 16, 16, /* 71 */
- 38, 38, 15, 38, 16, 40, 40, 40, /* 71 */
- 40, 46, 46, 46, 46, 46, 46, 46, /* 71 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */
- 46, 46, 46, 19, 19, 19, 19, 19, /* 72 */
- 19, 19, 19, 19, 19, 19, 19, 108, /* 72 */
-109, 109, 109, 109, 109, 109, 109, 109, /* 72 */
-109, 109, 109, 109, 110, 110, 110, 110, /* 72 */
-111, 111, 111, 111, 111, 111, 111, 111, /* 72 */
-111, 111, 111, 111, 112, 112, 112, 112, /* 72 */
-113, 113, 113, 46, 46, 46, 46, 46, /* 73 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 73 */
- 7, 7, 7, 7, 7, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */
- 15, 15, 7, 15, 7, 15, 15, 15, /* 74 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */
- 15, 15, 15, 46, 46, 46, 46, 46, /* 74 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */
- 7, 7, 46, 46, 46, 46, 46, 46, /* 76 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 76 */
- 15, 46, 15, 15, 15, 15, 15, 15, /* 77 */
- 7, 7, 7, 7, 15, 15, 15, 15, /* 77 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */
- 7, 7, 15, 15, 15, 15, 15, 15, /* 77 */
- 15, 5, 6, 15, 15, 15, 15, 15, /* 77 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */
- 15, 15, 15, 46, 46, 46, 46, 46, /* 78 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */
- 15, 15, 15, 15, 15, 46, 46, 46, /* 79 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 80 */
- 15, 15, 15, 46, 46, 46, 46, 46, /* 80 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */
-114, 114, 114, 114, 114, 114, 114, 114, /* 80 */
-114, 114, 114, 114, 114, 114, 114, 114, /* 80 */
-114, 114, 114, 114, 82, 82, 82, 82, /* 80 */
- 82, 82, 82, 82, 82, 82, 82, 82, /* 80 */
- 82, 82, 82, 82, 82, 82, 82, 82, /* 81 */
-115, 115, 115, 115, 115, 115, 115, 115, /* 81 */
-115, 115, 115, 115, 115, 115, 115, 115, /* 81 */
-115, 115, 115, 115, 15, 15, 15, 15, /* 81 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */
- 15, 15, 15, 15, 15, 15, 116, 116, /* 81 */
-116, 116, 116, 116, 116, 116, 116, 116, /* 81 */
-116, 116, 116, 116, 116, 116, 116, 116, /* 82 */
-116, 116, 116, 116, 116, 116, 116, 116, /* 82 */
-117, 117, 117, 117, 117, 117, 117, 117, /* 82 */
-117, 117, 117, 117, 117, 117, 117, 117, /* 82 */
-117, 117, 117, 117, 117, 117, 117, 117, /* 82 */
-117, 117, 118, 46, 46, 46, 46, 46, /* 82 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 46, 46, /* 84 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 46, 46, 46, 46, /* 86 */
- 46, 46, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */
- 46, 15, 15, 15, 15, 46, 15, 15, /* 87 */
- 15, 15, 46, 46, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 46, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 88 */
- 15, 15, 15, 15, 46, 15, 46, 15, /* 88 */
- 15, 15, 15, 46, 46, 46, 15, 46, /* 88 */
- 15, 15, 15, 15, 15, 15, 15, 46, /* 88 */
- 46, 15, 15, 15, 15, 15, 15, 15, /* 88 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 88 */
- 46, 46, 46, 46, 46, 46, 119, 119, /* 88 */
-119, 119, 119, 119, 119, 119, 119, 119, /* 88 */
-114, 114, 114, 114, 114, 114, 114, 114, /* 89 */
-114, 114, 83, 83, 83, 83, 83, 83, /* 89 */
- 83, 83, 83, 83, 15, 46, 46, 46, /* 89 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */
- 46, 15, 15, 15, 15, 15, 15, 15, /* 89 */
- 15, 15, 15, 15, 15, 15, 15, 46, /* 89 */
- 2, 3, 3, 3, 15, 59, 3, 120, /* 90 */
- 5, 6, 5, 6, 5, 6, 5, 6, /* 90 */
- 5, 6, 15, 15, 5, 6, 5, 6, /* 90 */
- 5, 6, 5, 6, 8, 5, 6, 5, /* 90 */
- 15, 121, 121, 121, 121, 121, 121, 121, /* 90 */
-121, 121, 60, 60, 60, 60, 60, 60, /* 90 */
- 8, 59, 59, 59, 59, 59, 15, 15, /* 90 */
- 46, 46, 46, 46, 46, 46, 46, 15, /* 90 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 46, 46, 46, /* 92 */
- 46, 60, 60, 59, 59, 59, 59, 46, /* 92 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */
- 40, 40, 40, 3, 59, 59, 59, 46, /* 93 */
- 46, 46, 46, 46, 46, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 46, 46, 46, /* 94 */
- 46, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 95 */
- 40, 40, 40, 40, 40, 40, 40, 46, /* 95 */
- 15, 15, 85, 85, 85, 85, 15, 15, /* 95 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 95 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 15, 46, 46, 46, /* 96 */
- 85, 85, 85, 85, 85, 85, 85, 85, /* 96 */
- 85, 85, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */
- 15, 15, 15, 15, 46, 46, 46, 46, /* 97 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */
- 15, 15, 15, 15, 46, 46, 46, 15, /* 97 */
-114, 114, 114, 114, 114, 114, 114, 114, /* 98 */
-114, 114, 15, 15, 15, 15, 15, 15, /* 98 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */
- 15, 46, 46, 46, 46, 46, 46, 46, /* 98 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 98 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 46, 46, 46, 46, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 46, /* 99 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 46, /* 100 */
- 46, 46, 46, 15, 15, 15, 15, 15, /* 100 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 46, 46, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */
- 15, 15, 15, 15, 15, 15, 15, 46, /* 101 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */
- 40, 40, 40, 40, 40, 40, 46, 46, /* 102 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */
- 40, 40, 40, 40, 46, 46, 46, 46, /* 103 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-122, 122, 122, 122, 122, 122, 122, 122, /* 104 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
-123, 123, 123, 123, 123, 123, 123, 123, /* 105 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */
- 40, 40, 40, 40, 40, 40, 46, 46, /* 106 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */
- 16, 16, 16, 16, 16, 16, 16, 46, /* 107 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 107 */
- 46, 46, 46, 16, 16, 16, 16, 16, /* 107 */
- 46, 46, 46, 46, 46, 46, 60, 40, /* 107 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 107 */
- 40, 7, 40, 40, 40, 40, 40, 40, /* 107 */
- 40, 40, 40, 40, 40, 40, 40, 46, /* 107 */
- 40, 40, 40, 40, 40, 46, 40, 46, /* 107 */
- 40, 40, 46, 40, 40, 46, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */
- 40, 40, 46, 46, 46, 46, 46, 46, /* 109 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 109 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */
- 46, 46, 46, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */
- 40, 40, 40, 40, 40, 40, 5, 6, /* 111 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 46, 46, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */
- 40, 40, 40, 40, 46, 46, 46, 46, /* 114 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */
- 60, 60, 60, 60, 46, 46, 46, 46, /* 115 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */
- 3, 8, 8, 12, 12, 5, 6, 5, /* 115 */
- 6, 5, 6, 5, 6, 5, 6, 5, /* 115 */
- 6, 5, 6, 5, 6, 46, 46, 46, /* 116 */
- 46, 3, 3, 3, 3, 12, 12, 12, /* 116 */
- 3, 3, 3, 46, 3, 3, 3, 3, /* 116 */
- 8, 5, 6, 5, 6, 5, 6, 3, /* 116 */
- 3, 3, 7, 8, 7, 7, 7, 46, /* 116 */
- 3, 4, 3, 3, 46, 46, 46, 46, /* 116 */
- 40, 40, 40, 46, 40, 46, 40, 40, /* 116 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 116 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */
- 40, 40, 40, 40, 40, 46, 46, 104, /* 117 */
- 46, 3, 3, 3, 4, 3, 3, 3, /* 118 */
- 5, 6, 3, 7, 3, 8, 3, 3, /* 118 */
- 9, 9, 9, 9, 9, 9, 9, 9, /* 118 */
- 9, 9, 3, 3, 7, 7, 7, 3, /* 118 */
- 3, 10, 10, 10, 10, 10, 10, 10, /* 118 */
- 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */
- 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */
- 10, 10, 10, 5, 3, 6, 11, 12, /* 118 */
- 11, 13, 13, 13, 13, 13, 13, 13, /* 119 */
- 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */
- 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */
- 13, 13, 13, 5, 7, 6, 7, 46, /* 119 */
- 46, 3, 5, 6, 3, 3, 40, 40, /* 119 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */
- 59, 40, 40, 40, 40, 40, 40, 40, /* 119 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 59, 59, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */
- 40, 40, 40, 40, 40, 40, 40, 46, /* 120 */
- 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */
- 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */
- 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */
- 46, 46, 40, 40, 40, 46, 46, 46, /* 121 */
- 4, 4, 7, 11, 15, 4, 4, 46, /* 121 */
- 7, 7, 7, 7, 7, 15, 15, 46, /* 121 */
- 46, 46, 46, 46, 46, 46, 46, 46, /* 121 */
- 46, 46, 46, 46, 46, 15, 46, 46 /* 121 */
-};
-
-/* The A table has 124 entries for a total of 496 bytes. */
-
-const uint32 js_A[] = {
-0x0001000F, /* 0 Cc, ignorable */
-0x0004000F, /* 1 Cc, whitespace */
-0x0004000C, /* 2 Zs, whitespace */
-0x00000018, /* 3 Po */
-0x0006001A, /* 4 Sc, currency */
-0x00000015, /* 5 Ps */
-0x00000016, /* 6 Pe */
-0x00000019, /* 7 Sm */
-0x00000014, /* 8 Pd */
-0x00036009, /* 9 Nd, identifier part, decimal 16 */
-0x0827FE01, /* 10 Lu, hasLower (add 32), identifier start, supradecimal 31 */
-0x0000001B, /* 11 Sk */
-0x00050017, /* 12 Pc, underscore */
-0x0817FE02, /* 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31 */
-0x0000000C, /* 14 Zs */
-0x0000001C, /* 15 So */
-0x00070002, /* 16 Ll, identifier start */
-0x0000600B, /* 17 No, decimal 16 */
-0x0000500B, /* 18 No, decimal 8 */
-0x0000800B, /* 19 No, strange */
-0x08270001, /* 20 Lu, hasLower (add 32), identifier start */
-0x08170002, /* 21 Ll, hasUpper (subtract 32), identifier start */
-0xE1D70002, /* 22 Ll, hasUpper (subtract -121), identifier start */
-0x00670001, /* 23 Lu, hasLower (add 1), identifier start */
-0x00570002, /* 24 Ll, hasUpper (subtract 1), identifier start */
-0xCE670001, /* 25 Lu, hasLower (add -199), identifier start */
-0x3A170002, /* 26 Ll, hasUpper (subtract 232), identifier start */
-0xE1E70001, /* 27 Lu, hasLower (add -121), identifier start */
-0x4B170002, /* 28 Ll, hasUpper (subtract 300), identifier start */
-0x34A70001, /* 29 Lu, hasLower (add 210), identifier start */
-0x33A70001, /* 30 Lu, hasLower (add 206), identifier start */
-0x33670001, /* 31 Lu, hasLower (add 205), identifier start */
-0x32A70001, /* 32 Lu, hasLower (add 202), identifier start */
-0x32E70001, /* 33 Lu, hasLower (add 203), identifier start */
-0x33E70001, /* 34 Lu, hasLower (add 207), identifier start */
-0x34E70001, /* 35 Lu, hasLower (add 211), identifier start */
-0x34670001, /* 36 Lu, hasLower (add 209), identifier start */
-0x35670001, /* 37 Lu, hasLower (add 213), identifier start */
-0x00070001, /* 38 Lu, identifier start */
-0x36A70001, /* 39 Lu, hasLower (add 218), identifier start */
-0x00070005, /* 40 Lo, identifier start */
-0x36670001, /* 41 Lu, hasLower (add 217), identifier start */
-0x36E70001, /* 42 Lu, hasLower (add 219), identifier start */
-0x00AF0001, /* 43 Lu, hasLower (add 2), hasTitle, identifier start */
-0x007F0003, /* 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start */
-0x009F0002, /* 45 Ll, hasUpper (subtract 2), hasTitle, identifier start */
-0x00000000, /* 46 unassigned */
-0x34970002, /* 47 Ll, hasUpper (subtract 210), identifier start */
-0x33970002, /* 48 Ll, hasUpper (subtract 206), identifier start */
-0x33570002, /* 49 Ll, hasUpper (subtract 205), identifier start */
-0x32970002, /* 50 Ll, hasUpper (subtract 202), identifier start */
-0x32D70002, /* 51 Ll, hasUpper (subtract 203), identifier start */
-0x33D70002, /* 52 Ll, hasUpper (subtract 207), identifier start */
-0x34570002, /* 53 Ll, hasUpper (subtract 209), identifier start */
-0x34D70002, /* 54 Ll, hasUpper (subtract 211), identifier start */
-0x35570002, /* 55 Ll, hasUpper (subtract 213), identifier start */
-0x36970002, /* 56 Ll, hasUpper (subtract 218), identifier start */
-0x36570002, /* 57 Ll, hasUpper (subtract 217), identifier start */
-0x36D70002, /* 58 Ll, hasUpper (subtract 219), identifier start */
-0x00070004, /* 59 Lm, identifier start */
-0x00030006, /* 60 Mn, identifier part */
-0x09A70001, /* 61 Lu, hasLower (add 38), identifier start */
-0x09670001, /* 62 Lu, hasLower (add 37), identifier start */
-0x10270001, /* 63 Lu, hasLower (add 64), identifier start */
-0x0FE70001, /* 64 Lu, hasLower (add 63), identifier start */
-0x09970002, /* 65 Ll, hasUpper (subtract 38), identifier start */
-0x09570002, /* 66 Ll, hasUpper (subtract 37), identifier start */
-0x10170002, /* 67 Ll, hasUpper (subtract 64), identifier start */
-0x0FD70002, /* 68 Ll, hasUpper (subtract 63), identifier start */
-0x0F970002, /* 69 Ll, hasUpper (subtract 62), identifier start */
-0x0E570002, /* 70 Ll, hasUpper (subtract 57), identifier start */
-0x0BD70002, /* 71 Ll, hasUpper (subtract 47), identifier start */
-0x0D970002, /* 72 Ll, hasUpper (subtract 54), identifier start */
-0x15970002, /* 73 Ll, hasUpper (subtract 86), identifier start */
-0x14170002, /* 74 Ll, hasUpper (subtract 80), identifier start */
-0x14270001, /* 75 Lu, hasLower (add 80), identifier start */
-0x0C270001, /* 76 Lu, hasLower (add 48), identifier start */
-0x0C170002, /* 77 Ll, hasUpper (subtract 48), identifier start */
-0x00034009, /* 78 Nd, identifier part, decimal 0 */
-0x00000007, /* 79 Me */
-0x00030008, /* 80 Mc, identifier part */
-0x00037409, /* 81 Nd, identifier part, decimal 26 */
-0x00005A0B, /* 82 No, decimal 13 */
-0x00006E0B, /* 83 No, decimal 23 */
-0x0000740B, /* 84 No, decimal 26 */
-0x0000000B, /* 85 No */
-0xFE170002, /* 86 Ll, hasUpper (subtract -8), identifier start */
-0xFE270001, /* 87 Lu, hasLower (add -8), identifier start */
-0xED970002, /* 88 Ll, hasUpper (subtract -74), identifier start */
-0xEA970002, /* 89 Ll, hasUpper (subtract -86), identifier start */
-0xE7170002, /* 90 Ll, hasUpper (subtract -100), identifier start */
-0xE0170002, /* 91 Ll, hasUpper (subtract -128), identifier start */
-0xE4170002, /* 92 Ll, hasUpper (subtract -112), identifier start */
-0xE0970002, /* 93 Ll, hasUpper (subtract -126), identifier start */
-0xFDD70002, /* 94 Ll, hasUpper (subtract -9), identifier start */
-0xEDA70001, /* 95 Lu, hasLower (add -74), identifier start */
-0xFDE70001, /* 96 Lu, hasLower (add -9), identifier start */
-0xEAA70001, /* 97 Lu, hasLower (add -86), identifier start */
-0xE7270001, /* 98 Lu, hasLower (add -100), identifier start */
-0xFE570002, /* 99 Ll, hasUpper (subtract -7), identifier start */
-0xE4270001, /* 100 Lu, hasLower (add -112), identifier start */
-0xFE670001, /* 101 Lu, hasLower (add -7), identifier start */
-0xE0270001, /* 102 Lu, hasLower (add -128), identifier start */
-0xE0A70001, /* 103 Lu, hasLower (add -126), identifier start */
-0x00010010, /* 104 Cf, ignorable */
-0x0004000D, /* 105 Zl, whitespace */
-0x0004000E, /* 106 Zp, whitespace */
-0x0000400B, /* 107 No, decimal 0 */
-0x0000440B, /* 108 No, decimal 2 */
-0x0427420A, /* 109 Nl, hasLower (add 16), identifier start, decimal 1 */
-0x0427800A, /* 110 Nl, hasLower (add 16), identifier start, strange */
-0x0417620A, /* 111 Nl, hasUpper (subtract 16), identifier start, decimal 17 */
-0x0417800A, /* 112 Nl, hasUpper (subtract 16), identifier start, strange */
-0x0007800A, /* 113 Nl, identifier start, strange */
-0x0000420B, /* 114 No, decimal 1 */
-0x0000720B, /* 115 No, decimal 25 */
-0x06A0001C, /* 116 So, hasLower (add 26) */
-0x0690001C, /* 117 So, hasUpper (subtract 26) */
-0x00006C0B, /* 118 No, decimal 22 */
-0x0000560B, /* 119 No, decimal 11 */
-0x0007720A, /* 120 Nl, identifier start, decimal 25 */
-0x0007400A, /* 121 Nl, identifier start, decimal 0 */
-0x00000013, /* 122 Cs */
-0x00000012 /* 123 Co */
-};
-
-const jschar js_uriReservedPlusPound_ucstr[] =
- {';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#', 0};
-const jschar js_uriUnescaped_ucstr[] =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '-', '_', '.', '!', '~', '*', '\'', '(', ')', 0};
-
-#define URI_CHUNK 64U
-
-/* Concatenate jschars onto an unshared/newborn JSString. */
-static JSBool
-AddCharsToURI(JSContext *cx, JSString *str, const jschar *chars, size_t length)
-{
- size_t total;
-
- JS_ASSERT(!JSSTRING_IS_DEPENDENT(str));
- total = str->length + length + 1;
- if (!str->chars ||
- JS_HOWMANY(total, URI_CHUNK) > JS_HOWMANY(str->length + 1, URI_CHUNK)) {
- total = JS_ROUNDUP(total, URI_CHUNK);
- str->chars = JS_realloc(cx, str->chars, total * sizeof(jschar));
- if (!str->chars)
- return JS_FALSE;
- }
- js_strncpy(str->chars + str->length, chars, length);
- str->length += length;
- str->chars[str->length] = 0;
- return JS_TRUE;
-}
-
-/*
- * ECMA 3, 15.1.3 URI Handling Function Properties
- *
- * The following are implementations of the algorithms
- * given in the ECMA specification for the hidden functions
- * 'Encode' and 'Decode'.
- */
-static JSBool
-Encode(JSContext *cx, JSString *str, const jschar *unescapedSet,
- const jschar *unescapedSet2, jsval *rval)
-{
- size_t length, j, k, L;
- jschar *chars, C, C2;
- uint32 V;
- uint8 utf8buf[6];
- jschar hexBuf[4];
- static const char HexDigits[] = "0123456789ABCDEF"; /* NB: uppercase */
- JSString *R;
-
- R = js_NewString(cx, NULL, 0, 0);
- if (!R)
- return JS_FALSE;
-
- hexBuf[0] = '%';
- hexBuf[3] = 0;
- chars = JSSTRING_CHARS(str);
- length = JSSTRING_LENGTH(str);
- for (k = 0; k < length; k++) {
- C = chars[k];
- if (js_strchr(unescapedSet, C) ||
- (unescapedSet2 && js_strchr(unescapedSet2, C))) {
- if (!AddCharsToURI(cx, R, &C, 1))
- return JS_FALSE;
- } else {
- if ((C >= 0xDC00) && (C <= 0xDFFF)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_URI, NULL);
- return JS_FALSE;
- }
- if (C < 0xD800 || C > 0xDBFF) {
- V = C;
- } else {
- k++;
- if (k == length) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_URI, NULL);
- return JS_FALSE;
- }
- C2 = chars[k];
- if ((C2 < 0xDC00) || (C2 > 0xDFFF)) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
- JSMSG_BAD_URI, NULL);
- return JS_FALSE;
- }
- V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000;
- }
- L = OneUcs4ToUtf8Char(utf8buf, V);
- for (j = 0; j < L; j++) {
- hexBuf[1] = HexDigits[utf8buf[j] >> 4];
- hexBuf[2] = HexDigits[utf8buf[j] & 0xf];
- if (!AddCharsToURI(cx, R, hexBuf, 3))
- return JS_FALSE;
- }
- }
- }
-
- /*
- * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we
- * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1
- * more jschars than it needs.
- */
- chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar));
- if (chars)
- R->chars = chars;
- *rval = STRING_TO_JSVAL(R);
- return JS_TRUE;
-}
-
-static JSBool
-Decode(JSContext *cx, JSString *str, const jschar *reservedSet, jsval *rval)
-{
- size_t length, start, k;
- jschar *chars, C, H;
- uint32 V;
- jsuint B;
- uint8 octets[6];
- JSString *R;
- intN j, n;
-
- R = js_NewString(cx, NULL, 0, 0);
- if (!R)
- return JS_FALSE;
-
- chars = JSSTRING_CHARS(str);
- length = JSSTRING_LENGTH(str);
- for (k = 0; k < length; k++) {
- C = chars[k];
- if (C == '%') {
- start = k;
- if ((k + 2) >= length)
- goto bad;
- if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2]))
- goto bad;
- B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
- k += 2;
- if (!(B & 0x80)) {
- C = (jschar)B;
- } else {
- n = 1;
- while (B & (0x80 >> n))
- n++;
- if (n == 1 || n > 6)
- goto bad;
- octets[0] = (uint8)B;
- if (k + 3 * (n - 1) >= length)
- goto bad;
- for (j = 1; j < n; j++) {
- k++;
- if (chars[k] != '%')
- goto bad;
- if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2]))
- goto bad;
- B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
- if ((B & 0xC0) != 0x80)
- goto bad;
- k += 2;
- octets[j] = (char)B;
- }
- V = Utf8ToOneUcs4Char(octets, n);
- if (V >= 0x10000) {
- V -= 0x10000;
- if (V > 0xFFFFF)
- goto bad;
- C = (jschar)((V & 0x3FF) + 0xDC00);
- H = (jschar)((V >> 10) + 0xD800);
- if (!AddCharsToURI(cx, R, &H, 1))
- return JS_FALSE;
- } else {
- C = (jschar)V;
- }
- }
- if (js_strchr(reservedSet, C)) {
- if (!AddCharsToURI(cx, R, &chars[start], (k - start + 1)))
- return JS_FALSE;
- } else {
- if (!AddCharsToURI(cx, R, &C, 1))
- return JS_FALSE;
- }
- } else {
- if (!AddCharsToURI(cx, R, &C, 1))
- return JS_FALSE;
- }
- }
-
- /*
- * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we
- * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1
- * more jschars than it needs.
- */
- chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar));
- if (chars)
- R->chars = chars;
- *rval = STRING_TO_JSVAL(R);
- return JS_TRUE;
-
-bad:
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_URI);
- return JS_FALSE;
-}
-
-static JSBool
-str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- return Decode(cx, str, js_uriReservedPlusPound_ucstr, rval);
-}
-
-static JSBool
-str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- return Decode(cx, str, js_empty_ucstr, rval);
-}
-
-static JSBool
-str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- return Encode(cx, str, js_uriReservedPlusPound_ucstr, js_uriUnescaped_ucstr,
- rval);
-}
-
-static JSBool
-str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval)
-{
- JSString *str;
-
- str = js_ValueToString(cx, argv[0]);
- if (!str)
- return JS_FALSE;
- return Encode(cx, str, js_uriUnescaped_ucstr, NULL, rval);
-}
-
-/*
- * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
- * least 6 bytes long. Return the number of UTF-8 bytes of data written.
- */
-static int
-OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char)
-{
- int utf8Length = 1;
-
- JS_ASSERT(ucs4Char <= 0x7FFFFFFF);
- if (ucs4Char < 0x80) {
- *utf8Buffer = (uint8)ucs4Char;
- } else {
- int i;
- uint32 a = ucs4Char >> 11;
- utf8Length = 2;
- while (a) {
- a >>= 5;
- utf8Length++;
- }
- i = utf8Length;
- while (--i) {
- utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80);
- ucs4Char >>= 6;
- }
- *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
- }
- return utf8Length;
-}
-
-/*
- * Convert a utf8 character sequence into a UCS-4 character and return that
- * character. It is assumed that the caller already checked that the sequence
- * is valid.
- */
-static uint32
-Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length)
-{
- uint32 ucs4Char;
- uint32 minucs4Char;
- /* from Unicode 3.1, non-shortest form is illegal */
- static const uint32 minucs4Table[] = {
- 0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000
- };
-
- JS_ASSERT(utf8Length >= 1 && utf8Length <= 6);
- if (utf8Length == 1) {
- ucs4Char = *utf8Buffer;
- JS_ASSERT(!(ucs4Char & 0x80));
- } else {
- JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) ==
- (0x100 - (1 << (8-utf8Length))));
- ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1);
- minucs4Char = minucs4Table[utf8Length-2];
- while (--utf8Length) {
- JS_ASSERT((*utf8Buffer & 0xC0) == 0x80);
- ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F);
- }
- if (ucs4Char < minucs4Char ||
- ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) {
- ucs4Char = 0xFFFD;
- }
- }
- return ucs4Char;
-}
diff --git a/src/extension/script/js/jsstr.h b/src/extension/script/js/jsstr.h
deleted file mode 100644
index 94ebe97b9..000000000
--- a/src/extension/script/js/jsstr.h
+++ /dev/null
@@ -1,439 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsstr_h___
-#define jsstr_h___
-/*
- * JS string type implementation.
- *
- * A JS string is a counted array of unicode characters. To support handoff
- * of API client memory, the chars are allocated separately from the length,
- * necessitating a pointer after the count, to form a separately allocated
- * string descriptor. String descriptors are GC'ed, while their chars are
- * allocated from the malloc heap.
- *
- * When a string is treated as an object (by following it with . or []), the
- * runtime wraps it with a JSObject whose valueOf method returns the unwrapped
- * string descriptor.
- */
-#include <ctype.h>
-#include "jspubtd.h"
-#include "jsprvtd.h"
-#include "jshash.h"
-
-JS_BEGIN_EXTERN_C
-
-/*
- * The original GC-thing "string" type, a flat character string owned by its
- * GC-thing descriptor. The chars member points to a vector having byte size
- * (length + 1) * sizeof(jschar), terminated at index length by a zero jschar.
- * The terminator is purely a backstop, in case the chars pointer flows out to
- * native code that requires \u0000 termination.
- *
- * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros,
- * unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str).
- */
-struct JSString {
- size_t length;
- jschar *chars;
-};
-
-/*
- * Overlay structure for a string that depends on another string's characters.
- * Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length. The base
- * member may point to another dependent string if JSSTRING_CHARS has not been
- * called yet. The length chars in a dependent string are stored starting at
- * base->chars + start, and are not necessarily zero-terminated. If start is
- * 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits in
- * the high two positions), and the JSSTRFLAG_PREFIX flag is set.
- */
-struct JSDependentString {
- size_t length;
- JSString *base;
-};
-
-/* Definitions for flags stored in the high order bits of JSString.length. */
-#define JSSTRFLAG_BITS 2
-#define JSSTRFLAG_SHIFT(flg) ((size_t)(flg) << JSSTRING_LENGTH_BITS)
-#define JSSTRFLAG_MASK JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BITS))
-#define JSSTRFLAG_DEPENDENT JSSTRFLAG_SHIFT(1)
-#define JSSTRFLAG_PREFIX JSSTRFLAG_SHIFT(2)
-
-/* Universal JSString type inquiry and accessor macros. */
-#define JSSTRING_BIT(n) ((size_t)1 << (n))
-#define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1)
-#define JSSTRING_HAS_FLAG(str,flg) ((str)->length & (flg))
-#define JSSTRING_IS_DEPENDENT(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPENDENT)
-#define JSSTRING_IS_PREFIX(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX)
-#define JSSTRING_CHARS(str) (JSSTRING_IS_DEPENDENT(str) \
- ? JSSTRDEP_CHARS(str) \
- : (str)->chars)
-#define JSSTRING_LENGTH(str) (JSSTRING_IS_DEPENDENT(str) \
- ? JSSTRDEP_LENGTH(str) \
- : (str)->length)
-#define JSSTRING_LENGTH_BITS (sizeof(size_t) * JS_BITS_PER_BYTE \
- - JSSTRFLAG_BITS)
-#define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
-
-/* Specific JSDependentString shift/mask accessor and mutator macros. */
-#define JSSTRDEP_START_BITS (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_BITS)
-#define JSSTRDEP_START_SHIFT JSSTRDEP_LENGTH_BITS
-#define JSSTRDEP_START_MASK JSSTRING_BITMASK(JSSTRDEP_START_BITS)
-#define JSSTRDEP_LENGTH_BITS (JSSTRING_LENGTH_BITS / 2)
-#define JSSTRDEP_LENGTH_MASK JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS)
-
-#define JSSTRDEP(str) ((JSDependentString *)(str))
-#define JSSTRDEP_START(str) (JSSTRING_IS_PREFIX(str) ? 0 \
- : ((JSSTRDEP(str)->length \
- >> JSSTRDEP_START_SHIFT) \
- & JSSTRDEP_START_MASK))
-#define JSSTRDEP_LENGTH(str) (JSSTRDEP(str)->length \
- & (JSSTRING_IS_PREFIX(str) \
- ? JSSTRING_LENGTH_MASK \
- : JSSTRDEP_LENGTH_MASK))
-
-#define JSSTRDEP_SET_START_AND_LENGTH(str,off,len) \
- (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT \
- | ((off) << JSSTRDEP_START_SHIFT) \
- | (len))
-#define JSPREFIX_SET_LENGTH(str,len) \
- (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len))
-
-#define JSSTRDEP_BASE(str) (JSSTRDEP(str)->base)
-#define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr))
-#define JSPREFIX_BASE(str) JSSTRDEP_BASE(str)
-#define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr)
-
-#define JSSTRDEP_CHARS(str) \
- (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str)) \
- ? js_GetDependentStringChars(str) \
- : JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str))
-
-extern size_t
-js_MinimizeDependentStrings(JSString *str, int level, JSString **basep);
-
-extern jschar *
-js_GetDependentStringChars(JSString *str);
-
-extern jschar *
-js_GetStringChars(JSString *str);
-
-extern JSString *
-js_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
-
-extern const jschar *
-js_UndependString(JSContext *cx, JSString *str);
-
-struct JSSubString {
- size_t length;
- const jschar *chars;
-};
-
-extern jschar js_empty_ucstr[];
-extern JSSubString js_EmptySubString;
-
-/* Unicode character attribute lookup tables. */
-extern const uint8 js_X[];
-extern const uint8 js_Y[];
-extern const uint32 js_A[];
-
-/* Enumerated Unicode general category types. */
-typedef enum JSCharType {
- JSCT_UNASSIGNED = 0,
- JSCT_UPPERCASE_LETTER = 1,
- JSCT_LOWERCASE_LETTER = 2,
- JSCT_TITLECASE_LETTER = 3,
- JSCT_MODIFIER_LETTER = 4,
- JSCT_OTHER_LETTER = 5,
- JSCT_NON_SPACING_MARK = 6,
- JSCT_ENCLOSING_MARK = 7,
- JSCT_COMBINING_SPACING_MARK = 8,
- JSCT_DECIMAL_DIGIT_NUMBER = 9,
- JSCT_LETTER_NUMBER = 10,
- JSCT_OTHER_NUMBER = 11,
- JSCT_SPACE_SEPARATOR = 12,
- JSCT_LINE_SEPARATOR = 13,
- JSCT_PARAGRAPH_SEPARATOR = 14,
- JSCT_CONTROL = 15,
- JSCT_FORMAT = 16,
- JSCT_PRIVATE_USE = 18,
- JSCT_SURROGATE = 19,
- JSCT_DASH_PUNCTUATION = 20,
- JSCT_START_PUNCTUATION = 21,
- JSCT_END_PUNCTUATION = 22,
- JSCT_CONNECTOR_PUNCTUATION = 23,
- JSCT_OTHER_PUNCTUATION = 24,
- JSCT_MATH_SYMBOL = 25,
- JSCT_CURRENCY_SYMBOL = 26,
- JSCT_MODIFIER_SYMBOL = 27,
- JSCT_OTHER_SYMBOL = 28
-} JSCharType;
-
-/* Character classifying and mapping macros, based on java.lang.Character. */
-#define JS_CCODE(c) (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]])
-#define JS_CTYPE(c) (JS_CCODE(c) & 0x1F)
-
-#define JS_ISALPHA(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
- (1 << JSCT_LOWERCASE_LETTER) | \
- (1 << JSCT_TITLECASE_LETTER) | \
- (1 << JSCT_MODIFIER_LETTER) | \
- (1 << JSCT_OTHER_LETTER)) \
- >> JS_CTYPE(c)) & 1)
-
-#define JS_ISALNUM(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
- (1 << JSCT_LOWERCASE_LETTER) | \
- (1 << JSCT_TITLECASE_LETTER) | \
- (1 << JSCT_MODIFIER_LETTER) | \
- (1 << JSCT_OTHER_LETTER) | \
- (1 << JSCT_DECIMAL_DIGIT_NUMBER)) \
- >> JS_CTYPE(c)) & 1)
-
-/* A unicode letter, suitable for use in an identifier. */
-#define JS_ISUC_LETTER(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
- (1 << JSCT_LOWERCASE_LETTER) | \
- (1 << JSCT_TITLECASE_LETTER) | \
- (1 << JSCT_MODIFIER_LETTER) | \
- (1 << JSCT_OTHER_LETTER) | \
- (1 << JSCT_LETTER_NUMBER)) \
- >> JS_CTYPE(c)) & 1)
-
-/*
-* 'IdentifierPart' from ECMA grammar, is Unicode letter or
-* combining mark or digit or connector punctuation.
-*/
-#define JS_ISID_PART(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
- (1 << JSCT_LOWERCASE_LETTER) | \
- (1 << JSCT_TITLECASE_LETTER) | \
- (1 << JSCT_MODIFIER_LETTER) | \
- (1 << JSCT_OTHER_LETTER) | \
- (1 << JSCT_LETTER_NUMBER) | \
- (1 << JSCT_NON_SPACING_MARK) | \
- (1 << JSCT_COMBINING_SPACING_MARK) | \
- (1 << JSCT_DECIMAL_DIGIT_NUMBER) | \
- (1 << JSCT_CONNECTOR_PUNCTUATION)) \
- >> JS_CTYPE(c)) & 1)
-
-/* Unicode control-format characters, ignored in input */
-#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1)
-
-#define JS_ISWORD(c) (JS_ISALNUM(c) || (c) == '_')
-
-/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
-#define JS_ISIDENT_START(c) (JS_ISUC_LETTER(c) || (c) == '_' || (c) == '$')
-#define JS_ISIDENT(c) (JS_ISID_PART(c) || (c) == '_' || (c) == '$')
-
-#define JS_ISDIGIT(c) (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER)
-
-/* XXXbe fs, etc. ? */
-#define JS_ISSPACE(c) ((JS_CCODE(c) & 0x00070000) == 0x00040000)
-#define JS_ISPRINT(c) ((c) < 128 && isprint(c))
-
-#define JS_ISUPPER(c) (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER)
-#define JS_ISLOWER(c) (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER)
-
-#define JS_TOUPPER(c) ((JS_CCODE(c) & 0x00100000) ? (c) - ((int32)JS_CCODE(c) >> 22) : (c))
-#define JS_TOLOWER(c) ((JS_CCODE(c) & 0x00200000) ? (c) + ((int32)JS_CCODE(c) >> 22) : (c))
-
-#define JS_TOCTRL(c) ((c) ^ 64) /* XXX unsafe! requires uppercase c */
-
-/* Shorthands for ASCII (7-bit) decimal and hex conversion. */
-#define JS7_ISDEC(c) ((c) < 128 && isdigit(c))
-#define JS7_UNDEC(c) ((c) - '0')
-#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c))
-#define JS7_UNHEX(c) (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a')
-#define JS7_ISLET(c) ((c) < 128 && isalpha(c))
-
-/* Initialize truly global state associated with JS strings. */
-extern JSBool
-js_InitStringGlobals(void);
-
-extern void
-js_FreeStringGlobals(void);
-
-extern void
-js_PurgeDeflatedStringCache(JSString *str);
-
-/* Initialize per-runtime string state for the first context in the runtime. */
-extern JSBool
-js_InitRuntimeStringState(JSContext *cx);
-
-extern void
-js_FinishRuntimeStringState(JSContext *cx);
-
-/* Initialize the String class, returning its prototype object. */
-extern JSObject *
-js_InitStringClass(JSContext *cx, JSObject *obj);
-
-extern const char js_escape_str[];
-extern const char js_unescape_str[];
-extern const char js_uneval_str[];
-extern const char js_decodeURI_str[];
-extern const char js_encodeURI_str[];
-extern const char js_decodeURIComponent_str[];
-extern const char js_encodeURIComponent_str[];
-
-/* GC-allocate a string descriptor for the given malloc-allocated chars. */
-extern JSString *
-js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag);
-
-extern JSString *
-js_NewDependentString(JSContext *cx, JSString *base, size_t start,
- size_t length, uintN gcflag);
-
-/* Copy a counted string and GC-allocate a descriptor for it. */
-extern JSString *
-js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag);
-
-/* Copy a C string and GC-allocate a descriptor for it. */
-extern JSString *
-js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag);
-
-/* Free the chars held by str when it is finalized by the GC. */
-extern void
-js_FinalizeString(JSContext *cx, JSString *str);
-
-extern void
-js_FinalizeStringRT(JSRuntime *rt, JSString *str);
-
-/* Wrap a string value in a String object. */
-extern JSObject *
-js_StringToObject(JSContext *cx, JSString *str);
-
-/*
- * Convert a value to a string, returning null after reporting an error,
- * otherwise returning a new string reference.
- */
-extern JSString *
-js_ValueToString(JSContext *cx, jsval v);
-
-/*
- * Convert a value to its source expression, returning null after reporting
- * an error, otherwise returning a new string reference.
- */
-extern JSString *
-js_ValueToSource(JSContext *cx, jsval v);
-
-#ifdef HT_ENUMERATE_NEXT /* XXX don't require jshash.h */
-/*
- * Compute a hash function from str.
- */
-extern JSHashNumber
-js_HashString(JSString *str);
-#endif
-
-/*
- * Return less than, equal to, or greater than zero depending on whether
- * str1 is less than, equal to, or greater than str2.
- */
-extern intN
-js_CompareStrings(JSString *str1, JSString *str2);
-
-/*
- * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen.
- * The patlen argument must be positive and no greater than BMH_PATLEN_MAX.
- * The start argument tells where in text to begin the search.
- *
- * Return the index of pat in text, or -1 if not found.
- */
-#define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */
-#define BMH_PATLEN_MAX 255 /* skip table element is uint8 */
-
-#define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 */
-
-extern jsint
-js_BoyerMooreHorspool(const jschar *text, jsint textlen,
- const jschar *pat, jsint patlen,
- jsint start);
-
-extern size_t
-js_strlen(const jschar *s);
-
-extern jschar *
-js_strchr(const jschar *s, jschar c);
-
-extern jschar *
-js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
-
-#define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar))
-
-/*
- * Return s advanced past any Unicode white space characters.
- */
-extern const jschar *
-js_SkipWhiteSpace(const jschar *s);
-
-/*
- * Inflate bytes to JS chars and vice versa. Report out of memory via cx
- * and return null on error, otherwise return the jschar or byte vector that
- * was JS_malloc'ed.
- */
-extern jschar *
-js_InflateString(JSContext *cx, const char *bytes, size_t length);
-
-extern char *
-js_DeflateString(JSContext *cx, const jschar *chars, size_t length);
-
-/*
- * Inflate bytes to JS chars into a buffer.
- * 'chars' must be large enough for 'length'+1 jschars.
- */
-extern void
-js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length);
-
-/*
- * Associate bytes with str in the deflated string cache, returning true on
- * successful association, false on out of memory.
- */
-extern JSBool
-js_SetStringBytes(JSString *str, char *bytes, size_t length);
-
-/*
- * Find or create a deflated string cache entry for str that contains its
- * characters chopped from Unicode code points into bytes.
- */
-extern char *
-js_GetStringBytes(JSString *str);
-
-JSBool
-js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
- jsval *rval);
-
-JS_END_EXTERN_C
-
-#endif /* jsstr_h___ */
diff --git a/src/extension/script/js/jstypes.h b/src/extension/script/js/jstypes.h
deleted file mode 100644
index 1709c6461..000000000
--- a/src/extension/script/js/jstypes.h
+++ /dev/null
@@ -1,388 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * IBM Corp.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-** File: jstypes.h
-** Description: Definitions of NSPR's basic types
-**
-** Prototypes and macros used to make up for deficiencies in ANSI environments
-** that we have found.
-**
-** Since we do not wrap <stdlib.h> and all the other standard headers, authors
-** of portable code will not know in general that they need these definitions.
-** Instead of requiring these authors to find the dependent uses in their code
-** and take the following steps only in those C files, we take steps once here
-** for all C files.
-**/
-
-#ifndef jstypes_h___
-#define jstypes_h___
-
-#include <stddef.h>
-
-/***********************************************************************
-** MACROS: JS_EXTERN_API
-** JS_EXPORT_API
-** DESCRIPTION:
-** These are only for externally visible routines and globals. For
-** internal routines, just use "extern" for type checking and that
-** will not export internal cross-file or forward-declared symbols.
-** Define a macro for declaring procedures return types. We use this to
-** deal with windoze specific type hackery for DLL definitions. Use
-** JS_EXTERN_API when the prototype for the method is declared. Use
-** JS_EXPORT_API for the implementation of the method.
-**
-** Example:
-** in dowhim.h
-** JS_EXTERN_API( void ) DoWhatIMean( void );
-** in dowhim.c
-** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
-**
-**
-***********************************************************************/
-#ifdef WIN32
-/* These also work for __MWERKS__ */
-#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type
-#define JS_EXPORT_API(__type) __declspec(dllexport) __type
-#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
-#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
-
-#define JS_DLL_CALLBACK
-#define JS_STATIC_DLL_CALLBACK(__x) static __x
-
-#elif defined(WIN16)
-
-#ifdef _WINDLL
-#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds
-#define JS_EXPORT_API(__type) __type _cdecl _export _loadds
-#define JS_EXTERN_DATA(__type) extern __type _export
-#define JS_EXPORT_DATA(__type) __type _export
-
-#define JS_DLL_CALLBACK __cdecl __loadds
-#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK
-
-#else /* this must be .EXE */
-#define JS_EXTERN_API(__type) extern __type _cdecl _export
-#define JS_EXPORT_API(__type) __type _cdecl _export
-#define JS_EXTERN_DATA(__type) extern __type _export
-#define JS_EXPORT_DATA(__type) __type _export
-
-#define JS_DLL_CALLBACK __cdecl __loadds
-#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK
-#endif /* _WINDLL */
-
-#elif defined(XP_MAC)
-#define JS_EXTERN_API(__type) extern __declspec(export) __type
-#define JS_EXPORT_API(__type) __declspec(export) __type
-#define JS_EXTERN_DATA(__type) extern __declspec(export) __type
-#define JS_EXPORT_DATA(__type) __declspec(export) __type
-
-#define JS_DLL_CALLBACK
-#define JS_STATIC_DLL_CALLBACK(__x) static __x
-
-#else /* Unix */
-
-#define JS_EXTERN_API(__type) extern __type
-#define JS_EXPORT_API(__type) __type
-#define JS_EXTERN_DATA(__type) extern __type
-#define JS_EXPORT_DATA(__type) __type
-
-#define JS_DLL_CALLBACK
-#define JS_STATIC_DLL_CALLBACK(__x) static __x
-
-#endif
-
-#ifdef _WIN32
-# if defined(__MWERKS__) || defined(__GNUC__)
-# define JS_IMPORT_API(__x) __x
-# else
-# define JS_IMPORT_API(__x) __declspec(dllimport) __x
-# endif
-#else
-# define JS_IMPORT_API(__x) JS_EXPORT_API (__x)
-#endif
-
-#if defined(_WIN32) && !defined(__MWERKS__) &&!defined(__GNUC__)
-# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
-#else
-# define JS_IMPORT_DATA(__x) __x
-#endif
-
-/*
- * The linkage of JS API functions differs depending on whether the file is
- * used within the JS library or not. Any source file within the JS
- * interpreter should define EXPORT_JS_API whereas any client of the library
- * should not.
- */
-#ifdef EXPORT_JS_API
-#define JS_PUBLIC_API(t) JS_EXPORT_API(t)
-#define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
-#else
-#define JS_PUBLIC_API(t) JS_IMPORT_API(t)
-#define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
-#endif
-
-#define JS_FRIEND_API(t) JS_PUBLIC_API(t)
-#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t)
-
-#ifdef _WIN32
-# define JS_INLINE __inline
-#elif defined(__GNUC__)
-# define JS_INLINE
-#else
-# define JS_INLINE
-#endif
-
-/***********************************************************************
-** MACROS: JS_BEGIN_MACRO
-** JS_END_MACRO
-** DESCRIPTION:
-** Macro body brackets so that macros with compound statement definitions
-** behave syntactically more like functions when called.
-***********************************************************************/
-#define JS_BEGIN_MACRO do {
-#define JS_END_MACRO } while (0)
-
-/***********************************************************************
-** MACROS: JS_BEGIN_EXTERN_C
-** JS_END_EXTERN_C
-** DESCRIPTION:
-** Macro shorthands for conditional C++ extern block delimiters.
-***********************************************************************/
-#ifdef __cplusplus
-#define JS_BEGIN_EXTERN_C extern "C" {
-#define JS_END_EXTERN_C }
-#else
-#define JS_BEGIN_EXTERN_C
-#define JS_END_EXTERN_C
-#endif
-
-/***********************************************************************
-** MACROS: JS_BIT
-** JS_BITMASK
-** DESCRIPTION:
-** Bit masking macros. XXX n must be <= 31 to be portable
-***********************************************************************/
-#define JS_BIT(n) ((JSUint32)1 << (n))
-#define JS_BITMASK(n) (JS_BIT(n) - 1)
-
-/***********************************************************************
-** MACROS: JS_HOWMANY
-** JS_ROUNDUP
-** JS_MIN
-** JS_MAX
-** DESCRIPTION:
-** Commonly used macros for operations on compatible types.
-***********************************************************************/
-#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y))
-#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y))
-#define JS_MIN(x,y) ((x)<(y)?(x):(y))
-#define JS_MAX(x,y) ((x)>(y)?(x):(y))
-
-#if (defined(XP_MAC) || defined(XP_WIN)) && !defined(CROSS_COMPILE)
-# include "jscpucfg.h" /* Use standard Mac or Windows configuration */
-#elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CROSS_COMPILE)
-# include "jsautocfg.h" /* Use auto-detected configuration */
-# include "jsosdep.h" /* ...and platform-specific flags */
-#else
-# error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN or XP_UNIX"
-#endif
-
-JS_BEGIN_EXTERN_C
-
-/************************************************************************
-** TYPES: JSUint8
-** JSInt8
-** DESCRIPTION:
-** The int8 types are known to be 8 bits each. There is no type that
-** is equivalent to a plain "char".
-************************************************************************/
-#if JS_BYTES_PER_BYTE == 1
-typedef unsigned char JSUint8;
-typedef signed char JSInt8;
-#else
-#error No suitable type for JSInt8/JSUint8
-#endif
-
-/************************************************************************
-** TYPES: JSUint16
-** JSInt16
-** DESCRIPTION:
-** The int16 types are known to be 16 bits each.
-************************************************************************/
-#if JS_BYTES_PER_SHORT == 2
-typedef unsigned short JSUint16;
-typedef short JSInt16;
-#else
-#error No suitable type for JSInt16/JSUint16
-#endif
-
-/************************************************************************
-** TYPES: JSUint32
-** JSInt32
-** DESCRIPTION:
-** The int32 types are known to be 32 bits each.
-************************************************************************/
-#if JS_BYTES_PER_INT == 4
-typedef unsigned int JSUint32;
-typedef int JSInt32;
-#define JS_INT32(x) x
-#define JS_UINT32(x) x ## U
-#elif JS_BYTES_PER_LONG == 4
-typedef unsigned long JSUint32;
-typedef long JSInt32;
-#define JS_INT32(x) x ## L
-#define JS_UINT32(x) x ## UL
-#else
-#error No suitable type for JSInt32/JSUint32
-#endif
-
-/************************************************************************
-** TYPES: JSUint64
-** JSInt64
-** DESCRIPTION:
-** The int64 types are known to be 64 bits each. Care must be used when
-** declaring variables of type JSUint64 or JSInt64. Different hardware
-** architectures and even different compilers have varying support for
-** 64 bit values. The only guaranteed portability requires the use of
-** the JSLL_ macros (see jslong.h).
-************************************************************************/
-#ifdef JS_HAVE_LONG_LONG
-#if JS_BYTES_PER_LONG == 8
-typedef long JSInt64;
-typedef unsigned long JSUint64;
-#elif defined(WIN16)
-typedef __int64 JSInt64;
-typedef unsigned __int64 JSUint64;
-#elif defined(WIN32) && !defined(__GNUC__)
-typedef __int64 JSInt64;
-typedef unsigned __int64 JSUint64;
-#else
-typedef long long JSInt64;
-typedef unsigned long long JSUint64;
-#endif /* JS_BYTES_PER_LONG == 8 */
-#else /* !JS_HAVE_LONG_LONG */
-typedef struct {
-#ifdef IS_LITTLE_ENDIAN
- JSUint32 lo, hi;
-#else
- JSUint32 hi, lo;
-#endif
-} JSInt64;
-typedef JSInt64 JSUint64;
-#endif /* !JS_HAVE_LONG_LONG */
-
-/************************************************************************
-** TYPES: JSUintn
-** JSIntn
-** DESCRIPTION:
-** The JSIntn types are most appropriate for automatic variables. They are
-** guaranteed to be at least 16 bits, though various architectures may
-** define them to be wider (e.g., 32 or even 64 bits). These types are
-** never valid for fields of a structure.
-************************************************************************/
-#if JS_BYTES_PER_INT >= 2
-typedef int JSIntn;
-typedef unsigned int JSUintn;
-#else
-#error 'sizeof(int)' not sufficient for platform use
-#endif
-
-/************************************************************************
-** TYPES: JSFloat64
-** DESCRIPTION:
-** NSPR's floating point type is always 64 bits.
-************************************************************************/
-typedef double JSFloat64;
-
-/************************************************************************
-** TYPES: JSSize
-** DESCRIPTION:
-** A type for representing the size of objects.
-************************************************************************/
-typedef size_t JSSize;
-
-/************************************************************************
-** TYPES: JSPtrDiff
-** DESCRIPTION:
-** A type for pointer difference. Variables of this type are suitable
-** for storing a pointer or pointer sutraction.
-************************************************************************/
-typedef ptrdiff_t JSPtrdiff;
-
-/************************************************************************
-** TYPES: JSUptrdiff
-** DESCRIPTION:
-** A type for pointer difference. Variables of this type are suitable
-** for storing a pointer or pointer sutraction.
-************************************************************************/
-typedef unsigned long JSUptrdiff;
-
-/************************************************************************
-** TYPES: JSBool
-** DESCRIPTION:
-** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE
-** for clarity of target type in assignments and actual arguments. Use
-** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
-** just as you would C int-valued conditions.
-************************************************************************/
-typedef JSIntn JSBool;
-#define JS_TRUE (JSIntn)1
-#define JS_FALSE (JSIntn)0
-
-/************************************************************************
-** TYPES: JSPackedBool
-** DESCRIPTION:
-** Use JSPackedBool within structs where bitfields are not desireable
-** but minimum and consistant overhead matters.
-************************************************************************/
-typedef JSUint8 JSPackedBool;
-
-/*
-** A JSWord is an integer that is the same size as a void*
-*/
-typedef long JSWord;
-typedef unsigned long JSUword;
-
-#include "jsotypes.h"
-
-JS_END_EXTERN_C
-
-#endif /* jstypes_h___ */
-
diff --git a/src/extension/script/js/jsutil.c b/src/extension/script/js/jsutil.c
deleted file mode 100644
index f64718ad4..000000000
--- a/src/extension/script/js/jsutil.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * IBM Corp.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * PR assertion checker.
- */
-#include "jsstddef.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "jstypes.h"
-#include "jsutil.h"
-
-#ifdef WIN32
-# include <windows.h>
-#endif
-
-#ifdef XP_MAC
-# include <Types.h>
-# include <stdarg.h>
-# include "jsprf.h"
-#endif
-
-#ifdef XP_MAC
-/*
- * PStrFromCStr converts the source C string to a destination
- * pascal string as it copies. The dest string will
- * be truncated to fit into an Str255 if necessary.
- * If the C String pointer is NULL, the pascal string's length is
- * set to zero.
- */
-static void PStrFromCStr(const char* src, Str255 dst)
-{
- short length = 0;
-
- /* handle case of overlapping strings */
- if ( (void*)src == (void*)dst )
- {
- unsigned char* curdst = &dst[1];
- unsigned char thisChar;
-
- thisChar = *(const unsigned char*)src++;
- while ( thisChar != '\0' )
- {
- unsigned char nextChar;
-
- /*
- * Use nextChar so we don't overwrite what we
- * are about to read
- */
- nextChar = *(const unsigned char*)src++;
- *curdst++ = thisChar;
- thisChar = nextChar;
-
- if ( ++length >= 255 )
- break;
- }
- }
- else if ( src != NULL )
- {
- unsigned char* curdst = &dst[1];
- /* count down so test it loop is faster */
- short overflow = 255;
- register char temp;
-
- /*
- * Can't do the K&R C thing of while (*s++ = *t++)
- * because it will copy trailing zero which might
- * overrun pascal buffer. Instead we use a temp variable.
- */
- while ( (temp = *src++) != 0 )
- {
- *(char*)curdst++ = temp;
-
- if ( --overflow <= 0 )
- break;
- }
- length = 255 - overflow;
- }
- dst[0] = length;
-}
-
-static void jsdebugstr(const char *debuggerMsg)
-{
- Str255 pStr;
-
- PStrFromCStr(debuggerMsg, pStr);
- DebugStr(pStr);
-}
-
-static void dprintf(const char *format, ...)
-{
- va_list ap;
- char *buffer;
-
- va_start(ap, format);
- buffer = (char *)JS_vsmprintf(format, ap);
- va_end(ap);
-
- jsdebugstr(buffer);
- JS_DELETE(buffer);
-}
-#endif /* XP_MAC */
-
-JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
-{
-#ifdef XP_MAC
- dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);
-#else
- fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
-#endif
-#if defined(WIN32)
- DebugBreak();
-#endif
-#if defined(XP_OS2)
- asm("int $3");
-#endif
-#ifndef XP_MAC
- abort();
-#endif
-}
diff --git a/src/extension/script/js/jsutil.h b/src/extension/script/js/jsutil.h
deleted file mode 100644
index d4edb919c..000000000
--- a/src/extension/script/js/jsutil.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * PR assertion checker.
- */
-
-#ifndef jsutil_h___
-#define jsutil_h___
-
-JS_BEGIN_EXTERN_C
-
-/***********************************************************************
-** FUNCTION: JS_MALLOC()
-** DESCRIPTION:
-** JS_NEW() allocates an untyped item of size _size from the heap.
-** INPUTS: _size: size in bytes of item to be allocated
-** OUTPUTS: untyped pointer to the node allocated
-** RETURN: pointer to node or error returned from malloc().
-***********************************************************************/
-#define JS_MALLOC(_bytes) (malloc((_bytes)))
-
-/***********************************************************************
-** FUNCTION: JS_DELETE()
-** DESCRIPTION:
-** JS_DELETE() unallocates an object previosly allocated via JS_NEW()
-** or JS_NEWZAP() to the heap.
-** INPUTS: pointer to previously allocated object
-** OUTPUTS: the referenced object is returned to the heap
-** RETURN: void
-***********************************************************************/
-#define JS_DELETE(_ptr) { free(_ptr); (_ptr) = NULL; }
-
-/***********************************************************************
-** FUNCTION: JS_NEW()
-** DESCRIPTION:
-** JS_NEW() allocates an item of type _struct from the heap.
-** INPUTS: _struct: a data type
-** OUTPUTS: pointer to _struct
-** RETURN: pointer to _struct or error returns from malloc().
-***********************************************************************/
-#define JS_NEW(_struct) ((_struct *) JS_MALLOC(sizeof(_struct)))
-
-#ifdef DEBUG
-
-extern JS_PUBLIC_API(void)
-JS_Assert(const char *s, const char *file, JSIntn ln);
-#define JS_ASSERT(_expr) \
- ((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__))
-
-#define JS_NOT_REACHED(_reasonStr) \
- JS_Assert(_reasonStr,__FILE__,__LINE__)
-
-#else
-
-#define JS_ASSERT(expr) ((void) 0)
-#define JS_NOT_REACHED(reasonStr)
-
-#endif /* defined(DEBUG) */
-
-/*
-** Abort the process in a non-graceful manner. This will cause a core file,
-** call to the debugger or other moral equivalent as well as causing the
-** entire process to stop.
-*/
-extern JS_PUBLIC_API(void) JS_Abort(void);
-
-JS_END_EXTERN_C
-
-#endif /* jsutil_h___ */
diff --git a/src/extension/script/js/jsxdrapi.c b/src/extension/script/js/jsxdrapi.c
deleted file mode 100644
index 1b092924d..000000000
--- a/src/extension/script/js/jsxdrapi.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include "jsstddef.h"
-#include "jsconfig.h"
-
-#if JS_HAS_XDR
-
-#include <string.h>
-#include "jstypes.h"
-#include "jsutil.h" /* Added by JSIFY */
-#include "jsdhash.h"
-#include "jsprf.h"
-#include "jsapi.h"
-#include "jscntxt.h"
-#include "jsobj.h" /* js_XDRObject */
-#include "jsscript.h" /* js_XDRScript */
-#include "jsstr.h"
-#include "jsxdrapi.h"
-
-#ifdef DEBUG
-#define DBG(x) x
-#else
-#define DBG(x) ((void)0)
-#endif
-
-typedef struct JSXDRMemState {
- JSXDRState state;
- char *base;
- uint32 count;
- uint32 limit;
-} JSXDRMemState;
-
-#define MEM_BLOCK 8192
-#define MEM_PRIV(xdr) ((JSXDRMemState *)(xdr))
-
-#define MEM_BASE(xdr) (MEM_PRIV(xdr)->base)
-#define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count)
-#define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit)
-
-#define MEM_LEFT(xdr, bytes) \
- JS_BEGIN_MACRO \
- if ((xdr)->mode == JSXDR_DECODE && \
- MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
- JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
- JSMSG_END_OF_DATA); \
- return 0; \
- } \
- JS_END_MACRO
-
-#define MEM_NEED(xdr, bytes) \
- JS_BEGIN_MACRO \
- if ((xdr)->mode == JSXDR_ENCODE) { \
- if (MEM_LIMIT(xdr) && \
- MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
- uint32 limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\
- void *data_ = JS_realloc((xdr)->cx, MEM_BASE(xdr), limit_); \
- if (!data_) \
- return 0; \
- MEM_BASE(xdr) = data_; \
- MEM_LIMIT(xdr) = limit_; \
- } \
- } else { \
- MEM_LEFT(xdr, bytes); \
- } \
- JS_END_MACRO
-
-#define MEM_DATA(xdr) ((void *)(MEM_BASE(xdr) + MEM_COUNT(xdr)))
-#define MEM_INCR(xdr,bytes) (MEM_COUNT(xdr) += (bytes))
-
-static JSBool
-mem_get32(JSXDRState *xdr, uint32 *lp)
-{
- MEM_LEFT(xdr, 4);
- *lp = *(uint32 *)MEM_DATA(xdr);
- MEM_INCR(xdr, 4);
- return JS_TRUE;
-}
-
-static JSBool
-mem_set32(JSXDRState *xdr, uint32 *lp)
-{
- MEM_NEED(xdr, 4);
- *(uint32 *)MEM_DATA(xdr) = *lp;
- MEM_INCR(xdr, 4);
- return JS_TRUE;
-}
-
-static JSBool
-mem_getbytes(JSXDRState *xdr, char *bytes, uint32 len)
-{
- MEM_LEFT(xdr, len);
- memcpy(bytes, MEM_DATA(xdr), len);
- MEM_INCR(xdr, len);
- return JS_TRUE;
-}
-
-static JSBool
-mem_setbytes(JSXDRState *xdr, char *bytes, uint32 len)
-{
- MEM_NEED(xdr, len);
- memcpy(MEM_DATA(xdr), bytes, len);
- MEM_INCR(xdr, len);
- return JS_TRUE;
-}
-
-static void *
-mem_raw(JSXDRState *xdr, uint32 len)
-{
- void *data;
- if (xdr->mode == JSXDR_ENCODE) {
- MEM_NEED(xdr, len);
- } else if (xdr->mode == JSXDR_DECODE) {
- MEM_LEFT(xdr, len);
- }
- data = MEM_DATA(xdr);
- MEM_INCR(xdr, len);
- return data;
-}
-
-static JSBool
-mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
-{
- switch (whence) {
- case JSXDR_SEEK_CUR:
- if ((int32)MEM_COUNT(xdr) + offset < 0) {
- JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
- JSMSG_SEEK_BEYOND_START);
- return JS_FALSE;
- }
- if (offset > 0)
- MEM_NEED(xdr, offset);
- MEM_COUNT(xdr) += offset;
- return JS_TRUE;
- case JSXDR_SEEK_SET:
- if (offset < 0) {
- JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
- JSMSG_SEEK_BEYOND_START);
- return JS_FALSE;
- }
- if (xdr->mode == JSXDR_ENCODE) {
- if ((uint32)offset > MEM_COUNT(xdr))
- MEM_NEED(xdr, offset - MEM_COUNT(xdr));
- MEM_COUNT(xdr) = offset;
- } else {
- if ((uint32)offset > MEM_LIMIT(xdr)) {
- JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
- JSMSG_SEEK_BEYOND_END);
- return JS_FALSE;
- }
- MEM_COUNT(xdr) = offset;
- }
- return JS_TRUE;
- case JSXDR_SEEK_END:
- if (offset >= 0 ||
- xdr->mode == JSXDR_ENCODE ||
- (int32)MEM_LIMIT(xdr) + offset < 0) {
- JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
- JSMSG_END_SEEK);
- return JS_FALSE;
- }
- MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset;
- return JS_TRUE;
- default: {
- char numBuf[12];
- JS_snprintf(numBuf, sizeof numBuf, "%d", whence);
- JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
- JSMSG_WHITHER_WHENCE, numBuf);
- return JS_FALSE;
- }
- }
-}
-
-static uint32
-mem_tell(JSXDRState *xdr)
-{
- return MEM_COUNT(xdr);
-}
-
-static void
-mem_finalize(JSXDRState *xdr)
-{
- JS_free(xdr->cx, MEM_BASE(xdr));
-}
-
-static JSXDROps xdrmem_ops = {
- mem_get32, mem_set32, mem_getbytes, mem_setbytes,
- mem_raw, mem_seek, mem_tell, mem_finalize
-};
-
-JS_PUBLIC_API(void)
-JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx)
-{
- xdr->mode = mode;
- xdr->cx = cx;
- xdr->registry = NULL;
- xdr->numclasses = xdr->maxclasses = 0;
- xdr->reghash = NULL;
- xdr->userdata = NULL;
-}
-
-JS_PUBLIC_API(JSXDRState *)
-JS_XDRNewMem(JSContext *cx, JSXDRMode mode)
-{
- JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState));
- if (!xdr)
- return NULL;
- JS_XDRInitBase(xdr, mode, cx);
- if (mode == JSXDR_ENCODE) {
- if (!(MEM_BASE(xdr) = JS_malloc(cx, MEM_BLOCK))) {
- JS_free(cx, xdr);
- return NULL;
- }
- } else {
- /* XXXbe ok, so better not deref MEM_BASE(xdr) if not ENCODE */
- MEM_BASE(xdr) = NULL;
- }
- xdr->ops = &xdrmem_ops;
- MEM_COUNT(xdr) = 0;
- MEM_LIMIT(xdr) = MEM_BLOCK;
- return xdr;
-}
-
-JS_PUBLIC_API(void *)
-JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp)
-{
- if (xdr->ops != &xdrmem_ops)
- return NULL;
- *lp = MEM_COUNT(xdr);
- return MEM_BASE(xdr);
-}
-
-JS_PUBLIC_API(void)
-JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len)
-{
- if (xdr->ops != &xdrmem_ops)
- return;
- MEM_LIMIT(xdr) = len;
- MEM_BASE(xdr) = data;
- MEM_COUNT(xdr) = 0;
-}
-
-JS_PUBLIC_API(uint32)
-JS_XDRMemDataLeft(JSXDRState *xdr)
-{
- if (xdr->ops != &xdrmem_ops)
- return 0;
- return MEM_LIMIT(xdr) - MEM_COUNT(xdr);
-}
-
-JS_PUBLIC_API(void)
-JS_XDRMemResetData(JSXDRState *xdr)
-{
- if (xdr->ops != &xdrmem_ops)
- return;
- MEM_COUNT(xdr) = 0;
-}
-
-JS_PUBLIC_API(void)
-JS_XDRDestroy(JSXDRState *xdr)
-{
- JSContext *cx = xdr->cx;
- xdr->ops->finalize(xdr);
- if (xdr->registry) {
- JS_free(cx, xdr->registry);
- if (xdr->reghash)
- JS_DHashTableDestroy(xdr->reghash);
- }
- JS_free(cx, xdr);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRUint8(JSXDRState *xdr, uint8 *b)
-{
- uint32 l = *b;
- if (!JS_XDRUint32(xdr, &l))
- return JS_FALSE;
- *b = (uint8) l;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRUint16(JSXDRState *xdr, uint16 *s)
-{
- uint32 l = *s;
- if (!JS_XDRUint32(xdr, &l))
- return JS_FALSE;
- *s = (uint16) l;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRUint32(JSXDRState *xdr, uint32 *lp)
-{
- JSBool ok = JS_TRUE;
- if (xdr->mode == JSXDR_ENCODE) {
- uint32 xl = JSXDR_SWAB32(*lp);
- ok = xdr->ops->set32(xdr, &xl);
- } else if (xdr->mode == JSXDR_DECODE) {
- ok = xdr->ops->get32(xdr, lp);
- *lp = JSXDR_SWAB32(*lp);
- }
- return ok;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len)
-{
- uint32 padlen;
- static char padbuf[JSXDR_ALIGN-1];
-
- if (xdr->mode == JSXDR_ENCODE) {
- if (!xdr->ops->setbytes(xdr, bytes, len))
- return JS_FALSE;
- } else {
- if (!xdr->ops->getbytes(xdr, bytes, len))
- return JS_FALSE;
- }
- len = xdr->ops->tell(xdr);
- if (len % JSXDR_ALIGN) {
- padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN);
- if (xdr->mode == JSXDR_ENCODE) {
- if (!xdr->ops->setbytes(xdr, padbuf, padlen))
- return JS_FALSE;
- } else {
- if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR))
- return JS_FALSE;
- }
- }
- return JS_TRUE;
-}
-
-/**
- * Convert between a C string and the XDR representation:
- * leading 32-bit count, then counted vector of chars,
- * then possibly \0 padding to multiple of 4.
- */
-JS_PUBLIC_API(JSBool)
-JS_XDRCString(JSXDRState *xdr, char **sp)
-{
- uint32 len;
-
- if (xdr->mode == JSXDR_ENCODE)
- len = strlen(*sp);
- JS_XDRUint32(xdr, &len);
- if (xdr->mode == JSXDR_DECODE) {
- if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1)))
- return JS_FALSE;
- }
- if (!JS_XDRBytes(xdr, *sp, len)) {
- if (xdr->mode == JSXDR_DECODE)
- JS_free(xdr->cx, *sp);
- return JS_FALSE;
- }
- if (xdr->mode == JSXDR_DECODE) {
- (*sp)[len] = '\0';
- } else if (xdr->mode == JSXDR_FREE) {
- JS_free(xdr->cx, *sp);
- *sp = NULL;
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
-{
- uint32 null = (*sp == NULL);
- if (!JS_XDRUint32(xdr, &null))
- return JS_FALSE;
- if (null) {
- *sp = NULL;
- return JS_TRUE;
- }
- return JS_XDRCString(xdr, sp);
-}
-
-/*
- * Convert between a JS (Unicode) string and the XDR representation.
- */
-JS_PUBLIC_API(JSBool)
-JS_XDRString(JSXDRState *xdr, JSString **strp)
-{
- uint32 i, len, padlen, nbytes;
- jschar *chars = NULL, *raw;
-
- if (xdr->mode == JSXDR_ENCODE)
- len = JSSTRING_LENGTH(*strp);
- if (!JS_XDRUint32(xdr, &len))
- return JS_FALSE;
- nbytes = len * sizeof(jschar);
-
- if (xdr->mode == JSXDR_DECODE) {
- if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
- return JS_FALSE;
- } else {
- chars = JSSTRING_CHARS(*strp);
- }
-
- padlen = nbytes % JSXDR_ALIGN;
- if (padlen) {
- padlen = JSXDR_ALIGN - padlen;
- nbytes += padlen;
- }
- if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
- goto bad;
- if (xdr->mode == JSXDR_ENCODE) {
- for (i = 0; i < len; i++)
- raw[i] = JSXDR_SWAB16(chars[i]);
- if (padlen)
- memset((char *)raw + nbytes - padlen, 0, padlen);
- } else if (xdr->mode == JSXDR_DECODE) {
- for (i = 0; i < len; i++)
- chars[i] = JSXDR_SWAB16(raw[i]);
- chars[len] = 0;
-
- if (!(*strp = JS_NewUCString(xdr->cx, chars, len)))
- goto bad;
- }
- return JS_TRUE;
-
-bad:
- if (xdr->mode == JSXDR_DECODE)
- JS_free(xdr->cx, chars);
- return JS_FALSE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp)
-{
- uint32 null = (*strp == NULL);
- if (!JS_XDRUint32(xdr, &null))
- return JS_FALSE;
- if (null) {
- *strp = NULL;
- return JS_TRUE;
- }
- return JS_XDRString(xdr, strp);
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
-{
- jsdouble d;
- if (xdr->mode == JSXDR_ENCODE)
- d = **dp;
-#if IS_BIG_ENDIAN
- if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) ||
- !JS_XDRUint32(xdr, (uint32 *)&d))
-#else
- if (!JS_XDRUint32(xdr, (uint32 *)&d) ||
- !JS_XDRUint32(xdr, (uint32 *)&d + 1))
-#endif
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE) {
- *dp = JS_NewDouble(xdr->cx, d);
- if (!*dp)
- return JS_FALSE;
- }
- return JS_TRUE;
-}
-
-/* These are magic pseudo-tags: see jsapi.h, near the top, for real tags. */
-#define JSVAL_XDRNULL 0x8
-#define JSVAL_XDRVOID 0xA
-
-JS_PUBLIC_API(JSBool)
-JS_XDRValue(JSXDRState *xdr, jsval *vp)
-{
- uint32 type;
-
- if (xdr->mode == JSXDR_ENCODE) {
- if (JSVAL_IS_NULL(*vp))
- type = JSVAL_XDRNULL;
- else if (JSVAL_IS_VOID(*vp))
- type = JSVAL_XDRVOID;
- else
- type = JSVAL_TAG(*vp);
- }
- if (!JS_XDRUint32(xdr, &type))
- return JS_FALSE;
-
- switch (type) {
- case JSVAL_XDRNULL:
- *vp = JSVAL_NULL;
- break;
- case JSVAL_XDRVOID:
- *vp = JSVAL_VOID;
- break;
- case JSVAL_STRING: {
- JSString *str;
- if (xdr->mode == JSXDR_ENCODE)
- str = JSVAL_TO_STRING(*vp);
- if (!JS_XDRString(xdr, &str))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- *vp = STRING_TO_JSVAL(str);
- break;
- }
- case JSVAL_DOUBLE: {
- jsdouble *dp;
- if (xdr->mode == JSXDR_ENCODE)
- dp = JSVAL_TO_DOUBLE(*vp);
- if (!JS_XDRDouble(xdr, &dp))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- *vp = DOUBLE_TO_JSVAL(dp);
- break;
- }
- case JSVAL_OBJECT: {
- JSObject *obj;
- if (xdr->mode == JSXDR_ENCODE)
- obj = JSVAL_TO_OBJECT(*vp);
- if (!js_XDRObject(xdr, &obj))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- *vp = OBJECT_TO_JSVAL(obj);
- break;
- }
- case JSVAL_BOOLEAN: {
- uint32 b;
- if (xdr->mode == JSXDR_ENCODE)
- b = (uint32) JSVAL_TO_BOOLEAN(*vp);
- if (!JS_XDRUint32(xdr, &b))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- *vp = BOOLEAN_TO_JSVAL((JSBool) b);
- break;
- }
- default: {
- uint32 i;
-
- JS_ASSERT(type & JSVAL_INT);
- if (xdr->mode == JSXDR_ENCODE)
- i = (uint32) JSVAL_TO_INT(*vp);
- if (!JS_XDRUint32(xdr, &i))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- *vp = INT_TO_JSVAL((int32) i);
- break;
- }
- }
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
-JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
-{
- if (!js_XDRScript(xdr, scriptp, NULL))
- return JS_FALSE;
- if (xdr->mode == JSXDR_DECODE)
- js_CallNewScriptHook(xdr->cx, *scriptp, NULL);
- return JS_TRUE;
-}
-
-#define CLASS_REGISTRY_MIN 8
-#define CLASS_INDEX_TO_ID(i) ((i)+1)
-#define CLASS_ID_TO_INDEX(id) ((id)-1)
-
-typedef struct JSRegHashEntry {
- JSDHashEntryHdr hdr;
- const char *name;
- uint32 index;
-} JSRegHashEntry;
-
-JS_PUBLIC_API(JSBool)
-JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
-{
- uintN numclasses, maxclasses;
- JSClass **registry;
-
- numclasses = xdr->numclasses;
- maxclasses = xdr->maxclasses;
- if (numclasses == maxclasses) {
- maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1;
- registry = (JSClass **)
- JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *));
- if (!registry)
- return JS_FALSE;
- xdr->registry = registry;
- xdr->maxclasses = maxclasses;
- } else {
- JS_ASSERT(numclasses && numclasses < maxclasses);
- registry = xdr->registry;
- }
-
- registry[numclasses] = clasp;
- if (xdr->reghash) {
- JSRegHashEntry *entry = (JSRegHashEntry *)
- JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD);
- if (!entry) {
- JS_ReportOutOfMemory(xdr->cx);
- return JS_FALSE;
- }
- entry->name = clasp->name;
- entry->index = numclasses;
- }
- *idp = CLASS_INDEX_TO_ID(numclasses);
- xdr->numclasses = ++numclasses;
- return JS_TRUE;
-}
-
-JS_PUBLIC_API(uint32)
-JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name)
-{
- uintN i, numclasses;
-
- numclasses = xdr->numclasses;
- if (numclasses >= 10) {
- JSRegHashEntry *entry;
-
- /* Bootstrap reghash from registry on first overpopulated Find. */
- if (!xdr->reghash) {
- xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
- sizeof(JSRegHashEntry),
- numclasses);
- if (xdr->reghash) {
- for (i = 0; i < numclasses; i++) {
- JSClass *clasp = xdr->registry[i];
- entry = (JSRegHashEntry *)
- JS_DHashTableOperate(xdr->reghash, clasp->name,
- JS_DHASH_ADD);
- entry->name = clasp->name;
- entry->index = i;
- }
- }
- }
-
- /* If we managed to create reghash, use it for O(1) Find. */
- if (xdr->reghash) {
- entry = (JSRegHashEntry *)
- JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP);
- if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr))
- return CLASS_INDEX_TO_ID(entry->index);
- }
- }
-
- /* Only a few classes, or we couldn't malloc reghash: use linear search. */
- for (i = 0; i < numclasses; i++) {
- if (!strcmp(name, xdr->registry[i]->name))
- return CLASS_INDEX_TO_ID(i);
- }
- return 0;
-}
-
-JS_PUBLIC_API(JSClass *)
-JS_XDRFindClassById(JSXDRState *xdr, uint32 id)
-{
- uintN i = CLASS_ID_TO_INDEX(id);
-
- if (i >= xdr->numclasses)
- return NULL;
- return xdr->registry[i];
-}
-
-#endif /* JS_HAS_XDR */
diff --git a/src/extension/script/js/jsxdrapi.h b/src/extension/script/js/jsxdrapi.h
deleted file mode 100644
index 874a62eeb..000000000
--- a/src/extension/script/js/jsxdrapi.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef jsxdrapi_h___
-#define jsxdrapi_h___
-
-/*
- * JS external data representation interface API.
- *
- * The XDR system is comprised of three major parts:
- *
- * - the state serialization/deserialization APIs, which allow consumers
- * of the API to serialize JS runtime state (script bytecodes, atom maps,
- * object graphs, etc.) for later restoration. These portions
- * are implemented in various appropriate files, such as jsscript.c
- * for the script portions and jsobj.c for object state.
- * - the callback APIs through which the runtime requests an opaque
- * representation of a native object, and through which the runtime
- * constructs a live native object from an opaque representation. These
- * portions are the responsibility of the native object implementor.
- * - utility functions for en/decoding of primitive types, such as
- * JSStrings. This portion is implemented in jsxdrapi.c.
- *
- * Spiritually guided by Sun's XDR, where appropriate.
- */
-
-#include "jspubtd.h"
-#include "jsprvtd.h"
-
-JS_BEGIN_EXTERN_C
-
-/* We use little-endian byteorder for all encoded data */
-
-#if defined IS_LITTLE_ENDIAN
-#define JSXDR_SWAB32(x) x
-#define JSXDR_SWAB16(x) x
-#elif defined IS_BIG_ENDIAN
-#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \
- (((uint32)(x) >> 8) & 0xff00) | \
- (((uint32)(x) << 8) & 0xff0000) | \
- ((uint32)(x) << 24))
-#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8))
-#else
-#error "unknown byte order"
-#endif
-
-#define JSXDR_ALIGN 4
-
-typedef enum JSXDRMode {
- JSXDR_ENCODE,
- JSXDR_DECODE,
- JSXDR_FREE
-} JSXDRMode;
-
-typedef enum JSXDRWhence {
- JSXDR_SEEK_SET,
- JSXDR_SEEK_CUR,
- JSXDR_SEEK_END
-} JSXDRWhence;
-
-typedef struct JSXDROps {
- JSBool (*get32)(JSXDRState *, uint32 *);
- JSBool (*set32)(JSXDRState *, uint32 *);
- JSBool (*getbytes)(JSXDRState *, char *, uint32);
- JSBool (*setbytes)(JSXDRState *, char *, uint32);
- void * (*raw)(JSXDRState *, uint32);
- JSBool (*seek)(JSXDRState *, int32, JSXDRWhence);
- uint32 (*tell)(JSXDRState *);
- void (*finalize)(JSXDRState *);
-} JSXDROps;
-
-struct JSXDRState {
- JSXDRMode mode;
- JSXDROps *ops;
- JSContext *cx;
- JSClass **registry;
- uintN numclasses;
- uintN maxclasses;
- void *reghash;
- void *userdata;
-};
-
-extern JS_PUBLIC_API(void)
-JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx);
-
-extern JS_PUBLIC_API(JSXDRState *)
-JS_XDRNewMem(JSContext *cx, JSXDRMode mode);
-
-extern JS_PUBLIC_API(void *)
-JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp);
-
-extern JS_PUBLIC_API(void)
-JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len);
-
-extern JS_PUBLIC_API(uint32)
-JS_XDRMemDataLeft(JSXDRState *xdr);
-
-extern JS_PUBLIC_API(void)
-JS_XDRMemResetData(JSXDRState *xdr);
-
-extern JS_PUBLIC_API(void)
-JS_XDRDestroy(JSXDRState *xdr);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRUint8(JSXDRState *xdr, uint8 *b);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRUint16(JSXDRState *xdr, uint16 *s);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRUint32(JSXDRState *xdr, uint32 *lp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRCString(JSXDRState *xdr, char **sp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRCStringOrNull(JSXDRState *xdr, char **sp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRString(JSXDRState *xdr, JSString **strp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRDouble(JSXDRState *xdr, jsdouble **dp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRValue(JSXDRState *xdr, jsval *vp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRScript(JSXDRState *xdr, JSScript **scriptp);
-
-extern JS_PUBLIC_API(JSBool)
-JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
-
-extern JS_PUBLIC_API(uint32)
-JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name);
-
-extern JS_PUBLIC_API(JSClass *)
-JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
-
-/*
- * Magic numbers.
- */
-#define JSXDR_MAGIC_SCRIPT_1 0xdead0001
-#define JSXDR_MAGIC_SCRIPT_2 0xdead0002
-#define JSXDR_MAGIC_SCRIPT_3 0xdead0003
-#define JSXDR_MAGIC_SCRIPT_4 0xdead0004
-#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_4
-
-JS_END_EXTERN_C
-
-#endif /* ! jsxdrapi_h___ */
diff --git a/src/extension/script/js/prmjtime.c b/src/extension/script/js/prmjtime.c
deleted file mode 100644
index 0a53f76bf..000000000
--- a/src/extension/script/js/prmjtime.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * PR time code.
- */
-#include "jsstddef.h"
-#ifdef SOLARIS
-#define _REENTRANT 1
-#endif
-#include <string.h>
-#include <time.h>
-#include "jstypes.h"
-#include "jsutil.h"
-
-#include "jsprf.h"
-#include "prmjtime.h"
-
-#define PRMJ_DO_MILLISECONDS 1
-
-#ifdef XP_OS2
-#include <sys/timeb.h>
-#endif
-#ifdef XP_WIN
-#include <windef.h>
-#include <winbase.h>
-#endif
-
-#ifdef XP_MAC
-#include <OSUtils.h>
-#include <TextUtils.h>
-#include <Resources.h>
-#include <Timer.h>
-#include <UTCUtils.h>
-#include <Power.h>
-#include <CodeFragments.h>
-#if !TARGET_CARBON
-#include <Traps.h>
-#endif
-#endif
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-
-#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
-extern int gettimeofday(struct timeval *tv);
-#endif
-
-#include <sys/time.h>
-
-#endif /* XP_UNIX */
-
-#ifdef XP_MAC
-static uint64 dstLocalBaseMicroseconds;
-static unsigned long gJanuaryFirst1970Seconds;
-
-static void MacintoshInitializeTime(void)
-{
- uint64 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((UnsignedWide*)&upTime);
-
- GetDateTime(&currentLocalTimeSeconds);
-
- JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC);
- JSLL_DIV(upTimeSecondsLong, upTime, microSecondsToSeconds);
- JSLL_L2I(upTimeSeconds, upTimeSecondsLong);
-
- startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds;
-
- /* Make sure that we normalize the macintosh base seconds to the unix base of January 1, 1970.
- */
-
- firstSecondOfUnixTime.year = 1970;
- firstSecondOfUnixTime.month = 1;
- firstSecondOfUnixTime.day = 1;
- firstSecondOfUnixTime.hour = 0;
- firstSecondOfUnixTime.minute = 0;
- firstSecondOfUnixTime.second = 0;
- firstSecondOfUnixTime.dayOfWeek = 0;
-
- DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds);
-
- startupTimeSeconds -= gJanuaryFirst1970Seconds;
-
- /* Now convert the startup time into a wide so that we can figure out GMT and DST.
- */
-
- JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds);
- JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC);
- JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds);
-}
-
-static SleepQRec gSleepQEntry = { NULL, sleepQType, NULL, 0 };
-static JSBool gSleepQEntryInstalled = JS_FALSE;
-
-static pascal long MySleepQProc(long message, SleepQRecPtr sleepQ)
-{
- /* just woke up from sleeping, so must recompute dstLocalBaseMicroseconds. */
- if (message == kSleepWakeUp)
- MacintoshInitializeTime();
- return 0;
-}
-
-/* Because serial port and SLIP conflict with ReadXPram calls,
- * we cache the call here
- */
-
-static void MyReadLocation(MachineLocation * loc)
-{
- static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */
- static JSBool didReadLocation = JS_FALSE;
- if (!didReadLocation)
- {
- MacintoshInitializeTime();
- ReadLocation(&storedLoc);
- /* install a sleep queue routine, so that when the machine wakes up, time can be recomputed. */
- if (&SleepQInstall != (void*)kUnresolvedCFragSymbolAddress
-#if !TARGET_CARBON
- && NGetTrapAddress(0xA28A, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap)
-#endif
- ) {
- if ((gSleepQEntry.sleepQProc = NewSleepQUPP(MySleepQProc)) != NULL) {
- SleepQInstall(&gSleepQEntry);
- gSleepQEntryInstalled = JS_TRUE;
- }
- }
- didReadLocation = JS_TRUE;
- }
- *loc = storedLoc;
-}
-
-
-#ifndef XP_MACOSX
-
-/* CFM library init and terminate routines. We'll use the terminate routine
- to clean up the sleep Q entry. On Mach-O, the sleep Q entry gets cleaned
- up for us, so nothing to do there.
-*/
-
-extern pascal OSErr __NSInitialize(const CFragInitBlock* initBlock);
-extern pascal void __NSTerminate();
-
-pascal OSErr __JSInitialize(const CFragInitBlock* initBlock);
-pascal void __JSTerminate(void);
-
-pascal OSErr __JSInitialize(const CFragInitBlock* initBlock)
-{
- return __NSInitialize(initBlock);
-}
-
-pascal void __JSTerminate()
-{
- /* clean up the sleepQ entry */
- if (gSleepQEntryInstalled)
- SleepQRemove(&gSleepQEntry);
-
- __NSTerminate();
-}
-#endif /* XP_MACOSX */
-
-#endif /* XP_MAC */
-
-#define IS_LEAP(year) \
- (year != 0 && ((((year & 0x3) == 0) && \
- ((year - ((year/100) * 100)) != 0)) || \
- (year - ((year/400) * 400)) == 0))
-
-#define PRMJ_HOUR_SECONDS 3600L
-#define PRMJ_DAY_SECONDS (24L * PRMJ_HOUR_SECONDS)
-#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)
-#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */
-/* function prototypes */
-static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm);
-/*
- * get the difference in seconds between this time zone and UTC (GMT)
- */
-JSInt32
-PRMJ_LocalGMTDifference()
-{
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
- 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 JSInt32 zone = -1L;
- MachineLocation machineLocation;
- JSInt32 gmtOffsetSeconds;
-
- /* 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. */
- gmtOffsetSeconds = (machineLocation.u.gmtDelta << 8);
- gmtOffsetSeconds >>= 8;
-
- /* Backout OS adjustment for DST, to give consistent GMT offset. */
- if (machineLocation.u.dlsDelta != 0)
- gmtOffsetSeconds -= PRMJ_HOUR_SECONDS;
- return (zone = -gmtOffsetSeconds);
-#endif
-}
-
-/* Constants for GMT offset from 1970 */
-#define G1970GMTMICROHI 0x00dcdcad /* micro secs to 1970 hi */
-#define G1970GMTMICROLOW 0x8b3fa000 /* micro secs to 1970 low */
-
-#define G2037GMTMICROHI 0x00e45fab /* micro secs to 2037 high */
-#define G2037GMTMICROLOW 0x7a238000 /* micro secs to 2037 low */
-
-/* Convert from base time to extended time */
-static JSInt64
-PRMJ_ToExtendedTime(JSInt32 base_time)
-{
- JSInt64 exttime;
- JSInt64 g1970GMTMicroSeconds;
- JSInt64 low;
- JSInt32 diff;
- JSInt64 tmp;
- JSInt64 tmp1;
-
- diff = PRMJ_LocalGMTDifference();
- JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC);
- JSLL_I2L(tmp1,diff);
- JSLL_MUL(tmp,tmp,tmp1);
-
- JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
- JSLL_UI2L(low,G1970GMTMICROLOW);
-#ifndef JS_HAVE_LONG_LONG
- JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
- JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
-#else
- JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
-#endif
- JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);
-
- JSLL_I2L(exttime,base_time);
- JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds);
- JSLL_SUB(exttime,exttime,tmp);
- return exttime;
-}
-
-JSInt64
-PRMJ_Now(void)
-{
-#ifdef XP_OS2
- JSInt64 s, us, ms2us, s2us;
- struct timeb b;
-#endif
-#ifdef XP_WIN
- JSInt64 s, us,
- win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000),
- ten = JSLL_INIT(0, 10);
- FILETIME time, midnight;
-#endif
-#if defined(XP_UNIX) || defined(XP_BEOS)
- struct timeval tv;
- JSInt64 s, us, s2us;
-#endif /* XP_UNIX */
-#ifdef XP_MAC
- JSUint64 upTime;
- JSInt64 localTime;
- JSInt64 gmtOffset;
- JSInt64 dstOffset;
- JSInt32 gmtDiff;
- JSInt64 s2us;
-#endif /* XP_MAC */
-
-#ifdef XP_OS2
- ftime(&b);
- JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
- JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
- JSLL_UI2L(s, b.time);
- JSLL_UI2L(us, b.millitm);
- JSLL_MUL(us, us, ms2us);
- JSLL_MUL(s, s, s2us);
- JSLL_ADD(s, s, us);
- return s;
-#endif
-#ifdef XP_WIN
- /* The windows epoch is around 1600. The unix epoch is around 1970.
- win2un is the difference (in windows time units which are 10 times
- more precise than the JS time unit) */
- GetSystemTimeAsFileTime(&time);
- /* Win9x gets confused at midnight
- http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423
- So if the low part (precision <8mins) is 0 then we get the time
- again. */
- if (!time.dwLowDateTime) {
- GetSystemTimeAsFileTime(&midnight);
- time.dwHighDateTime = midnight.dwHighDateTime;
- }
- JSLL_UI2L(s, time.dwHighDateTime);
- JSLL_UI2L(us, time.dwLowDateTime);
- JSLL_SHL(s, s, 32);
- JSLL_ADD(s, s, us);
- JSLL_SUB(s, s, win2un);
- JSLL_DIV(s, s, ten);
- return s;
-#endif
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
- gettimeofday(&tv);
-#else
- gettimeofday(&tv, 0);
-#endif /* _SVID_GETTOD */
- JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
- JSLL_UI2L(s, tv.tv_sec);
- JSLL_UI2L(us, tv.tv_usec);
- JSLL_MUL(s, s, s2us);
- JSLL_ADD(s, s, us);
- return s;
-#endif /* XP_UNIX */
-#ifdef XP_MAC
- JSLL_UI2L(localTime,0);
- gmtDiff = PRMJ_LocalGMTDifference();
- JSLL_I2L(gmtOffset,gmtDiff);
- JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
- JSLL_MUL(gmtOffset,gmtOffset,s2us);
-
- /* don't adjust for DST since it sets ctime and gmtime off on the MAC */
- Microseconds((UnsignedWide*)&upTime);
- JSLL_ADD(localTime,localTime,gmtOffset);
- JSLL_ADD(localTime,localTime, dstLocalBaseMicroseconds);
- JSLL_ADD(localTime,localTime, upTime);
-
- dstOffset = PRMJ_DSTOffset(localTime);
- JSLL_SUB(localTime,localTime,dstOffset);
-
- return *((JSUint64 *)&localTime);
-#endif /* XP_MAC */
-}
-
-/* Get the DST timezone offset for the time passed in */
-JSInt64
-PRMJ_DSTOffset(JSInt64 local_time)
-{
- JSInt64 us2s;
-#ifdef XP_MAC
- /*
- * Convert the local time passed in to Macintosh epoch seconds. Use UTC utilities to convert
- * to UTC time, then compare difference with our GMT offset. If they are the same, then
- * DST must not be in effect for the input date/time.
- */
- UInt32 macLocalSeconds = (local_time / PRMJ_USEC_PER_SEC) + gJanuaryFirst1970Seconds, utcSeconds;
- ConvertLocalTimeToUTC(macLocalSeconds, &utcSeconds);
- if ((utcSeconds - macLocalSeconds) == PRMJ_LocalGMTDifference())
- return 0;
- else {
- JSInt64 dlsOffset;
- JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
- JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS);
- JSLL_MUL(dlsOffset, dlsOffset, us2s);
- return dlsOffset;
- }
-#else
- time_t local;
- JSInt32 diff;
- JSInt64 maxtimet;
- struct tm tm;
- PRMJTime prtm;
-#ifndef HAVE_LOCALTIME_R
- struct tm *ptm;
-#endif
-
-
- JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
- JSLL_DIV(local_time, local_time, us2s);
-
- /* get the maximum of time_t value */
- JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET);
-
- if(JSLL_CMP(local_time,>,maxtimet)){
- JSLL_UI2L(local_time,PRMJ_MAX_UNIX_TIMET);
- } else if(!JSLL_GE_ZERO(local_time)){
- /*go ahead a day to make localtime work (does not work with 0) */
- JSLL_UI2L(local_time,PRMJ_DAY_SECONDS);
- }
- JSLL_L2UI(local,local_time);
- PRMJ_basetime(local_time,&prtm);
-#ifndef HAVE_LOCALTIME_R
- ptm = localtime(&local);
- if(!ptm){
- return JSLL_ZERO;
- }
- tm = *ptm;
-#else
- localtime_r(&local,&tm); /* get dst information */
-#endif
-
- diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) +
- ((tm.tm_min - prtm.tm_min) * 60);
-
- if(diff < 0){
- diff += PRMJ_DAY_SECONDS;
- }
-
- JSLL_UI2L(local_time,diff);
-
- JSLL_MUL(local_time,local_time,us2s);
-
- return(local_time);
-#endif
-}
-
-/* Format a time value into a buffer. Same semantics as strftime() */
-size_t
-PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm)
-{
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_MAC) || defined(XP_BEOS)
- struct tm a;
-
- /* Zero out the tm struct. Linux, SunOS 4 struct tm has extra members int
- * tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets
- * confused and dumps core. NSPR20 prtime.c attempts to fill these in by
- * calling mktime on the partially filled struct, but this doesn't seem to
- * work as well; the result string has "can't get timezone" for ECMA-valid
- * years. Might still make sense to use this, but find the range of years
- * for which valid tz information exists, and map (per ECMA hint) from the
- * given year into that range.
-
- * N.B. This hasn't been tested with anything that actually _uses_
- * tm_gmtoff; zero might be the wrong thing to set it to if you really need
- * to format a time. This fix is for jsdate.c, which only uses
- * JS_FormatTime to get a string representing the time zone. */
- memset(&a, 0, sizeof(struct tm));
-
- a.tm_sec = prtm->tm_sec;
- a.tm_min = prtm->tm_min;
- a.tm_hour = prtm->tm_hour;
- a.tm_mday = prtm->tm_mday;
- a.tm_mon = prtm->tm_mon;
- a.tm_wday = prtm->tm_wday;
- a.tm_year = prtm->tm_year - 1900;
- a.tm_yday = prtm->tm_yday;
- a.tm_isdst = prtm->tm_isdst;
-
- /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
- * are null. This doesn't quite work, though - the timezone is off by
- * tzoff + dst. (And mktime seems to return -1 for the exact dst
- * changeover time.)
-
- */
-
-#if defined(SUNOS4)
- if (mktime(&a) == -1) {
- /* Seems to fail whenever the requested date is outside of the 32-bit
- * UNIX epoch. We could proceed at this point (setting a.tm_zone to
- * "") but then strftime returns a string with a 2-digit field of
- * garbage for the year. So we return 0 and hope jsdate.c
- * will fall back on toString.
- */
- return 0;
- }
-#endif
-
- return strftime(buf, buflen, fmt, &a);
-#endif
-}
-
-/* table for number of days in a month */
-static int mtab[] = {
- /* jan, feb,mar,apr,may,jun */
- 31,28,31,30,31,30,
- /* july,aug,sep,oct,nov,dec */
- 31,31,30,31,30,31
-};
-
-/*
- * basic time calculation functionality for localtime and gmtime
- * setups up prtm argument with correct values based upon input number
- * of seconds.
- */
-static void
-PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm)
-{
- /* convert tsecs back to year,month,day,hour,secs */
- JSInt32 year = 0;
- JSInt32 month = 0;
- JSInt32 yday = 0;
- JSInt32 mday = 0;
- JSInt32 wday = 6; /* start on a Sunday */
- JSInt32 days = 0;
- JSInt32 seconds = 0;
- JSInt32 minutes = 0;
- JSInt32 hours = 0;
- JSInt32 isleap = 0;
- JSInt64 result;
- JSInt64 result1;
- JSInt64 result2;
- JSInt64 base;
-
- JSLL_UI2L(result,0);
- JSLL_UI2L(result1,0);
- JSLL_UI2L(result2,0);
-
- /* get the base time via UTC */
- base = PRMJ_ToExtendedTime(0);
- JSLL_UI2L(result, PRMJ_USEC_PER_SEC);
- JSLL_DIV(base,base,result);
- JSLL_ADD(tsecs,tsecs,base);
-
- JSLL_UI2L(result, PRMJ_YEAR_SECONDS);
- JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
- JSLL_ADD(result2,result,result1);
-
- /* get the year */
- while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) {
- /* subtract a year from tsecs */
- JSLL_SUB(tsecs,tsecs,result);
- days += 365;
- /* is it a leap year ? */
- if(IS_LEAP(year)){
- JSLL_SUB(tsecs,tsecs,result1);
- days++;
- }
- year++;
- isleap = IS_LEAP(year);
- }
-
- JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
-
- JSLL_DIV(result,tsecs,result1);
- JSLL_L2I(mday,result);
-
- /* let's find the month */
- while(((month == 1 && isleap) ?
- (mday >= mtab[month] + 1) :
- (mday >= mtab[month]))){
- yday += mtab[month];
- days += mtab[month];
-
- mday -= mtab[month];
-
- /* it's a Feb, check if this is a leap year */
- if(month == 1 && isleap != 0){
- yday++;
- days++;
- mday--;
- }
- month++;
- }
-
- /* now adjust tsecs */
- JSLL_MUL(result,result,result1);
- JSLL_SUB(tsecs,tsecs,result);
-
- mday++; /* day of month always start with 1 */
- days += mday;
- wday = (days + wday) % 7;
-
- yday += mday;
-
- /* get the hours */
- JSLL_UI2L(result1,PRMJ_HOUR_SECONDS);
- JSLL_DIV(result,tsecs,result1);
- JSLL_L2I(hours,result);
- JSLL_MUL(result,result,result1);
- JSLL_SUB(tsecs,tsecs,result);
-
- /* get minutes */
- JSLL_UI2L(result1,60);
- JSLL_DIV(result,tsecs,result1);
- JSLL_L2I(minutes,result);
- JSLL_MUL(result,result,result1);
- JSLL_SUB(tsecs,tsecs,result);
-
- JSLL_L2I(seconds,tsecs);
-
- prtm->tm_usec = 0L;
- prtm->tm_sec = (JSInt8)seconds;
- prtm->tm_min = (JSInt8)minutes;
- prtm->tm_hour = (JSInt8)hours;
- prtm->tm_mday = (JSInt8)mday;
- prtm->tm_mon = (JSInt8)month;
- prtm->tm_wday = (JSInt8)wday;
- prtm->tm_year = (JSInt16)year;
- prtm->tm_yday = (JSInt16)yday;
-}
diff --git a/src/extension/script/js/prmjtime.h b/src/extension/script/js/prmjtime.h
deleted file mode 100644
index 6a94a11b1..000000000
--- a/src/extension/script/js/prmjtime.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef prmjtime_h___
-#define prmjtime_h___
-/*
- * PR date stuff for mocha and java. Placed here temporarily not to break
- * Navigator and localize changes to mocha.
- */
-#include <time.h>
-#include "jslong.h"
-#ifdef MOZILLA_CLIENT
-#include "jscompat.h"
-#endif
-
-JS_BEGIN_EXTERN_C
-
-typedef struct PRMJTime PRMJTime;
-
-/*
- * Broken down form of 64 bit time value.
- */
-struct PRMJTime {
- JSInt32 tm_usec; /* microseconds of second (0-999999) */
- JSInt8 tm_sec; /* seconds of minute (0-59) */
- JSInt8 tm_min; /* minutes of hour (0-59) */
- JSInt8 tm_hour; /* hour of day (0-23) */
- JSInt8 tm_mday; /* day of month (1-31) */
- JSInt8 tm_mon; /* month of year (0-11) */
- JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */
- JSInt16 tm_year; /* absolute year, AD */
- JSInt16 tm_yday; /* day of year (0 to 365) */
- JSInt8 tm_isdst; /* non-zero if DST in effect */
-};
-
-/* Some handy constants */
-#define PRMJ_USEC_PER_SEC 1000000L
-#define PRMJ_USEC_PER_MSEC 1000L
-
-/* Return the current local time in micro-seconds */
-extern JSInt64
-PRMJ_Now(void);
-
-/* get the difference between this time zone and gmt timezone in seconds */
-extern JSInt32
-PRMJ_LocalGMTDifference(void);
-
-/* Format a time value into a buffer. Same semantics as strftime() */
-extern size_t
-PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm);
-
-/* Get the DST offset for the local time passed in */
-extern JSInt64
-PRMJ_DSTOffset(JSInt64 local_time);
-
-JS_END_EXTERN_C
-
-#endif /* prmjtime_h___ */
-
diff --git a/src/extension/script/js/resource.h b/src/extension/script/js/resource.h
deleted file mode 100644
index 9301810e4..000000000
--- a/src/extension/script/js/resource.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by js3240.rc
-//
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1000
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif