]>
Commit | Line | Data |
---|---|---|
bd3239d2 MF |
1 | extern "C" { |
2 | typedef float float_t; | |
3 | typedef double double_t; | |
4 | extern double acos (double __x) throw (); extern double __acos (double __x) throw (); | |
5 | extern double asin (double __x) throw (); extern double __asin (double __x) throw (); | |
6 | extern double atan (double __x) throw (); extern double __atan (double __x) throw (); | |
7 | extern double atan2 (double __y, double __x) throw (); extern double __atan2 (double __y, double __x) throw (); | |
8 | extern double cos (double __x) throw (); extern double __cos (double __x) throw (); | |
9 | extern double sin (double __x) throw (); extern double __sin (double __x) throw (); | |
10 | extern double tan (double __x) throw (); extern double __tan (double __x) throw (); | |
11 | extern double cosh (double __x) throw (); extern double __cosh (double __x) throw (); | |
12 | extern double sinh (double __x) throw (); extern double __sinh (double __x) throw (); | |
13 | extern double tanh (double __x) throw (); extern double __tanh (double __x) throw (); | |
14 | extern void sincos (double __x, double *__sinx, double *__cosx) throw (); extern void __sincos (double __x, double *__sinx, double *__cosx) throw () | |
15 | ; | |
16 | extern double acosh (double __x) throw (); extern double __acosh (double __x) throw (); | |
17 | extern double asinh (double __x) throw (); extern double __asinh (double __x) throw (); | |
18 | extern double atanh (double __x) throw (); extern double __atanh (double __x) throw (); | |
19 | extern double exp (double __x) throw (); extern double __exp (double __x) throw (); | |
20 | extern double frexp (double __x, int *__exponent) throw (); extern double __frexp (double __x, int *__exponent) throw (); | |
21 | extern double ldexp (double __x, int __exponent) throw (); extern double __ldexp (double __x, int __exponent) throw (); | |
22 | extern double log (double __x) throw (); extern double __log (double __x) throw (); | |
23 | extern double log10 (double __x) throw (); extern double __log10 (double __x) throw (); | |
24 | extern double modf (double __x, double *__iptr) throw (); extern double __modf (double __x, double *__iptr) throw () __attribute__ ((__nonnull__ (2))); | |
25 | extern double exp10 (double __x) throw (); extern double __exp10 (double __x) throw (); | |
26 | extern double pow10 (double __x) throw (); extern double __pow10 (double __x) throw (); | |
27 | extern double expm1 (double __x) throw (); extern double __expm1 (double __x) throw (); | |
28 | extern double log1p (double __x) throw (); extern double __log1p (double __x) throw (); | |
29 | extern double logb (double __x) throw (); extern double __logb (double __x) throw (); | |
30 | extern double exp2 (double __x) throw (); extern double __exp2 (double __x) throw (); | |
31 | extern double log2 (double __x) throw (); extern double __log2 (double __x) throw (); | |
32 | extern double pow (double __x, double __y) throw (); extern double __pow (double __x, double __y) throw (); | |
33 | extern double sqrt (double __x) throw (); extern double __sqrt (double __x) throw (); | |
34 | extern double hypot (double __x, double __y) throw (); extern double __hypot (double __x, double __y) throw (); | |
35 | extern double cbrt (double __x) throw (); extern double __cbrt (double __x) throw (); | |
36 | extern double ceil (double __x) throw () __attribute__ ((__const__)); extern double __ceil (double __x) throw () __attribute__ ((__const__)); | |
37 | extern double fabs (double __x) throw () __attribute__ ((__const__)); extern double __fabs (double __x) throw () __attribute__ ((__const__)); | |
38 | extern double floor (double __x) throw () __attribute__ ((__const__)); extern double __floor (double __x) throw () __attribute__ ((__const__)); | |
39 | extern double fmod (double __x, double __y) throw (); extern double __fmod (double __x, double __y) throw (); | |
40 | extern int __isinf (double __value) throw () __attribute__ ((__const__)); | |
41 | extern int __finite (double __value) throw () __attribute__ ((__const__)); | |
42 | extern int isinf (double __value) throw () __attribute__ ((__const__)); | |
43 | extern int finite (double __value) throw () __attribute__ ((__const__)); | |
44 | extern double drem (double __x, double __y) throw (); extern double __drem (double __x, double __y) throw (); | |
45 | extern double significand (double __x) throw (); extern double __significand (double __x) throw (); | |
46 | extern double copysign (double __x, double __y) throw () __attribute__ ((__const__)); extern double __copysign (double __x, double __y) throw () __attribute__ ((__const__)); | |
47 | extern double nan (const char *__tagb) throw () __attribute__ ((__const__)); extern double __nan (const char *__tagb) throw () __attribute__ ((__const__)); | |
48 | extern int __isnan (double __value) throw () __attribute__ ((__const__)); | |
49 | extern int isnan (double __value) throw () __attribute__ ((__const__)); | |
50 | extern double j0 (double) throw (); extern double __j0 (double) throw (); | |
51 | extern double j1 (double) throw (); extern double __j1 (double) throw (); | |
52 | extern double jn (int, double) throw (); extern double __jn (int, double) throw (); | |
53 | extern double y0 (double) throw (); extern double __y0 (double) throw (); | |
54 | extern double y1 (double) throw (); extern double __y1 (double) throw (); | |
55 | extern double yn (int, double) throw (); extern double __yn (int, double) throw (); | |
56 | extern double erf (double) throw (); extern double __erf (double) throw (); | |
57 | extern double erfc (double) throw (); extern double __erfc (double) throw (); | |
58 | extern double lgamma (double) throw (); extern double __lgamma (double) throw (); | |
59 | extern double tgamma (double) throw (); extern double __tgamma (double) throw (); | |
60 | extern double gamma (double) throw (); extern double __gamma (double) throw (); | |
61 | extern double lgamma_r (double, int *__signgamp) throw (); extern double __lgamma_r (double, int *__signgamp) throw (); | |
62 | extern double rint (double __x) throw (); extern double __rint (double __x) throw (); | |
63 | extern double nextafter (double __x, double __y) throw () __attribute__ ((__const__)); extern double __nextafter (double __x, double __y) throw () __attribute__ ((__const__)); | |
64 | extern double nexttoward (double __x, long double __y) throw () __attribute__ ((__const__)); extern double __nexttoward (double __x, long double __y) throw () __attribute__ ((__const__)); | |
65 | extern double remainder (double __x, double __y) throw (); extern double __remainder (double __x, double __y) throw (); | |
66 | extern double scalbn (double __x, int __n) throw (); extern double __scalbn (double __x, int __n) throw (); | |
67 | extern int ilogb (double __x) throw (); extern int __ilogb (double __x) throw (); | |
68 | extern double scalbln (double __x, long int __n) throw (); extern double __scalbln (double __x, long int __n) throw (); | |
69 | extern double nearbyint (double __x) throw (); extern double __nearbyint (double __x) throw (); | |
70 | extern double round (double __x) throw () __attribute__ ((__const__)); extern double __round (double __x) throw () __attribute__ ((__const__)); | |
71 | extern double trunc (double __x) throw () __attribute__ ((__const__)); extern double __trunc (double __x) throw () __attribute__ ((__const__)); | |
72 | extern double remquo (double __x, double __y, int *__quo) throw (); extern double __remquo (double __x, double __y, int *__quo) throw (); | |
73 | extern long int lrint (double __x) throw (); extern long int __lrint (double __x) throw (); | |
74 | __extension__ | |
75 | extern long long int llrint (double __x) throw (); extern long long int __llrint (double __x) throw (); | |
76 | extern long int lround (double __x) throw (); extern long int __lround (double __x) throw (); | |
77 | __extension__ | |
78 | extern long long int llround (double __x) throw (); extern long long int __llround (double __x) throw (); | |
79 | extern double fdim (double __x, double __y) throw (); extern double __fdim (double __x, double __y) throw (); | |
80 | extern double fmax (double __x, double __y) throw () __attribute__ ((__const__)); extern double __fmax (double __x, double __y) throw () __attribute__ ((__const__)); | |
81 | extern double fmin (double __x, double __y) throw () __attribute__ ((__const__)); extern double __fmin (double __x, double __y) throw () __attribute__ ((__const__)); | |
82 | extern int __fpclassify (double __value) throw () | |
83 | __attribute__ ((__const__)); | |
84 | extern int __signbit (double __value) throw () | |
85 | __attribute__ ((__const__)); | |
86 | extern double fma (double __x, double __y, double __z) throw (); extern double __fma (double __x, double __y, double __z) throw (); | |
87 | extern int __issignaling (double __value) throw () | |
88 | __attribute__ ((__const__)); | |
89 | extern double scalb (double __x, double __n) throw (); extern double __scalb (double __x, double __n) throw (); | |
90 | extern float acosf (float __x) throw (); extern float __acosf (float __x) throw (); | |
91 | extern float asinf (float __x) throw (); extern float __asinf (float __x) throw (); | |
92 | extern float atanf (float __x) throw (); extern float __atanf (float __x) throw (); | |
93 | extern float atan2f (float __y, float __x) throw (); extern float __atan2f (float __y, float __x) throw (); | |
94 | extern float cosf (float __x) throw (); extern float __cosf (float __x) throw (); | |
95 | extern float sinf (float __x) throw (); extern float __sinf (float __x) throw (); | |
96 | extern float tanf (float __x) throw (); extern float __tanf (float __x) throw (); | |
97 | extern float coshf (float __x) throw (); extern float __coshf (float __x) throw (); | |
98 | extern float sinhf (float __x) throw (); extern float __sinhf (float __x) throw (); | |
99 | extern float tanhf (float __x) throw (); extern float __tanhf (float __x) throw (); | |
100 | extern void sincosf (float __x, float *__sinx, float *__cosx) throw (); extern void __sincosf (float __x, float *__sinx, float *__cosx) throw () | |
101 | ; | |
102 | extern float acoshf (float __x) throw (); extern float __acoshf (float __x) throw (); | |
103 | extern float asinhf (float __x) throw (); extern float __asinhf (float __x) throw (); | |
104 | extern float atanhf (float __x) throw (); extern float __atanhf (float __x) throw (); | |
105 | extern float expf (float __x) throw (); extern float __expf (float __x) throw (); | |
106 | extern float frexpf (float __x, int *__exponent) throw (); extern float __frexpf (float __x, int *__exponent) throw (); | |
107 | extern float ldexpf (float __x, int __exponent) throw (); extern float __ldexpf (float __x, int __exponent) throw (); | |
108 | extern float logf (float __x) throw (); extern float __logf (float __x) throw (); | |
109 | extern float log10f (float __x) throw (); extern float __log10f (float __x) throw (); | |
110 | extern float modff (float __x, float *__iptr) throw (); extern float __modff (float __x, float *__iptr) throw () __attribute__ ((__nonnull__ (2))); | |
111 | extern float exp10f (float __x) throw (); extern float __exp10f (float __x) throw (); | |
112 | extern float pow10f (float __x) throw (); extern float __pow10f (float __x) throw (); | |
113 | extern float expm1f (float __x) throw (); extern float __expm1f (float __x) throw (); | |
114 | extern float log1pf (float __x) throw (); extern float __log1pf (float __x) throw (); | |
115 | extern float logbf (float __x) throw (); extern float __logbf (float __x) throw (); | |
116 | extern float exp2f (float __x) throw (); extern float __exp2f (float __x) throw (); | |
117 | extern float log2f (float __x) throw (); extern float __log2f (float __x) throw (); | |
118 | extern float powf (float __x, float __y) throw (); extern float __powf (float __x, float __y) throw (); | |
119 | extern float sqrtf (float __x) throw (); extern float __sqrtf (float __x) throw (); | |
120 | extern float hypotf (float __x, float __y) throw (); extern float __hypotf (float __x, float __y) throw (); | |
121 | extern float cbrtf (float __x) throw (); extern float __cbrtf (float __x) throw (); | |
122 | extern float ceilf (float __x) throw () __attribute__ ((__const__)); extern float __ceilf (float __x) throw () __attribute__ ((__const__)); | |
123 | extern float fabsf (float __x) throw () __attribute__ ((__const__)); extern float __fabsf (float __x) throw () __attribute__ ((__const__)); | |
124 | extern float floorf (float __x) throw () __attribute__ ((__const__)); extern float __floorf (float __x) throw () __attribute__ ((__const__)); | |
125 | extern float fmodf (float __x, float __y) throw (); extern float __fmodf (float __x, float __y) throw (); | |
126 | extern int __isinff (float __value) throw () __attribute__ ((__const__)); | |
127 | extern int __finitef (float __value) throw () __attribute__ ((__const__)); | |
128 | extern int isinff (float __value) throw () __attribute__ ((__const__)); | |
129 | extern int finitef (float __value) throw () __attribute__ ((__const__)); | |
130 | extern float dremf (float __x, float __y) throw (); extern float __dremf (float __x, float __y) throw (); | |
131 | extern float significandf (float __x) throw (); extern float __significandf (float __x) throw (); | |
132 | extern float copysignf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __copysignf (float __x, float __y) throw () __attribute__ ((__const__)); | |
133 | extern float nanf (const char *__tagb) throw () __attribute__ ((__const__)); extern float __nanf (const char *__tagb) throw () __attribute__ ((__const__)); | |
134 | extern int __isnanf (float __value) throw () __attribute__ ((__const__)); | |
135 | extern int isnanf (float __value) throw () __attribute__ ((__const__)); | |
136 | extern float j0f (float) throw (); extern float __j0f (float) throw (); | |
137 | extern float j1f (float) throw (); extern float __j1f (float) throw (); | |
138 | extern float jnf (int, float) throw (); extern float __jnf (int, float) throw (); | |
139 | extern float y0f (float) throw (); extern float __y0f (float) throw (); | |
140 | extern float y1f (float) throw (); extern float __y1f (float) throw (); | |
141 | extern float ynf (int, float) throw (); extern float __ynf (int, float) throw (); | |
142 | extern float erff (float) throw (); extern float __erff (float) throw (); | |
143 | extern float erfcf (float) throw (); extern float __erfcf (float) throw (); | |
144 | extern float lgammaf (float) throw (); extern float __lgammaf (float) throw (); | |
145 | extern float tgammaf (float) throw (); extern float __tgammaf (float) throw (); | |
146 | extern float gammaf (float) throw (); extern float __gammaf (float) throw (); | |
147 | extern float lgammaf_r (float, int *__signgamp) throw (); extern float __lgammaf_r (float, int *__signgamp) throw (); | |
148 | extern float rintf (float __x) throw (); extern float __rintf (float __x) throw (); | |
149 | extern float nextafterf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __nextafterf (float __x, float __y) throw () __attribute__ ((__const__)); | |
150 | extern float nexttowardf (float __x, long double __y) throw () __attribute__ ((__const__)); extern float __nexttowardf (float __x, long double __y) throw () __attribute__ ((__const__)); | |
151 | extern float remainderf (float __x, float __y) throw (); extern float __remainderf (float __x, float __y) throw (); | |
152 | extern float scalbnf (float __x, int __n) throw (); extern float __scalbnf (float __x, int __n) throw (); | |
153 | extern int ilogbf (float __x) throw (); extern int __ilogbf (float __x) throw (); | |
154 | extern float scalblnf (float __x, long int __n) throw (); extern float __scalblnf (float __x, long int __n) throw (); | |
155 | extern float nearbyintf (float __x) throw (); extern float __nearbyintf (float __x) throw (); | |
156 | extern float roundf (float __x) throw () __attribute__ ((__const__)); extern float __roundf (float __x) throw () __attribute__ ((__const__)); | |
157 | extern float truncf (float __x) throw () __attribute__ ((__const__)); extern float __truncf (float __x) throw () __attribute__ ((__const__)); | |
158 | extern float remquof (float __x, float __y, int *__quo) throw (); extern float __remquof (float __x, float __y, int *__quo) throw (); | |
159 | extern long int lrintf (float __x) throw (); extern long int __lrintf (float __x) throw (); | |
160 | __extension__ | |
161 | extern long long int llrintf (float __x) throw (); extern long long int __llrintf (float __x) throw (); | |
162 | extern long int lroundf (float __x) throw (); extern long int __lroundf (float __x) throw (); | |
163 | __extension__ | |
164 | extern long long int llroundf (float __x) throw (); extern long long int __llroundf (float __x) throw (); | |
165 | extern float fdimf (float __x, float __y) throw (); extern float __fdimf (float __x, float __y) throw (); | |
166 | extern float fmaxf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __fmaxf (float __x, float __y) throw () __attribute__ ((__const__)); | |
167 | extern float fminf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __fminf (float __x, float __y) throw () __attribute__ ((__const__)); | |
168 | extern int __fpclassifyf (float __value) throw () | |
169 | __attribute__ ((__const__)); | |
170 | extern int __signbitf (float __value) throw () | |
171 | __attribute__ ((__const__)); | |
172 | extern float fmaf (float __x, float __y, float __z) throw (); extern float __fmaf (float __x, float __y, float __z) throw (); | |
173 | extern int __issignalingf (float __value) throw () | |
174 | __attribute__ ((__const__)); | |
175 | extern float scalbf (float __x, float __n) throw (); extern float __scalbf (float __x, float __n) throw (); | |
176 | extern long double acosl (long double __x) throw (); extern long double __acosl (long double __x) throw (); | |
177 | extern long double asinl (long double __x) throw (); extern long double __asinl (long double __x) throw (); | |
178 | extern long double atanl (long double __x) throw (); extern long double __atanl (long double __x) throw (); | |
179 | extern long double atan2l (long double __y, long double __x) throw (); extern long double __atan2l (long double __y, long double __x) throw (); | |
180 | extern long double cosl (long double __x) throw (); extern long double __cosl (long double __x) throw (); | |
181 | extern long double sinl (long double __x) throw (); extern long double __sinl (long double __x) throw (); | |
182 | extern long double tanl (long double __x) throw (); extern long double __tanl (long double __x) throw (); | |
183 | extern long double coshl (long double __x) throw (); extern long double __coshl (long double __x) throw (); | |
184 | extern long double sinhl (long double __x) throw (); extern long double __sinhl (long double __x) throw (); | |
185 | extern long double tanhl (long double __x) throw (); extern long double __tanhl (long double __x) throw (); | |
186 | extern void sincosl (long double __x, long double *__sinx, long double *__cosx) throw (); extern void __sincosl (long double __x, long double *__sinx, long double *__cosx) throw () | |
187 | ; | |
188 | extern long double acoshl (long double __x) throw (); extern long double __acoshl (long double __x) throw (); | |
189 | extern long double asinhl (long double __x) throw (); extern long double __asinhl (long double __x) throw (); | |
190 | extern long double atanhl (long double __x) throw (); extern long double __atanhl (long double __x) throw (); | |
191 | extern long double expl (long double __x) throw (); extern long double __expl (long double __x) throw (); | |
192 | extern long double frexpl (long double __x, int *__exponent) throw (); extern long double __frexpl (long double __x, int *__exponent) throw (); | |
193 | extern long double ldexpl (long double __x, int __exponent) throw (); extern long double __ldexpl (long double __x, int __exponent) throw (); | |
194 | extern long double logl (long double __x) throw (); extern long double __logl (long double __x) throw (); | |
195 | extern long double log10l (long double __x) throw (); extern long double __log10l (long double __x) throw (); | |
196 | extern long double modfl (long double __x, long double *__iptr) throw (); extern long double __modfl (long double __x, long double *__iptr) throw () __attribute__ ((__nonnull__ (2))); | |
197 | extern long double exp10l (long double __x) throw (); extern long double __exp10l (long double __x) throw (); | |
198 | extern long double pow10l (long double __x) throw (); extern long double __pow10l (long double __x) throw (); | |
199 | extern long double expm1l (long double __x) throw (); extern long double __expm1l (long double __x) throw (); | |
200 | extern long double log1pl (long double __x) throw (); extern long double __log1pl (long double __x) throw (); | |
201 | extern long double logbl (long double __x) throw (); extern long double __logbl (long double __x) throw (); | |
202 | extern long double exp2l (long double __x) throw (); extern long double __exp2l (long double __x) throw (); | |
203 | extern long double log2l (long double __x) throw (); extern long double __log2l (long double __x) throw (); | |
204 | extern long double powl (long double __x, long double __y) throw (); extern long double __powl (long double __x, long double __y) throw (); | |
205 | extern long double sqrtl (long double __x) throw (); extern long double __sqrtl (long double __x) throw (); | |
206 | extern long double hypotl (long double __x, long double __y) throw (); extern long double __hypotl (long double __x, long double __y) throw (); | |
207 | extern long double cbrtl (long double __x) throw (); extern long double __cbrtl (long double __x) throw (); | |
208 | extern long double ceill (long double __x) throw () __attribute__ ((__const__)); extern long double __ceill (long double __x) throw () __attribute__ ((__const__)); | |
209 | extern long double fabsl (long double __x) throw () __attribute__ ((__const__)); extern long double __fabsl (long double __x) throw () __attribute__ ((__const__)); | |
210 | extern long double floorl (long double __x) throw () __attribute__ ((__const__)); extern long double __floorl (long double __x) throw () __attribute__ ((__const__)); | |
211 | extern long double fmodl (long double __x, long double __y) throw (); extern long double __fmodl (long double __x, long double __y) throw (); | |
212 | extern int __isinfl (long double __value) throw () __attribute__ ((__const__)); | |
213 | extern int __finitel (long double __value) throw () __attribute__ ((__const__)); | |
214 | extern int isinfl (long double __value) throw () __attribute__ ((__const__)); | |
215 | extern int finitel (long double __value) throw () __attribute__ ((__const__)); | |
216 | extern long double dreml (long double __x, long double __y) throw (); extern long double __dreml (long double __x, long double __y) throw (); | |
217 | extern long double significandl (long double __x) throw (); extern long double __significandl (long double __x) throw (); | |
218 | extern long double copysignl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __copysignl (long double __x, long double __y) throw () __attribute__ ((__const__)); | |
219 | extern long double nanl (const char *__tagb) throw () __attribute__ ((__const__)); extern long double __nanl (const char *__tagb) throw () __attribute__ ((__const__)); | |
220 | extern int __isnanl (long double __value) throw () __attribute__ ((__const__)); | |
221 | extern int isnanl (long double __value) throw () __attribute__ ((__const__)); | |
222 | extern long double j0l (long double) throw (); extern long double __j0l (long double) throw (); | |
223 | extern long double j1l (long double) throw (); extern long double __j1l (long double) throw (); | |
224 | extern long double jnl (int, long double) throw (); extern long double __jnl (int, long double) throw (); | |
225 | extern long double y0l (long double) throw (); extern long double __y0l (long double) throw (); | |
226 | extern long double y1l (long double) throw (); extern long double __y1l (long double) throw (); | |
227 | extern long double ynl (int, long double) throw (); extern long double __ynl (int, long double) throw (); | |
228 | extern long double erfl (long double) throw (); extern long double __erfl (long double) throw (); | |
229 | extern long double erfcl (long double) throw (); extern long double __erfcl (long double) throw (); | |
230 | extern long double lgammal (long double) throw (); extern long double __lgammal (long double) throw (); | |
231 | extern long double tgammal (long double) throw (); extern long double __tgammal (long double) throw (); | |
232 | extern long double gammal (long double) throw (); extern long double __gammal (long double) throw (); | |
233 | extern long double lgammal_r (long double, int *__signgamp) throw (); extern long double __lgammal_r (long double, int *__signgamp) throw (); | |
234 | extern long double rintl (long double __x) throw (); extern long double __rintl (long double __x) throw (); | |
235 | extern long double nextafterl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __nextafterl (long double __x, long double __y) throw () __attribute__ ((__const__)); | |
236 | extern long double nexttowardl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __nexttowardl (long double __x, long double __y) throw () __attribute__ ((__const__)); | |
237 | extern long double remainderl (long double __x, long double __y) throw (); extern long double __remainderl (long double __x, long double __y) throw (); | |
238 | extern long double scalbnl (long double __x, int __n) throw (); extern long double __scalbnl (long double __x, int __n) throw (); | |
239 | extern int ilogbl (long double __x) throw (); extern int __ilogbl (long double __x) throw (); | |
240 | extern long double scalblnl (long double __x, long int __n) throw (); extern long double __scalblnl (long double __x, long int __n) throw (); | |
241 | extern long double nearbyintl (long double __x) throw (); extern long double __nearbyintl (long double __x) throw (); | |
242 | extern long double roundl (long double __x) throw () __attribute__ ((__const__)); extern long double __roundl (long double __x) throw () __attribute__ ((__const__)); | |
243 | extern long double truncl (long double __x) throw () __attribute__ ((__const__)); extern long double __truncl (long double __x) throw () __attribute__ ((__const__)); | |
244 | extern long double remquol (long double __x, long double __y, int *__quo) throw (); extern long double __remquol (long double __x, long double __y, int *__quo) throw (); | |
245 | extern long int lrintl (long double __x) throw (); extern long int __lrintl (long double __x) throw (); | |
246 | __extension__ | |
247 | extern long long int llrintl (long double __x) throw (); extern long long int __llrintl (long double __x) throw (); | |
248 | extern long int lroundl (long double __x) throw (); extern long int __lroundl (long double __x) throw (); | |
249 | __extension__ | |
250 | extern long long int llroundl (long double __x) throw (); extern long long int __llroundl (long double __x) throw (); | |
251 | extern long double fdiml (long double __x, long double __y) throw (); extern long double __fdiml (long double __x, long double __y) throw (); | |
252 | extern long double fmaxl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __fmaxl (long double __x, long double __y) throw () __attribute__ ((__const__)); | |
253 | extern long double fminl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __fminl (long double __x, long double __y) throw () __attribute__ ((__const__)); | |
254 | extern int __fpclassifyl (long double __value) throw () | |
255 | __attribute__ ((__const__)); | |
256 | extern int __signbitl (long double __value) throw () | |
257 | __attribute__ ((__const__)); | |
258 | extern long double fmal (long double __x, long double __y, long double __z) throw (); extern long double __fmal (long double __x, long double __y, long double __z) throw (); | |
259 | extern int __issignalingl (long double __value) throw () | |
260 | __attribute__ ((__const__)); | |
261 | extern long double scalbl (long double __x, long double __n) throw (); extern long double __scalbl (long double __x, long double __n) throw (); | |
262 | extern int signgam; | |
263 | enum | |
264 | { | |
265 | FP_NAN = | |
266 | 0, | |
267 | FP_INFINITE = | |
268 | 1, | |
269 | FP_ZERO = | |
270 | 2, | |
271 | FP_SUBNORMAL = | |
272 | 3, | |
273 | FP_NORMAL = | |
274 | 4 | |
275 | }; | |
276 | typedef enum | |
277 | { | |
278 | _IEEE_ = -1, | |
279 | _SVID_, | |
280 | _XOPEN_, | |
281 | _POSIX_, | |
282 | _ISOC_ | |
283 | } _LIB_VERSION_TYPE; | |
284 | extern _LIB_VERSION_TYPE _LIB_VERSION; | |
285 | struct __exception | |
286 | { | |
287 | int type; | |
288 | char *name; | |
289 | double arg1; | |
290 | double arg2; | |
291 | double retval; | |
292 | }; | |
293 | extern int matherr (struct __exception *__exc) throw (); | |
294 | extern __inline __attribute__ ((__gnu_inline__)) int | |
295 | __attribute__ ((__leaf__)) __signbitf (float __x) throw () | |
296 | { | |
297 | return __builtin_signbitf (__x); | |
298 | } | |
299 | extern __inline __attribute__ ((__gnu_inline__)) int | |
300 | __attribute__ ((__leaf__)) __signbit (double __x) throw () | |
301 | { | |
302 | return __builtin_signbit (__x); | |
303 | } | |
304 | extern __inline __attribute__ ((__gnu_inline__)) int | |
305 | __attribute__ ((__leaf__)) __signbitl (long double __x) throw () | |
306 | { | |
307 | return __signbit ((double) __x); | |
308 | } | |
309 | extern __inline __attribute__ ((__gnu_inline__)) double fdim (double __x, double __y) throw (); | |
310 | extern __inline __attribute__ ((__gnu_inline__)) double | |
311 | __attribute__ ((__leaf__)) fdim (double __x, double __y) throw () | |
312 | { | |
313 | return __x <= __y ? 0 : __x - __y; | |
314 | } | |
315 | extern __inline __attribute__ ((__gnu_inline__)) float fdimf (float __x, float __y) throw (); | |
316 | extern __inline __attribute__ ((__gnu_inline__)) float | |
317 | __attribute__ ((__leaf__)) fdimf (float __x, float __y) throw () | |
318 | { | |
319 | return __x <= __y ? 0 : __x - __y; | |
320 | } | |
321 | } | |
322 | typedef long unsigned int size_t; | |
323 | extern "C" { | |
324 | typedef unsigned char __u_char; | |
325 | typedef unsigned short int __u_short; | |
326 | typedef unsigned int __u_int; | |
327 | typedef unsigned long int __u_long; | |
328 | typedef signed char __int8_t; | |
329 | typedef unsigned char __uint8_t; | |
330 | typedef signed short int __int16_t; | |
331 | typedef unsigned short int __uint16_t; | |
332 | typedef signed int __int32_t; | |
333 | typedef unsigned int __uint32_t; | |
334 | typedef signed long int __int64_t; | |
335 | typedef unsigned long int __uint64_t; | |
336 | typedef long int __quad_t; | |
337 | typedef unsigned long int __u_quad_t; | |
338 | typedef unsigned long int __dev_t; | |
339 | typedef unsigned int __uid_t; | |
340 | typedef unsigned int __gid_t; | |
341 | typedef unsigned long int __ino_t; | |
342 | typedef unsigned long int __ino64_t; | |
343 | typedef unsigned int __mode_t; | |
344 | typedef unsigned long int __nlink_t; | |
345 | typedef long int __off_t; | |
346 | typedef long int __off64_t; | |
347 | typedef int __pid_t; | |
348 | typedef struct { int __val[2]; } __fsid_t; | |
349 | typedef long int __clock_t; | |
350 | typedef unsigned long int __rlim_t; | |
351 | typedef unsigned long int __rlim64_t; | |
352 | typedef unsigned int __id_t; | |
353 | typedef long int __time_t; | |
354 | typedef unsigned int __useconds_t; | |
355 | typedef long int __suseconds_t; | |
356 | typedef int __daddr_t; | |
357 | typedef int __key_t; | |
358 | typedef int __clockid_t; | |
359 | typedef void * __timer_t; | |
360 | typedef long int __blksize_t; | |
361 | typedef long int __blkcnt_t; | |
362 | typedef long int __blkcnt64_t; | |
363 | typedef unsigned long int __fsblkcnt_t; | |
364 | typedef unsigned long int __fsblkcnt64_t; | |
365 | typedef unsigned long int __fsfilcnt_t; | |
366 | typedef unsigned long int __fsfilcnt64_t; | |
367 | typedef long int __fsword_t; | |
368 | typedef long int __ssize_t; | |
369 | typedef long int __syscall_slong_t; | |
370 | typedef unsigned long int __syscall_ulong_t; | |
371 | typedef __off64_t __loff_t; | |
372 | typedef __quad_t *__qaddr_t; | |
373 | typedef char *__caddr_t; | |
374 | typedef long int __intptr_t; | |
375 | typedef unsigned int __socklen_t; | |
376 | static __inline unsigned int | |
377 | __bswap_32 (unsigned int __bsx) | |
378 | { | |
379 | return __builtin_bswap32 (__bsx); | |
380 | } | |
381 | static __inline __uint64_t | |
382 | __bswap_64 (__uint64_t __bsx) | |
383 | { | |
384 | return __builtin_bswap64 (__bsx); | |
385 | } | |
386 | union wait | |
387 | { | |
388 | int w_status; | |
389 | struct | |
390 | { | |
391 | unsigned int:16; | |
392 | unsigned int __w_retcode:8; | |
393 | unsigned int __w_coredump:1; | |
394 | unsigned int __w_termsig:7; | |
395 | } __wait_terminated; | |
396 | struct | |
397 | { | |
398 | unsigned int:16; | |
399 | unsigned int __w_stopsig:8; | |
400 | unsigned int __w_stopval:8; | |
401 | } __wait_stopped; | |
402 | }; | |
403 | typedef struct | |
404 | { | |
405 | int quot; | |
406 | int rem; | |
407 | } div_t; | |
408 | typedef struct | |
409 | { | |
410 | long int quot; | |
411 | long int rem; | |
412 | } ldiv_t; | |
413 | __extension__ typedef struct | |
414 | { | |
415 | long long int quot; | |
416 | long long int rem; | |
417 | } lldiv_t; | |
418 | extern size_t __ctype_get_mb_cur_max (void) throw () __attribute__ ((__warn_unused_result__)); | |
419 | extern double atof (const char *__nptr) | |
420 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
421 | extern int atoi (const char *__nptr) | |
422 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
423 | extern long int atol (const char *__nptr) | |
424 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
425 | __extension__ extern long long int atoll (const char *__nptr) | |
426 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
427 | extern double strtod (const char *__restrict __nptr, | |
428 | char **__restrict __endptr) | |
429 | throw () __attribute__ ((__nonnull__ (1))); | |
430 | extern float strtof (const char *__restrict __nptr, | |
431 | char **__restrict __endptr) throw () __attribute__ ((__nonnull__ (1))); | |
432 | extern long double strtold (const char *__restrict __nptr, | |
433 | char **__restrict __endptr) | |
434 | throw () __attribute__ ((__nonnull__ (1))); | |
435 | extern long int strtol (const char *__restrict __nptr, | |
436 | char **__restrict __endptr, int __base) | |
437 | throw () __attribute__ ((__nonnull__ (1))); | |
438 | extern unsigned long int strtoul (const char *__restrict __nptr, | |
439 | char **__restrict __endptr, int __base) | |
440 | throw () __attribute__ ((__nonnull__ (1))); | |
441 | __extension__ | |
442 | extern long long int strtoq (const char *__restrict __nptr, | |
443 | char **__restrict __endptr, int __base) | |
444 | throw () __attribute__ ((__nonnull__ (1))); | |
445 | __extension__ | |
446 | extern unsigned long long int strtouq (const char *__restrict __nptr, | |
447 | char **__restrict __endptr, int __base) | |
448 | throw () __attribute__ ((__nonnull__ (1))); | |
449 | __extension__ | |
450 | extern long long int strtoll (const char *__restrict __nptr, | |
451 | char **__restrict __endptr, int __base) | |
452 | throw () __attribute__ ((__nonnull__ (1))); | |
453 | __extension__ | |
454 | extern unsigned long long int strtoull (const char *__restrict __nptr, | |
455 | char **__restrict __endptr, int __base) | |
456 | throw () __attribute__ ((__nonnull__ (1))); | |
457 | typedef struct __locale_struct | |
458 | { | |
459 | struct __locale_data *__locales[13]; | |
460 | const unsigned short int *__ctype_b; | |
461 | const int *__ctype_tolower; | |
462 | const int *__ctype_toupper; | |
463 | const char *__names[13]; | |
464 | } *__locale_t; | |
465 | typedef __locale_t locale_t; | |
466 | extern long int strtol_l (const char *__restrict __nptr, | |
467 | char **__restrict __endptr, int __base, | |
468 | __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))); | |
469 | extern unsigned long int strtoul_l (const char *__restrict __nptr, | |
470 | char **__restrict __endptr, | |
471 | int __base, __locale_t __loc) | |
472 | throw () __attribute__ ((__nonnull__ (1, 4))); | |
473 | __extension__ | |
474 | extern long long int strtoll_l (const char *__restrict __nptr, | |
475 | char **__restrict __endptr, int __base, | |
476 | __locale_t __loc) | |
477 | throw () __attribute__ ((__nonnull__ (1, 4))); | |
478 | __extension__ | |
479 | extern unsigned long long int strtoull_l (const char *__restrict __nptr, | |
480 | char **__restrict __endptr, | |
481 | int __base, __locale_t __loc) | |
482 | throw () __attribute__ ((__nonnull__ (1, 4))); | |
483 | extern double strtod_l (const char *__restrict __nptr, | |
484 | char **__restrict __endptr, __locale_t __loc) | |
485 | throw () __attribute__ ((__nonnull__ (1, 3))); | |
486 | extern float strtof_l (const char *__restrict __nptr, | |
487 | char **__restrict __endptr, __locale_t __loc) | |
488 | throw () __attribute__ ((__nonnull__ (1, 3))); | |
489 | extern long double strtold_l (const char *__restrict __nptr, | |
490 | char **__restrict __endptr, | |
491 | __locale_t __loc) | |
492 | throw () __attribute__ ((__nonnull__ (1, 3))); | |
493 | extern __inline __attribute__ ((__gnu_inline__)) int | |
494 | __attribute__ ((__leaf__)) atoi (const char *__nptr) throw () | |
495 | { | |
496 | return (int) strtol (__nptr, (char **) __null, 10); | |
497 | } | |
498 | extern __inline __attribute__ ((__gnu_inline__)) long int | |
499 | __attribute__ ((__leaf__)) atol (const char *__nptr) throw () | |
500 | { | |
501 | return strtol (__nptr, (char **) __null, 10); | |
502 | } | |
503 | __extension__ extern __inline __attribute__ ((__gnu_inline__)) long long int | |
504 | __attribute__ ((__leaf__)) atoll (const char *__nptr) throw () | |
505 | { | |
506 | return strtoll (__nptr, (char **) __null, 10); | |
507 | } | |
508 | extern char *l64a (long int __n) throw () __attribute__ ((__warn_unused_result__)); | |
509 | extern long int a64l (const char *__s) | |
510 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
511 | extern "C" { | |
512 | typedef __u_char u_char; | |
513 | typedef __u_short u_short; | |
514 | typedef __u_int u_int; | |
515 | typedef __u_long u_long; | |
516 | typedef __quad_t quad_t; | |
517 | typedef __u_quad_t u_quad_t; | |
518 | typedef __fsid_t fsid_t; | |
519 | typedef __loff_t loff_t; | |
520 | typedef __ino_t ino_t; | |
521 | typedef __ino64_t ino64_t; | |
522 | typedef __dev_t dev_t; | |
523 | typedef __gid_t gid_t; | |
524 | typedef __mode_t mode_t; | |
525 | typedef __nlink_t nlink_t; | |
526 | typedef __uid_t uid_t; | |
527 | typedef __off_t off_t; | |
528 | typedef __off64_t off64_t; | |
529 | typedef __pid_t pid_t; | |
530 | typedef __id_t id_t; | |
531 | typedef __ssize_t ssize_t; | |
532 | typedef __daddr_t daddr_t; | |
533 | typedef __caddr_t caddr_t; | |
534 | typedef __key_t key_t; | |
535 | typedef __clock_t clock_t; | |
536 | typedef __time_t time_t; | |
537 | typedef __clockid_t clockid_t; | |
538 | typedef __timer_t timer_t; | |
539 | typedef __useconds_t useconds_t; | |
540 | typedef __suseconds_t suseconds_t; | |
541 | typedef unsigned long int ulong; | |
542 | typedef unsigned short int ushort; | |
543 | typedef unsigned int uint; | |
544 | typedef int int8_t __attribute__ ((__mode__ (__QI__))); | |
545 | typedef int int16_t __attribute__ ((__mode__ (__HI__))); | |
546 | typedef int int32_t __attribute__ ((__mode__ (__SI__))); | |
547 | typedef int int64_t __attribute__ ((__mode__ (__DI__))); | |
548 | typedef unsigned int u_int8_t __attribute__ ((__mode__ (__QI__))); | |
549 | typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__))); | |
550 | typedef unsigned int u_int32_t __attribute__ ((__mode__ (__SI__))); | |
551 | typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__))); | |
552 | typedef int register_t __attribute__ ((__mode__ (__word__))); | |
553 | typedef int __sig_atomic_t; | |
554 | typedef struct | |
555 | { | |
556 | unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; | |
557 | } __sigset_t; | |
558 | typedef __sigset_t sigset_t; | |
559 | struct timespec | |
560 | { | |
561 | __time_t tv_sec; | |
562 | __syscall_slong_t tv_nsec; | |
563 | }; | |
564 | struct timeval | |
565 | { | |
566 | __time_t tv_sec; | |
567 | __suseconds_t tv_usec; | |
568 | }; | |
569 | typedef long int __fd_mask; | |
570 | typedef struct | |
571 | { | |
572 | __fd_mask fds_bits[1024 / (8 * (int) sizeof (__fd_mask))]; | |
573 | } fd_set; | |
574 | typedef __fd_mask fd_mask; | |
575 | extern "C" { | |
576 | extern int select (int __nfds, fd_set *__restrict __readfds, | |
577 | fd_set *__restrict __writefds, | |
578 | fd_set *__restrict __exceptfds, | |
579 | struct timeval *__restrict __timeout); | |
580 | extern int pselect (int __nfds, fd_set *__restrict __readfds, | |
581 | fd_set *__restrict __writefds, | |
582 | fd_set *__restrict __exceptfds, | |
583 | const struct timespec *__restrict __timeout, | |
584 | const __sigset_t *__restrict __sigmask); | |
585 | extern long int __fdelt_chk (long int __d); | |
586 | extern long int __fdelt_warn (long int __d) | |
587 | __attribute__((__warning__ ("bit outside of fd_set selected"))); | |
588 | } | |
589 | extern "C" { | |
590 | __extension__ | |
591 | extern unsigned int gnu_dev_major (unsigned long long int __dev) | |
592 | throw () __attribute__ ((__const__)); | |
593 | __extension__ | |
594 | extern unsigned int gnu_dev_minor (unsigned long long int __dev) | |
595 | throw () __attribute__ ((__const__)); | |
596 | __extension__ | |
597 | extern unsigned long long int gnu_dev_makedev (unsigned int __major, | |
598 | unsigned int __minor) | |
599 | throw () __attribute__ ((__const__)); | |
600 | __extension__ extern __inline __attribute__ ((__gnu_inline__)) __attribute__ ((__const__)) unsigned int | |
601 | __attribute__ ((__leaf__)) gnu_dev_major (unsigned long long int __dev) throw () | |
602 | { | |
603 | return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff); | |
604 | } | |
605 | __extension__ extern __inline __attribute__ ((__gnu_inline__)) __attribute__ ((__const__)) unsigned int | |
606 | __attribute__ ((__leaf__)) gnu_dev_minor (unsigned long long int __dev) throw () | |
607 | { | |
608 | return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); | |
609 | } | |
610 | __extension__ extern __inline __attribute__ ((__gnu_inline__)) __attribute__ ((__const__)) unsigned long long int | |
611 | __attribute__ ((__leaf__)) gnu_dev_makedev (unsigned int __major, unsigned int __minor) throw () | |
612 | { | |
613 | return ((__minor & 0xff) | ((__major & 0xfff) << 8) | |
614 | | (((unsigned long long int) (__minor & ~0xff)) << 12) | |
615 | | (((unsigned long long int) (__major & ~0xfff)) << 32)); | |
616 | } | |
617 | } | |
618 | typedef __blksize_t blksize_t; | |
619 | typedef __blkcnt_t blkcnt_t; | |
620 | typedef __fsblkcnt_t fsblkcnt_t; | |
621 | typedef __fsfilcnt_t fsfilcnt_t; | |
622 | typedef __blkcnt64_t blkcnt64_t; | |
623 | typedef __fsblkcnt64_t fsblkcnt64_t; | |
624 | typedef __fsfilcnt64_t fsfilcnt64_t; | |
625 | typedef unsigned long int pthread_t; | |
626 | union pthread_attr_t | |
627 | { | |
628 | char __size[56]; | |
629 | long int __align; | |
630 | }; | |
631 | typedef union pthread_attr_t pthread_attr_t; | |
632 | typedef struct __pthread_internal_list | |
633 | { | |
634 | struct __pthread_internal_list *__prev; | |
635 | struct __pthread_internal_list *__next; | |
636 | } __pthread_list_t; | |
637 | typedef union | |
638 | { | |
639 | struct __pthread_mutex_s | |
640 | { | |
641 | int __lock; | |
642 | unsigned int __count; | |
643 | int __owner; | |
644 | unsigned int __nusers; | |
645 | int __kind; | |
646 | short __spins; | |
647 | short __elision; | |
648 | __pthread_list_t __list; | |
649 | } __data; | |
650 | char __size[40]; | |
651 | long int __align; | |
652 | } pthread_mutex_t; | |
653 | typedef union | |
654 | { | |
655 | char __size[4]; | |
656 | int __align; | |
657 | } pthread_mutexattr_t; | |
658 | typedef union | |
659 | { | |
660 | struct | |
661 | { | |
662 | int __lock; | |
663 | unsigned int __futex; | |
664 | __extension__ unsigned long long int __total_seq; | |
665 | __extension__ unsigned long long int __wakeup_seq; | |
666 | __extension__ unsigned long long int __woken_seq; | |
667 | void *__mutex; | |
668 | unsigned int __nwaiters; | |
669 | unsigned int __broadcast_seq; | |
670 | } __data; | |
671 | char __size[48]; | |
672 | __extension__ long long int __align; | |
673 | } pthread_cond_t; | |
674 | typedef union | |
675 | { | |
676 | char __size[4]; | |
677 | int __align; | |
678 | } pthread_condattr_t; | |
679 | typedef unsigned int pthread_key_t; | |
680 | typedef int pthread_once_t; | |
681 | typedef union | |
682 | { | |
683 | struct | |
684 | { | |
685 | int __lock; | |
686 | unsigned int __nr_readers; | |
687 | unsigned int __readers_wakeup; | |
688 | unsigned int __writer_wakeup; | |
689 | unsigned int __nr_readers_queued; | |
690 | unsigned int __nr_writers_queued; | |
691 | int __writer; | |
692 | int __shared; | |
693 | unsigned char __rwelision; | |
694 | unsigned char __pad1[7]; | |
695 | unsigned long int __pad2; | |
696 | unsigned int __flags; | |
697 | } __data; | |
698 | char __size[56]; | |
699 | long int __align; | |
700 | } pthread_rwlock_t; | |
701 | typedef union | |
702 | { | |
703 | char __size[8]; | |
704 | long int __align; | |
705 | } pthread_rwlockattr_t; | |
706 | typedef volatile int pthread_spinlock_t; | |
707 | typedef union | |
708 | { | |
709 | char __size[32]; | |
710 | long int __align; | |
711 | } pthread_barrier_t; | |
712 | typedef union | |
713 | { | |
714 | char __size[4]; | |
715 | int __align; | |
716 | } pthread_barrierattr_t; | |
717 | } | |
718 | extern long int random (void) throw (); | |
719 | extern void srandom (unsigned int __seed) throw (); | |
720 | extern char *initstate (unsigned int __seed, char *__statebuf, | |
721 | size_t __statelen) throw () __attribute__ ((__nonnull__ (2))); | |
722 | extern char *setstate (char *__statebuf) throw () __attribute__ ((__nonnull__ (1))); | |
723 | struct random_data | |
724 | { | |
725 | int32_t *fptr; | |
726 | int32_t *rptr; | |
727 | int32_t *state; | |
728 | int rand_type; | |
729 | int rand_deg; | |
730 | int rand_sep; | |
731 | int32_t *end_ptr; | |
732 | }; | |
733 | extern int random_r (struct random_data *__restrict __buf, | |
734 | int32_t *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); | |
735 | extern int srandom_r (unsigned int __seed, struct random_data *__buf) | |
736 | throw () __attribute__ ((__nonnull__ (2))); | |
737 | extern int initstate_r (unsigned int __seed, char *__restrict __statebuf, | |
738 | size_t __statelen, | |
739 | struct random_data *__restrict __buf) | |
740 | throw () __attribute__ ((__nonnull__ (2, 4))); | |
741 | extern int setstate_r (char *__restrict __statebuf, | |
742 | struct random_data *__restrict __buf) | |
743 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
744 | extern int rand (void) throw (); | |
745 | extern void srand (unsigned int __seed) throw (); | |
746 | extern int rand_r (unsigned int *__seed) throw (); | |
747 | extern double drand48 (void) throw (); | |
748 | extern double erand48 (unsigned short int __xsubi[3]) throw () __attribute__ ((__nonnull__ (1))); | |
749 | extern long int lrand48 (void) throw (); | |
750 | extern long int nrand48 (unsigned short int __xsubi[3]) | |
751 | throw () __attribute__ ((__nonnull__ (1))); | |
752 | extern long int mrand48 (void) throw (); | |
753 | extern long int jrand48 (unsigned short int __xsubi[3]) | |
754 | throw () __attribute__ ((__nonnull__ (1))); | |
755 | extern void srand48 (long int __seedval) throw (); | |
756 | extern unsigned short int *seed48 (unsigned short int __seed16v[3]) | |
757 | throw () __attribute__ ((__nonnull__ (1))); | |
758 | extern void lcong48 (unsigned short int __param[7]) throw () __attribute__ ((__nonnull__ (1))); | |
759 | struct drand48_data | |
760 | { | |
761 | unsigned short int __x[3]; | |
762 | unsigned short int __old_x[3]; | |
763 | unsigned short int __c; | |
764 | unsigned short int __init; | |
765 | __extension__ unsigned long long int __a; | |
766 | }; | |
767 | extern int drand48_r (struct drand48_data *__restrict __buffer, | |
768 | double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); | |
769 | extern int erand48_r (unsigned short int __xsubi[3], | |
770 | struct drand48_data *__restrict __buffer, | |
771 | double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); | |
772 | extern int lrand48_r (struct drand48_data *__restrict __buffer, | |
773 | long int *__restrict __result) | |
774 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
775 | extern int nrand48_r (unsigned short int __xsubi[3], | |
776 | struct drand48_data *__restrict __buffer, | |
777 | long int *__restrict __result) | |
778 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
779 | extern int mrand48_r (struct drand48_data *__restrict __buffer, | |
780 | long int *__restrict __result) | |
781 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
782 | extern int jrand48_r (unsigned short int __xsubi[3], | |
783 | struct drand48_data *__restrict __buffer, | |
784 | long int *__restrict __result) | |
785 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
786 | extern int srand48_r (long int __seedval, struct drand48_data *__buffer) | |
787 | throw () __attribute__ ((__nonnull__ (2))); | |
788 | extern int seed48_r (unsigned short int __seed16v[3], | |
789 | struct drand48_data *__buffer) throw () __attribute__ ((__nonnull__ (1, 2))); | |
790 | extern int lcong48_r (unsigned short int __param[7], | |
791 | struct drand48_data *__buffer) | |
792 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
793 | extern void *malloc (size_t __size) throw () __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__)); | |
794 | extern void *calloc (size_t __nmemb, size_t __size) | |
795 | throw () __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__)); | |
796 | extern void *realloc (void *__ptr, size_t __size) | |
797 | throw () __attribute__ ((__warn_unused_result__)); | |
798 | extern void free (void *__ptr) throw (); | |
799 | extern void cfree (void *__ptr) throw (); | |
800 | extern "C" { | |
801 | extern void *alloca (size_t __size) throw (); | |
802 | } | |
803 | extern void *valloc (size_t __size) throw () __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__)); | |
804 | extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) | |
805 | throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
806 | extern void *aligned_alloc (size_t __alignment, size_t __size) | |
807 | throw () __attribute__ ((__malloc__)) __attribute__ ((__alloc_size__ (2))) __attribute__ ((__warn_unused_result__)); | |
808 | extern void abort (void) throw () __attribute__ ((__noreturn__)); | |
809 | extern int atexit (void (*__func) (void)) throw () __attribute__ ((__nonnull__ (1))); | |
810 | extern "C++" int at_quick_exit (void (*__func) (void)) | |
811 | throw () __asm ("at_quick_exit") __attribute__ ((__nonnull__ (1))); | |
812 | extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg) | |
813 | throw () __attribute__ ((__nonnull__ (1))); | |
814 | extern void exit (int __status) throw () __attribute__ ((__noreturn__)); | |
815 | extern void quick_exit (int __status) throw () __attribute__ ((__noreturn__)); | |
816 | extern void _Exit (int __status) throw () __attribute__ ((__noreturn__)); | |
817 | extern char *getenv (const char *__name) throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
818 | extern char *secure_getenv (const char *__name) | |
819 | throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
820 | extern int putenv (char *__string) throw () __attribute__ ((__nonnull__ (1))); | |
821 | extern int setenv (const char *__name, const char *__value, int __replace) | |
822 | throw () __attribute__ ((__nonnull__ (2))); | |
823 | extern int unsetenv (const char *__name) throw () __attribute__ ((__nonnull__ (1))); | |
824 | extern int clearenv (void) throw (); | |
825 | extern char *mktemp (char *__template) throw () __attribute__ ((__nonnull__ (1))); | |
826 | extern int mkstemp (char *__template) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
827 | extern int mkstemp64 (char *__template) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
828 | extern int mkstemps (char *__template, int __suffixlen) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
829 | extern int mkstemps64 (char *__template, int __suffixlen) | |
830 | __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
831 | extern char *mkdtemp (char *__template) throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
832 | extern int mkostemp (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
833 | extern int mkostemp64 (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
834 | extern int mkostemps (char *__template, int __suffixlen, int __flags) | |
835 | __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
836 | extern int mkostemps64 (char *__template, int __suffixlen, int __flags) | |
837 | __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
838 | extern int system (const char *__command) __attribute__ ((__warn_unused_result__)); | |
839 | extern char *canonicalize_file_name (const char *__name) | |
840 | throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
841 | extern char *realpath (const char *__restrict __name, | |
842 | char *__restrict __resolved) throw () __attribute__ ((__warn_unused_result__)); | |
843 | typedef int (*__compar_fn_t) (const void *, const void *); | |
844 | typedef __compar_fn_t comparison_fn_t; | |
845 | typedef int (*__compar_d_fn_t) (const void *, const void *, void *); | |
846 | extern void *bsearch (const void *__key, const void *__base, | |
847 | size_t __nmemb, size_t __size, __compar_fn_t __compar) | |
848 | __attribute__ ((__nonnull__ (1, 2, 5))) __attribute__ ((__warn_unused_result__)); | |
849 | extern __inline __attribute__ ((__gnu_inline__)) void * | |
850 | bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, | |
851 | __compar_fn_t __compar) | |
852 | { | |
853 | size_t __l, __u, __idx; | |
854 | const void *__p; | |
855 | int __comparison; | |
856 | __l = 0; | |
857 | __u = __nmemb; | |
858 | while (__l < __u) | |
859 | { | |
860 | __idx = (__l + __u) / 2; | |
861 | __p = (void *) (((const char *) __base) + (__idx * __size)); | |
862 | __comparison = (*__compar) (__key, __p); | |
863 | if (__comparison < 0) | |
864 | __u = __idx; | |
865 | else if (__comparison > 0) | |
866 | __l = __idx + 1; | |
867 | else | |
868 | return (void *) __p; | |
869 | } | |
870 | return __null; | |
871 | } | |
872 | extern void qsort (void *__base, size_t __nmemb, size_t __size, | |
873 | __compar_fn_t __compar) __attribute__ ((__nonnull__ (1, 4))); | |
874 | extern void qsort_r (void *__base, size_t __nmemb, size_t __size, | |
875 | __compar_d_fn_t __compar, void *__arg) | |
876 | __attribute__ ((__nonnull__ (1, 4))); | |
877 | extern int abs (int __x) throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
878 | extern long int labs (long int __x) throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
879 | __extension__ extern long long int llabs (long long int __x) | |
880 | throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
881 | extern div_t div (int __numer, int __denom) | |
882 | throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
883 | extern ldiv_t ldiv (long int __numer, long int __denom) | |
884 | throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
885 | __extension__ extern lldiv_t lldiv (long long int __numer, | |
886 | long long int __denom) | |
887 | throw () __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__)); | |
888 | extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt, | |
889 | int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__)); | |
890 | extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt, | |
891 | int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__)); | |
892 | extern char *gcvt (double __value, int __ndigit, char *__buf) | |
893 | throw () __attribute__ ((__nonnull__ (3))) __attribute__ ((__warn_unused_result__)); | |
894 | extern char *qecvt (long double __value, int __ndigit, | |
895 | int *__restrict __decpt, int *__restrict __sign) | |
896 | throw () __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__)); | |
897 | extern char *qfcvt (long double __value, int __ndigit, | |
898 | int *__restrict __decpt, int *__restrict __sign) | |
899 | throw () __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__)); | |
900 | extern char *qgcvt (long double __value, int __ndigit, char *__buf) | |
901 | throw () __attribute__ ((__nonnull__ (3))) __attribute__ ((__warn_unused_result__)); | |
902 | extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt, | |
903 | int *__restrict __sign, char *__restrict __buf, | |
904 | size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); | |
905 | extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt, | |
906 | int *__restrict __sign, char *__restrict __buf, | |
907 | size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); | |
908 | extern int qecvt_r (long double __value, int __ndigit, | |
909 | int *__restrict __decpt, int *__restrict __sign, | |
910 | char *__restrict __buf, size_t __len) | |
911 | throw () __attribute__ ((__nonnull__ (3, 4, 5))); | |
912 | extern int qfcvt_r (long double __value, int __ndigit, | |
913 | int *__restrict __decpt, int *__restrict __sign, | |
914 | char *__restrict __buf, size_t __len) | |
915 | throw () __attribute__ ((__nonnull__ (3, 4, 5))); | |
916 | extern int mblen (const char *__s, size_t __n) throw (); | |
917 | extern int mbtowc (wchar_t *__restrict __pwc, | |
918 | const char *__restrict __s, size_t __n) throw (); | |
919 | extern int wctomb (char *__s, wchar_t __wchar) throw (); | |
920 | extern size_t mbstowcs (wchar_t *__restrict __pwcs, | |
921 | const char *__restrict __s, size_t __n) throw (); | |
922 | extern size_t wcstombs (char *__restrict __s, | |
923 | const wchar_t *__restrict __pwcs, size_t __n) | |
924 | throw (); | |
925 | extern int rpmatch (const char *__response) throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)); | |
926 | extern int getsubopt (char **__restrict __optionp, | |
927 | char *const *__restrict __tokens, | |
928 | char **__restrict __valuep) | |
929 | throw () __attribute__ ((__nonnull__ (1, 2, 3))) __attribute__ ((__warn_unused_result__)); | |
930 | extern void setkey (const char *__key) throw () __attribute__ ((__nonnull__ (1))); | |
931 | extern int posix_openpt (int __oflag) __attribute__ ((__warn_unused_result__)); | |
932 | extern int grantpt (int __fd) throw (); | |
933 | extern int unlockpt (int __fd) throw (); | |
934 | extern char *ptsname (int __fd) throw () __attribute__ ((__warn_unused_result__)); | |
935 | extern int ptsname_r (int __fd, char *__buf, size_t __buflen) | |
936 | throw () __attribute__ ((__nonnull__ (2))); | |
937 | extern int getpt (void); | |
938 | extern int getloadavg (double __loadavg[], int __nelem) | |
939 | throw () __attribute__ ((__nonnull__ (1))); | |
940 | extern __inline __attribute__ ((__gnu_inline__)) double | |
941 | __attribute__ ((__leaf__)) atof (const char *__nptr) throw () | |
942 | { | |
943 | return strtod (__nptr, (char **) __null); | |
944 | } | |
945 | extern char *__realpath_chk (const char *__restrict __name, | |
946 | char *__restrict __resolved, | |
947 | size_t __resolvedlen) throw () __attribute__ ((__warn_unused_result__)); | |
948 | extern char *__realpath_alias (const char *__restrict __name, char *__restrict __resolved) throw () __asm__ ("" "realpath") | |
949 | __attribute__ ((__warn_unused_result__)); | |
950 | extern char *__realpath_chk_warn (const char *__restrict __name, char *__restrict __resolved, size_t __resolvedlen) throw () __asm__ ("" "__realpath_chk") | |
951 | __attribute__ ((__warn_unused_result__)) | |
952 | __attribute__((__warning__ ("second argument of realpath must be either NULL or at " "least PATH_MAX bytes long buffer"))) | |
953 | ; | |
954 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char * | |
955 | __attribute__ ((__leaf__)) realpath (const char *__restrict __name, char *__restrict __resolved) throw () | |
956 | { | |
957 | if (__builtin_object_size (__resolved, 2 > 1) != (size_t) -1) | |
958 | { | |
959 | return __realpath_chk (__name, __resolved, __builtin_object_size (__resolved, 2 > 1)); | |
960 | } | |
961 | return __realpath_alias (__name, __resolved); | |
962 | } | |
963 | extern int __ptsname_r_chk (int __fd, char *__buf, size_t __buflen, | |
964 | size_t __nreal) throw () __attribute__ ((__nonnull__ (2))); | |
965 | extern int __ptsname_r_alias (int __fd, char *__buf, size_t __buflen) throw () __asm__ ("" "ptsname_r") | |
966 | __attribute__ ((__nonnull__ (2))); | |
967 | extern int __ptsname_r_chk_warn (int __fd, char *__buf, size_t __buflen, size_t __nreal) throw () __asm__ ("" "__ptsname_r_chk") | |
968 | __attribute__ ((__nonnull__ (2))) __attribute__((__warning__ ("ptsname_r called with buflen bigger than " "size of buf"))) | |
969 | ; | |
970 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
971 | __attribute__ ((__leaf__)) ptsname_r (int __fd, char *__buf, size_t __buflen) throw () | |
972 | { | |
973 | if (__builtin_object_size (__buf, 2 > 1) != (size_t) -1) | |
974 | { | |
975 | if (!__builtin_constant_p (__buflen)) | |
976 | return __ptsname_r_chk (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1)); | |
977 | if (__buflen > __builtin_object_size (__buf, 2 > 1)) | |
978 | return __ptsname_r_chk_warn (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1)); | |
979 | } | |
980 | return __ptsname_r_alias (__fd, __buf, __buflen); | |
981 | } | |
982 | extern int __wctomb_chk (char *__s, wchar_t __wchar, size_t __buflen) | |
983 | throw () __attribute__ ((__warn_unused_result__)); | |
984 | extern int __wctomb_alias (char *__s, wchar_t __wchar) throw () __asm__ ("" "wctomb") | |
985 | __attribute__ ((__warn_unused_result__)); | |
986 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) int | |
987 | __attribute__ ((__leaf__)) wctomb (char *__s, wchar_t __wchar) throw () | |
988 | { | |
989 | if (__builtin_object_size (__s, 2 > 1) != (size_t) -1 && 16 > __builtin_object_size (__s, 2 > 1)) | |
990 | return __wctomb_chk (__s, __wchar, __builtin_object_size (__s, 2 > 1)); | |
991 | return __wctomb_alias (__s, __wchar); | |
992 | } | |
993 | extern size_t __mbstowcs_chk (wchar_t *__restrict __dst, | |
994 | const char *__restrict __src, | |
995 | size_t __len, size_t __dstlen) throw (); | |
996 | extern size_t __mbstowcs_alias (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len) throw () __asm__ ("" "mbstowcs") | |
997 | ; | |
998 | extern size_t __mbstowcs_chk_warn (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len, size_t __dstlen) throw () __asm__ ("" "__mbstowcs_chk") | |
999 | __attribute__((__warning__ ("mbstowcs called with dst buffer smaller than len " "* sizeof (wchar_t)"))) | |
1000 | ; | |
1001 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) size_t | |
1002 | __attribute__ ((__leaf__)) mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len) throw () | |
1003 | { | |
1004 | if (__builtin_object_size (__dst, 2 > 1) != (size_t) -1) | |
1005 | { | |
1006 | if (!__builtin_constant_p (__len)) | |
1007 | return __mbstowcs_chk (__dst, __src, __len, | |
1008 | __builtin_object_size (__dst, 2 > 1) / sizeof (wchar_t)); | |
1009 | if (__len > __builtin_object_size (__dst, 2 > 1) / sizeof (wchar_t)) | |
1010 | return __mbstowcs_chk_warn (__dst, __src, __len, | |
1011 | __builtin_object_size (__dst, 2 > 1) / sizeof (wchar_t)); | |
1012 | } | |
1013 | return __mbstowcs_alias (__dst, __src, __len); | |
1014 | } | |
1015 | extern size_t __wcstombs_chk (char *__restrict __dst, | |
1016 | const wchar_t *__restrict __src, | |
1017 | size_t __len, size_t __dstlen) throw (); | |
1018 | extern size_t __wcstombs_alias (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len) throw () __asm__ ("" "wcstombs") | |
1019 | ; | |
1020 | extern size_t __wcstombs_chk_warn (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len, size_t __dstlen) throw () __asm__ ("" "__wcstombs_chk") | |
1021 | __attribute__((__warning__ ("wcstombs called with dst buffer smaller than len"))); | |
1022 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) size_t | |
1023 | __attribute__ ((__leaf__)) wcstombs (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len) throw () | |
1024 | { | |
1025 | if (__builtin_object_size (__dst, 2 > 1) != (size_t) -1) | |
1026 | { | |
1027 | if (!__builtin_constant_p (__len)) | |
1028 | return __wcstombs_chk (__dst, __src, __len, __builtin_object_size (__dst, 2 > 1)); | |
1029 | if (__len > __builtin_object_size (__dst, 2 > 1)) | |
1030 | return __wcstombs_chk_warn (__dst, __src, __len, __builtin_object_size (__dst, 2 > 1)); | |
1031 | } | |
1032 | return __wcstombs_alias (__dst, __src, __len); | |
1033 | } | |
1034 | } | |
1035 | extern "C" { | |
1036 | extern void *memcpy (void *__restrict __dest, const void *__restrict __src, | |
1037 | size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); | |
1038 | extern void *memmove (void *__dest, const void *__src, size_t __n) | |
1039 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1040 | extern void *memccpy (void *__restrict __dest, const void *__restrict __src, | |
1041 | int __c, size_t __n) | |
1042 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1043 | extern void *memset (void *__s, int __c, size_t __n) throw () __attribute__ ((__nonnull__ (1))); | |
1044 | extern int memcmp (const void *__s1, const void *__s2, size_t __n) | |
1045 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1046 | extern "C++" | |
1047 | { | |
1048 | extern void *memchr (void *__s, int __c, size_t __n) | |
1049 | throw () __asm ("memchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1050 | extern const void *memchr (const void *__s, int __c, size_t __n) | |
1051 | throw () __asm ("memchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1052 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) void * | |
1053 | memchr (void *__s, int __c, size_t __n) throw () | |
1054 | { | |
1055 | return __builtin_memchr (__s, __c, __n); | |
1056 | } | |
1057 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const void * | |
1058 | memchr (const void *__s, int __c, size_t __n) throw () | |
1059 | { | |
1060 | return __builtin_memchr (__s, __c, __n); | |
1061 | } | |
1062 | } | |
1063 | extern "C++" void *rawmemchr (void *__s, int __c) | |
1064 | throw () __asm ("rawmemchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1065 | extern "C++" const void *rawmemchr (const void *__s, int __c) | |
1066 | throw () __asm ("rawmemchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1067 | extern "C++" void *memrchr (void *__s, int __c, size_t __n) | |
1068 | throw () __asm ("memrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1069 | extern "C++" const void *memrchr (const void *__s, int __c, size_t __n) | |
1070 | throw () __asm ("memrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1071 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | |
1072 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1073 | extern char *strncpy (char *__restrict __dest, | |
1074 | const char *__restrict __src, size_t __n) | |
1075 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1076 | extern char *strcat (char *__restrict __dest, const char *__restrict __src) | |
1077 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1078 | extern char *strncat (char *__restrict __dest, const char *__restrict __src, | |
1079 | size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); | |
1080 | extern int strcmp (const char *__s1, const char *__s2) | |
1081 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1082 | extern int strncmp (const char *__s1, const char *__s2, size_t __n) | |
1083 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1084 | extern int strcoll (const char *__s1, const char *__s2) | |
1085 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1086 | extern size_t strxfrm (char *__restrict __dest, | |
1087 | const char *__restrict __src, size_t __n) | |
1088 | throw () __attribute__ ((__nonnull__ (2))); | |
1089 | extern int strcoll_l (const char *__s1, const char *__s2, __locale_t __l) | |
1090 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); | |
1091 | extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n, | |
1092 | __locale_t __l) throw () __attribute__ ((__nonnull__ (2, 4))); | |
1093 | extern char *strdup (const char *__s) | |
1094 | throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); | |
1095 | extern char *strndup (const char *__string, size_t __n) | |
1096 | throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); | |
1097 | extern "C++" | |
1098 | { | |
1099 | extern char *strchr (char *__s, int __c) | |
1100 | throw () __asm ("strchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1101 | extern const char *strchr (const char *__s, int __c) | |
1102 | throw () __asm ("strchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1103 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1104 | strchr (char *__s, int __c) throw () | |
1105 | { | |
1106 | return __builtin_strchr (__s, __c); | |
1107 | } | |
1108 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1109 | strchr (const char *__s, int __c) throw () | |
1110 | { | |
1111 | return __builtin_strchr (__s, __c); | |
1112 | } | |
1113 | } | |
1114 | extern "C++" | |
1115 | { | |
1116 | extern char *strrchr (char *__s, int __c) | |
1117 | throw () __asm ("strrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1118 | extern const char *strrchr (const char *__s, int __c) | |
1119 | throw () __asm ("strrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1120 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1121 | strrchr (char *__s, int __c) throw () | |
1122 | { | |
1123 | return __builtin_strrchr (__s, __c); | |
1124 | } | |
1125 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1126 | strrchr (const char *__s, int __c) throw () | |
1127 | { | |
1128 | return __builtin_strrchr (__s, __c); | |
1129 | } | |
1130 | } | |
1131 | extern "C++" char *strchrnul (char *__s, int __c) | |
1132 | throw () __asm ("strchrnul") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1133 | extern "C++" const char *strchrnul (const char *__s, int __c) | |
1134 | throw () __asm ("strchrnul") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1135 | extern size_t strcspn (const char *__s, const char *__reject) | |
1136 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1137 | extern size_t strspn (const char *__s, const char *__accept) | |
1138 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1139 | extern "C++" | |
1140 | { | |
1141 | extern char *strpbrk (char *__s, const char *__accept) | |
1142 | throw () __asm ("strpbrk") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1143 | extern const char *strpbrk (const char *__s, const char *__accept) | |
1144 | throw () __asm ("strpbrk") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1145 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1146 | strpbrk (char *__s, const char *__accept) throw () | |
1147 | { | |
1148 | return __builtin_strpbrk (__s, __accept); | |
1149 | } | |
1150 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1151 | strpbrk (const char *__s, const char *__accept) throw () | |
1152 | { | |
1153 | return __builtin_strpbrk (__s, __accept); | |
1154 | } | |
1155 | } | |
1156 | extern "C++" | |
1157 | { | |
1158 | extern char *strstr (char *__haystack, const char *__needle) | |
1159 | throw () __asm ("strstr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1160 | extern const char *strstr (const char *__haystack, const char *__needle) | |
1161 | throw () __asm ("strstr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1162 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1163 | strstr (char *__haystack, const char *__needle) throw () | |
1164 | { | |
1165 | return __builtin_strstr (__haystack, __needle); | |
1166 | } | |
1167 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1168 | strstr (const char *__haystack, const char *__needle) throw () | |
1169 | { | |
1170 | return __builtin_strstr (__haystack, __needle); | |
1171 | } | |
1172 | } | |
1173 | extern char *strtok (char *__restrict __s, const char *__restrict __delim) | |
1174 | throw () __attribute__ ((__nonnull__ (2))); | |
1175 | extern char *__strtok_r (char *__restrict __s, | |
1176 | const char *__restrict __delim, | |
1177 | char **__restrict __save_ptr) | |
1178 | throw () __attribute__ ((__nonnull__ (2, 3))); | |
1179 | extern char *strtok_r (char *__restrict __s, const char *__restrict __delim, | |
1180 | char **__restrict __save_ptr) | |
1181 | throw () __attribute__ ((__nonnull__ (2, 3))); | |
1182 | extern "C++" char *strcasestr (char *__haystack, const char *__needle) | |
1183 | throw () __asm ("strcasestr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1184 | extern "C++" const char *strcasestr (const char *__haystack, | |
1185 | const char *__needle) | |
1186 | throw () __asm ("strcasestr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1187 | extern void *memmem (const void *__haystack, size_t __haystacklen, | |
1188 | const void *__needle, size_t __needlelen) | |
1189 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 3))); | |
1190 | extern void *__mempcpy (void *__restrict __dest, | |
1191 | const void *__restrict __src, size_t __n) | |
1192 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1193 | extern void *mempcpy (void *__restrict __dest, | |
1194 | const void *__restrict __src, size_t __n) | |
1195 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1196 | extern size_t strlen (const char *__s) | |
1197 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1198 | extern size_t strnlen (const char *__string, size_t __maxlen) | |
1199 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1200 | extern char *strerror (int __errnum) throw (); | |
1201 | extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) | |
1202 | throw () __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__)); | |
1203 | extern char *strerror_l (int __errnum, __locale_t __l) throw (); | |
1204 | extern void __bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); | |
1205 | extern void bcopy (const void *__src, void *__dest, size_t __n) | |
1206 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1207 | extern void bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); | |
1208 | extern int bcmp (const void *__s1, const void *__s2, size_t __n) | |
1209 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1210 | extern "C++" | |
1211 | { | |
1212 | extern char *index (char *__s, int __c) | |
1213 | throw () __asm ("index") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1214 | extern const char *index (const char *__s, int __c) | |
1215 | throw () __asm ("index") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1216 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1217 | index (char *__s, int __c) throw () | |
1218 | { | |
1219 | return __builtin_index (__s, __c); | |
1220 | } | |
1221 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1222 | index (const char *__s, int __c) throw () | |
1223 | { | |
1224 | return __builtin_index (__s, __c); | |
1225 | } | |
1226 | } | |
1227 | extern "C++" | |
1228 | { | |
1229 | extern char *rindex (char *__s, int __c) | |
1230 | throw () __asm ("rindex") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1231 | extern const char *rindex (const char *__s, int __c) | |
1232 | throw () __asm ("rindex") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); | |
1233 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * | |
1234 | rindex (char *__s, int __c) throw () | |
1235 | { | |
1236 | return __builtin_rindex (__s, __c); | |
1237 | } | |
1238 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) const char * | |
1239 | rindex (const char *__s, int __c) throw () | |
1240 | { | |
1241 | return __builtin_rindex (__s, __c); | |
1242 | } | |
1243 | } | |
1244 | extern int ffs (int __i) throw () __attribute__ ((__const__)); | |
1245 | extern int ffsl (long int __l) throw () __attribute__ ((__const__)); | |
1246 | __extension__ extern int ffsll (long long int __ll) | |
1247 | throw () __attribute__ ((__const__)); | |
1248 | extern int strcasecmp (const char *__s1, const char *__s2) | |
1249 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1250 | extern int strncasecmp (const char *__s1, const char *__s2, size_t __n) | |
1251 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1252 | extern int strcasecmp_l (const char *__s1, const char *__s2, | |
1253 | __locale_t __loc) | |
1254 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); | |
1255 | extern int strncasecmp_l (const char *__s1, const char *__s2, | |
1256 | size_t __n, __locale_t __loc) | |
1257 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 4))); | |
1258 | extern char *strsep (char **__restrict __stringp, | |
1259 | const char *__restrict __delim) | |
1260 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1261 | extern char *strsignal (int __sig) throw (); | |
1262 | extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src) | |
1263 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1264 | extern char *stpcpy (char *__restrict __dest, const char *__restrict __src) | |
1265 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1266 | extern char *__stpncpy (char *__restrict __dest, | |
1267 | const char *__restrict __src, size_t __n) | |
1268 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1269 | extern char *stpncpy (char *__restrict __dest, | |
1270 | const char *__restrict __src, size_t __n) | |
1271 | throw () __attribute__ ((__nonnull__ (1, 2))); | |
1272 | extern int strverscmp (const char *__s1, const char *__s2) | |
1273 | throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); | |
1274 | extern char *strfry (char *__string) throw () __attribute__ ((__nonnull__ (1))); | |
1275 | extern void *memfrob (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); | |
1276 | extern "C++" char *basename (char *__filename) | |
1277 | throw () __asm ("basename") __attribute__ ((__nonnull__ (1))); | |
1278 | extern "C++" const char *basename (const char *__filename) | |
1279 | throw () __asm ("basename") __attribute__ ((__nonnull__ (1))); | |
1280 | extern void __warn_memset_zero_len (void) __attribute__((__warning__ ("memset used with constant zero length parameter; this could be due to transposed parameters"))) | |
1281 | ; | |
1282 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void * | |
1283 | __attribute__ ((__leaf__)) memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len) throw () | |
1284 | { | |
1285 | return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); | |
1286 | } | |
1287 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void * | |
1288 | __attribute__ ((__leaf__)) memmove (void *__dest, const void *__src, size_t __len) throw () | |
1289 | { | |
1290 | return __builtin___memmove_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); | |
1291 | } | |
1292 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void * | |
1293 | __attribute__ ((__leaf__)) mempcpy (void *__restrict __dest, const void *__restrict __src, size_t __len) throw () | |
1294 | { | |
1295 | return __builtin___mempcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); | |
1296 | } | |
1297 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void * | |
1298 | __attribute__ ((__leaf__)) memset (void *__dest, int __ch, size_t __len) throw () | |
1299 | { | |
1300 | if (__builtin_constant_p (__len) && __len == 0 | |
1301 | && (!__builtin_constant_p (__ch) || __ch != 0)) | |
1302 | { | |
1303 | __warn_memset_zero_len (); | |
1304 | return __dest; | |
1305 | } | |
1306 | return __builtin___memset_chk (__dest, __ch, __len, __builtin_object_size (__dest, 0)); | |
1307 | } | |
1308 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void | |
1309 | __attribute__ ((__leaf__)) bcopy (const void *__src, void *__dest, size_t __len) throw () | |
1310 | { | |
1311 | (void) __builtin___memmove_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); | |
1312 | } | |
1313 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void | |
1314 | __attribute__ ((__leaf__)) bzero (void *__dest, size_t __len) throw () | |
1315 | { | |
1316 | (void) __builtin___memset_chk (__dest, '\0', __len, __builtin_object_size (__dest, 0)); | |
1317 | } | |
1318 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1319 | __attribute__ ((__leaf__)) strcpy (char *__restrict __dest, const char *__restrict __src) throw () | |
1320 | { | |
1321 | return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); | |
1322 | } | |
1323 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1324 | __attribute__ ((__leaf__)) stpcpy (char *__restrict __dest, const char *__restrict __src) throw () | |
1325 | { | |
1326 | return __builtin___stpcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); | |
1327 | } | |
1328 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1329 | __attribute__ ((__leaf__)) strncpy (char *__restrict __dest, const char *__restrict __src, size_t __len) throw () | |
1330 | { | |
1331 | return __builtin___strncpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 2 > 1)); | |
1332 | } | |
1333 | extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, | |
1334 | size_t __destlen) throw (); | |
1335 | extern char *__stpncpy_alias (char *__dest, const char *__src, size_t __n) throw () __asm__ ("" "stpncpy") | |
1336 | ; | |
1337 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1338 | __attribute__ ((__leaf__)) stpncpy (char *__dest, const char *__src, size_t __n) throw () | |
1339 | { | |
1340 | if (__builtin_object_size (__dest, 2 > 1) != (size_t) -1 | |
1341 | && (!__builtin_constant_p (__n) || __n <= __builtin_object_size (__dest, 2 > 1))) | |
1342 | return __stpncpy_chk (__dest, __src, __n, __builtin_object_size (__dest, 2 > 1)); | |
1343 | return __stpncpy_alias (__dest, __src, __n); | |
1344 | } | |
1345 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1346 | __attribute__ ((__leaf__)) strcat (char *__restrict __dest, const char *__restrict __src) throw () | |
1347 | { | |
1348 | return __builtin___strcat_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); | |
1349 | } | |
1350 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char * | |
1351 | __attribute__ ((__leaf__)) strncat (char *__restrict __dest, const char *__restrict __src, size_t __len) throw () | |
1352 | { | |
1353 | return __builtin___strncat_chk (__dest, __src, __len, __builtin_object_size (__dest, 2 > 1)); | |
1354 | } | |
1355 | } | |
1356 | typedef long int ptrdiff_t; | |
1357 | typedef unsigned char uint8_t; | |
1358 | typedef unsigned short int uint16_t; | |
1359 | typedef unsigned int uint32_t; | |
1360 | typedef unsigned long int uint64_t; | |
1361 | typedef signed char int_least8_t; | |
1362 | typedef short int int_least16_t; | |
1363 | typedef int int_least32_t; | |
1364 | typedef long int int_least64_t; | |
1365 | typedef unsigned char uint_least8_t; | |
1366 | typedef unsigned short int uint_least16_t; | |
1367 | typedef unsigned int uint_least32_t; | |
1368 | typedef unsigned long int uint_least64_t; | |
1369 | typedef signed char int_fast8_t; | |
1370 | typedef long int int_fast16_t; | |
1371 | typedef long int int_fast32_t; | |
1372 | typedef long int int_fast64_t; | |
1373 | typedef unsigned char uint_fast8_t; | |
1374 | typedef unsigned long int uint_fast16_t; | |
1375 | typedef unsigned long int uint_fast32_t; | |
1376 | typedef unsigned long int uint_fast64_t; | |
1377 | typedef long int intptr_t; | |
1378 | typedef unsigned long int uintptr_t; | |
1379 | typedef long int intmax_t; | |
1380 | typedef unsigned long int uintmax_t; | |
1381 | typedef int8_t JSInt8; | |
1382 | typedef int16_t JSInt16; | |
1383 | typedef int32_t JSInt32; | |
1384 | typedef int64_t JSInt64; | |
1385 | typedef intptr_t JSIntPtr; | |
1386 | typedef uint8_t JSUint8; | |
1387 | typedef uint16_t JSUint16; | |
1388 | typedef uint32_t JSUint32; | |
1389 | typedef uint64_t JSUint64; | |
1390 | typedef uintptr_t JSUintPtr; | |
1391 | extern "C" { | |
1392 | typedef int JSIntn; | |
1393 | typedef unsigned int JSUintn; | |
1394 | typedef double JSFloat64; | |
1395 | typedef size_t JSSize; | |
1396 | typedef ptrdiff_t JSPtrdiff; | |
1397 | typedef JSUintPtr JSUptrdiff; | |
1398 | typedef JSIntn JSBool; | |
1399 | typedef JSUint8 JSPackedBool; | |
1400 | typedef JSIntPtr JSWord; | |
1401 | typedef JSUintPtr JSUword; | |
1402 | typedef JSUintn uintn; | |
1403 | typedef JSUint64 uint64; | |
1404 | typedef JSUint32 uint32; | |
1405 | typedef JSUint16 uint16; | |
1406 | typedef JSUint8 uint8; | |
1407 | typedef JSIntn intn; | |
1408 | typedef JSInt64 int64; | |
1409 | typedef JSInt32 int32; | |
1410 | typedef JSInt16 int16; | |
1411 | typedef JSInt8 int8; | |
1412 | typedef JSFloat64 float64; | |
1413 | } | |
1414 | extern "C" { | |
1415 | } | |
1416 | typedef JSIntn intN; | |
1417 | typedef JSUintn uintN; | |
1418 | typedef JSUword jsuword; | |
1419 | typedef JSWord jsword; | |
1420 | typedef float float32; | |
1421 | extern "C" { | |
1422 | extern __attribute__((visibility ("default"))) void | |
1423 | JS_Assert(const char *s, const char *file, JSIntn ln); | |
1424 | extern __attribute__((visibility ("default"))) void JS_Abort(void); | |
1425 | static inline void* js_malloc(size_t bytes) { | |
1426 | return malloc(bytes); | |
1427 | } | |
1428 | static inline void* js_calloc(size_t bytes) { | |
1429 | return calloc(bytes, 1); | |
1430 | } | |
1431 | static inline void* js_realloc(void* p, size_t bytes) { | |
1432 | return realloc(p, bytes); | |
1433 | } | |
1434 | static inline void js_free(void* p) { | |
1435 | free(p); | |
1436 | } | |
1437 | } | |
1438 | template <class T> | |
1439 | __attribute__((always_inline)) inline T *js_new() { | |
1440 | void *memory = js_malloc(sizeof(T)); return memory ? new(memory) T () : __null; | |
1441 | } | |
1442 | template <class T, class P1> | |
1443 | __attribute__((always_inline)) inline T *js_new(const P1 &p1) { | |
1444 | void *memory = js_malloc(sizeof(T)); return memory ? new(memory) T (p1) : __null; | |
1445 | } | |
1446 | template <class T, class P1, class P2> | |
1447 | __attribute__((always_inline)) inline T *js_new(const P1 &p1, const P2 &p2) { | |
1448 | void *memory = js_malloc(sizeof(T)); return memory ? new(memory) T (p1, p2) : __null; | |
1449 | } | |
1450 | template <class T, class P1, class P2, class P3> | |
1451 | __attribute__((always_inline)) inline T *js_new(const P1 &p1, const P2 &p2, const P3 &p3) { | |
1452 | void *memory = js_malloc(sizeof(T)); return memory ? new(memory) T (p1, p2, p3) : __null; | |
1453 | } | |
1454 | template <class T, class P1, class P2, class P3, class P4> | |
1455 | __attribute__((always_inline)) inline T *js_new(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4) { | |
1456 | void *memory = js_malloc(sizeof(T)); return memory ? new(memory) T (p1, p2, p3, p4) : __null; | |
1457 | } | |
1458 | template <class T> | |
1459 | __attribute__((always_inline)) inline void js_delete(T *p) { | |
1460 | if (p) { | |
1461 | p->~T(); | |
1462 | js_free(p); | |
1463 | } | |
1464 | } | |
1465 | static const int JSMinAlignment = 8; | |
1466 | template <class T> | |
1467 | __attribute__((always_inline)) inline T *js_array_new(size_t n) { | |
1468 | uint64 numBytes64 = uint64(JSMinAlignment) + uint64(sizeof(T)) * uint64(n); | |
1469 | size_t numBytes = size_t(numBytes64); | |
1470 | if (numBytes64 != numBytes) { | |
1471 | ((void) 0); | |
1472 | return __null; | |
1473 | } | |
1474 | void *memory = js_malloc(numBytes); | |
1475 | if (!memory) | |
1476 | return __null; | |
1477 | *(size_t *)memory = n; | |
1478 | memory = (void*)(uintptr_t(memory) + JSMinAlignment); | |
1479 | return new(memory) T[n]; | |
1480 | } | |
1481 | template <class T> | |
1482 | __attribute__((always_inline)) inline void js_array_delete(T *p) { | |
1483 | if (p) { | |
1484 | void* p0 = (void *)(uintptr_t(p) - JSMinAlignment); | |
1485 | size_t n = *(size_t *)p0; | |
1486 | for (size_t i = 0; i < n; i++) | |
1487 | (p + i)->~T(); | |
1488 | js_free(p0); | |
1489 | } | |
1490 | } | |
1491 | namespace js { | |
1492 | template <class T> | |
1493 | __attribute__((always_inline)) inline static void | |
1494 | PodZero(T *t) | |
1495 | { | |
1496 | memset(t, 0, sizeof(T)); | |
1497 | } | |
1498 | template <class T> | |
1499 | __attribute__((always_inline)) inline static void | |
1500 | PodZero(T *t, size_t nelem) | |
1501 | { | |
1502 | memset(t, 0, nelem * sizeof(T)); | |
1503 | } | |
1504 | template <class T, size_t N> static void PodZero(T (&)[N]); | |
1505 | template <class T, size_t N> static void PodZero(T (&)[N], size_t); | |
1506 | template <class T, size_t N> | |
1507 | __attribute__((always_inline)) inline static void | |
1508 | PodArrayZero(T (&t)[N]) | |
1509 | { | |
1510 | memset(t, 0, N * sizeof(T)); | |
1511 | } | |
1512 | template <class T> | |
1513 | __attribute__((always_inline)) inline static void | |
1514 | PodCopy(T *dst, const T *src, size_t nelem) | |
1515 | { | |
1516 | ((void) 0); | |
1517 | ((void) 0); | |
1518 | if (nelem < 128) { | |
1519 | for (const T *srcend = src + nelem; src != srcend; ++src, ++dst) | |
1520 | *dst = *src; | |
1521 | } else { | |
1522 | memcpy(dst, src, nelem * sizeof(T)); | |
1523 | } | |
1524 | } | |
1525 | } | |
1526 | extern "C" { | |
1527 | typedef jsuword jsbitmap_t; | |
1528 | typedef jsbitmap_t jsbitmap; | |
1529 | extern __attribute__((visibility ("default"))) JSIntn JS_CeilingLog2(JSUint32 i); | |
1530 | extern __attribute__((visibility ("default"))) JSIntn JS_FloorLog2(JSUint32 i); | |
1531 | namespace js { | |
1532 | inline size_t | |
1533 | CountTrailingZeros(size_t n) | |
1534 | { | |
1535 | ((void) 0); | |
1536 | return __builtin_ctzll(n); | |
1537 | } | |
1538 | } | |
1539 | } | |
1540 | extern "C" { | |
1541 | struct _IO_FILE; | |
1542 | typedef struct _IO_FILE FILE; | |
1543 | typedef struct _IO_FILE __FILE; | |
1544 | typedef struct | |
1545 | { | |
1546 | int __count; | |
1547 | union | |
1548 | { | |
1549 | unsigned int __wch; | |
1550 | char __wchb[4]; | |
1551 | } __value; | |
1552 | } __mbstate_t; | |
1553 | typedef struct | |
1554 | { | |
1555 | __off_t __pos; | |
1556 | __mbstate_t __state; | |
1557 | } _G_fpos_t; | |
1558 | typedef struct | |
1559 | { | |
1560 | __off64_t __pos; | |
1561 | __mbstate_t __state; | |
1562 | } _G_fpos64_t; | |
1563 | typedef __builtin_va_list __gnuc_va_list; | |
1564 | struct _IO_jump_t; struct _IO_FILE; | |
1565 | typedef void _IO_lock_t; | |
1566 | struct _IO_marker { | |
1567 | struct _IO_marker *_next; | |
1568 | struct _IO_FILE *_sbuf; | |
1569 | int _pos; | |
1570 | }; | |
1571 | enum __codecvt_result | |
1572 | { | |
1573 | __codecvt_ok, | |
1574 | __codecvt_partial, | |
1575 | __codecvt_error, | |
1576 | __codecvt_noconv | |
1577 | }; | |
1578 | struct _IO_FILE { | |
1579 | int _flags; | |
1580 | char* _IO_read_ptr; | |
1581 | char* _IO_read_end; | |
1582 | char* _IO_read_base; | |
1583 | char* _IO_write_base; | |
1584 | char* _IO_write_ptr; | |
1585 | char* _IO_write_end; | |
1586 | char* _IO_buf_base; | |
1587 | char* _IO_buf_end; | |
1588 | char *_IO_save_base; | |
1589 | char *_IO_backup_base; | |
1590 | char *_IO_save_end; | |
1591 | struct _IO_marker *_markers; | |
1592 | struct _IO_FILE *_chain; | |
1593 | int _fileno; | |
1594 | int _flags2; | |
1595 | __off_t _old_offset; | |
1596 | unsigned short _cur_column; | |
1597 | signed char _vtable_offset; | |
1598 | char _shortbuf[1]; | |
1599 | _IO_lock_t *_lock; | |
1600 | __off64_t _offset; | |
1601 | void *__pad1; | |
1602 | void *__pad2; | |
1603 | void *__pad3; | |
1604 | void *__pad4; | |
1605 | size_t __pad5; | |
1606 | int _mode; | |
1607 | char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; | |
1608 | }; | |
1609 | struct _IO_FILE_plus; | |
1610 | extern struct _IO_FILE_plus _IO_2_1_stdin_; | |
1611 | extern struct _IO_FILE_plus _IO_2_1_stdout_; | |
1612 | extern struct _IO_FILE_plus _IO_2_1_stderr_; | |
1613 | typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); | |
1614 | typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf, | |
1615 | size_t __n); | |
1616 | typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w); | |
1617 | typedef int __io_close_fn (void *__cookie); | |
1618 | typedef __io_read_fn cookie_read_function_t; | |
1619 | typedef __io_write_fn cookie_write_function_t; | |
1620 | typedef __io_seek_fn cookie_seek_function_t; | |
1621 | typedef __io_close_fn cookie_close_function_t; | |
1622 | typedef struct | |
1623 | { | |
1624 | __io_read_fn *read; | |
1625 | __io_write_fn *write; | |
1626 | __io_seek_fn *seek; | |
1627 | __io_close_fn *close; | |
1628 | } _IO_cookie_io_functions_t; | |
1629 | typedef _IO_cookie_io_functions_t cookie_io_functions_t; | |
1630 | struct _IO_cookie_file; | |
1631 | extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, | |
1632 | void *__cookie, _IO_cookie_io_functions_t __fns); | |
1633 | extern "C" { | |
1634 | extern int __underflow (_IO_FILE *); | |
1635 | extern int __uflow (_IO_FILE *); | |
1636 | extern int __overflow (_IO_FILE *, int); | |
1637 | extern int _IO_getc (_IO_FILE *__fp); | |
1638 | extern int _IO_putc (int __c, _IO_FILE *__fp); | |
1639 | extern int _IO_feof (_IO_FILE *__fp) throw (); | |
1640 | extern int _IO_ferror (_IO_FILE *__fp) throw (); | |
1641 | extern int _IO_peekc_locked (_IO_FILE *__fp); | |
1642 | extern void _IO_flockfile (_IO_FILE *) throw (); | |
1643 | extern void _IO_funlockfile (_IO_FILE *) throw (); | |
1644 | extern int _IO_ftrylockfile (_IO_FILE *) throw (); | |
1645 | extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, | |
1646 | __gnuc_va_list, int *__restrict); | |
1647 | extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, | |
1648 | __gnuc_va_list); | |
1649 | extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t); | |
1650 | extern size_t _IO_sgetn (_IO_FILE *, void *, size_t); | |
1651 | extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int); | |
1652 | extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int); | |
1653 | extern void _IO_free_backup_area (_IO_FILE *) throw (); | |
1654 | } | |
1655 | typedef __gnuc_va_list va_list; | |
1656 | typedef _G_fpos_t fpos_t; | |
1657 | typedef _G_fpos64_t fpos64_t; | |
1658 | extern struct _IO_FILE *stdin; | |
1659 | extern struct _IO_FILE *stdout; | |
1660 | extern struct _IO_FILE *stderr; | |
1661 | extern int remove (const char *__filename) throw (); | |
1662 | extern int rename (const char *__old, const char *__new) throw (); | |
1663 | extern int renameat (int __oldfd, const char *__old, int __newfd, | |
1664 | const char *__new) throw (); | |
1665 | extern FILE *tmpfile (void) __attribute__ ((__warn_unused_result__)); | |
1666 | extern FILE *tmpfile64 (void) __attribute__ ((__warn_unused_result__)); | |
1667 | extern char *tmpnam (char *__s) throw () __attribute__ ((__warn_unused_result__)); | |
1668 | extern char *tmpnam_r (char *__s) throw () __attribute__ ((__warn_unused_result__)); | |
1669 | extern char *tempnam (const char *__dir, const char *__pfx) | |
1670 | throw () __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__)); | |
1671 | extern int fclose (FILE *__stream); | |
1672 | extern int fflush (FILE *__stream); | |
1673 | extern int fflush_unlocked (FILE *__stream); | |
1674 | extern int fcloseall (void); | |
1675 | extern FILE *fopen (const char *__restrict __filename, | |
1676 | const char *__restrict __modes) __attribute__ ((__warn_unused_result__)); | |
1677 | extern FILE *freopen (const char *__restrict __filename, | |
1678 | const char *__restrict __modes, | |
1679 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1680 | extern FILE *fopen64 (const char *__restrict __filename, | |
1681 | const char *__restrict __modes) __attribute__ ((__warn_unused_result__)); | |
1682 | extern FILE *freopen64 (const char *__restrict __filename, | |
1683 | const char *__restrict __modes, | |
1684 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1685 | extern FILE *fdopen (int __fd, const char *__modes) throw () __attribute__ ((__warn_unused_result__)); | |
1686 | extern FILE *fopencookie (void *__restrict __magic_cookie, | |
1687 | const char *__restrict __modes, | |
1688 | _IO_cookie_io_functions_t __io_funcs) throw () __attribute__ ((__warn_unused_result__)); | |
1689 | extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) | |
1690 | throw () __attribute__ ((__warn_unused_result__)); | |
1691 | extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) throw () __attribute__ ((__warn_unused_result__)); | |
1692 | extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) throw (); | |
1693 | extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, | |
1694 | int __modes, size_t __n) throw (); | |
1695 | extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, | |
1696 | size_t __size) throw (); | |
1697 | extern void setlinebuf (FILE *__stream) throw (); | |
1698 | extern int fprintf (FILE *__restrict __stream, | |
1699 | const char *__restrict __format, ...); | |
1700 | extern int printf (const char *__restrict __format, ...); | |
1701 | extern int sprintf (char *__restrict __s, | |
1702 | const char *__restrict __format, ...) throw (); | |
1703 | extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, | |
1704 | __gnuc_va_list __arg); | |
1705 | extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); | |
1706 | extern int vsprintf (char *__restrict __s, const char *__restrict __format, | |
1707 | __gnuc_va_list __arg) throw (); | |
1708 | extern int snprintf (char *__restrict __s, size_t __maxlen, | |
1709 | const char *__restrict __format, ...) | |
1710 | throw () __attribute__ ((__format__ (__printf__, 3, 4))); | |
1711 | extern int vsnprintf (char *__restrict __s, size_t __maxlen, | |
1712 | const char *__restrict __format, __gnuc_va_list __arg) | |
1713 | throw () __attribute__ ((__format__ (__printf__, 3, 0))); | |
1714 | extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, | |
1715 | __gnuc_va_list __arg) | |
1716 | throw () __attribute__ ((__format__ (__printf__, 2, 0))) __attribute__ ((__warn_unused_result__)); | |
1717 | extern int __asprintf (char **__restrict __ptr, | |
1718 | const char *__restrict __fmt, ...) | |
1719 | throw () __attribute__ ((__format__ (__printf__, 2, 3))) __attribute__ ((__warn_unused_result__)); | |
1720 | extern int asprintf (char **__restrict __ptr, | |
1721 | const char *__restrict __fmt, ...) | |
1722 | throw () __attribute__ ((__format__ (__printf__, 2, 3))) __attribute__ ((__warn_unused_result__)); | |
1723 | extern int vdprintf (int __fd, const char *__restrict __fmt, | |
1724 | __gnuc_va_list __arg) | |
1725 | __attribute__ ((__format__ (__printf__, 2, 0))); | |
1726 | extern int dprintf (int __fd, const char *__restrict __fmt, ...) | |
1727 | __attribute__ ((__format__ (__printf__, 2, 3))); | |
1728 | extern int fscanf (FILE *__restrict __stream, | |
1729 | const char *__restrict __format, ...) __attribute__ ((__warn_unused_result__)); | |
1730 | extern int scanf (const char *__restrict __format, ...) __attribute__ ((__warn_unused_result__)); | |
1731 | extern int sscanf (const char *__restrict __s, | |
1732 | const char *__restrict __format, ...) throw (); | |
1733 | extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, | |
1734 | __gnuc_va_list __arg) | |
1735 | __attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__warn_unused_result__)); | |
1736 | extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) | |
1737 | __attribute__ ((__format__ (__scanf__, 1, 0))) __attribute__ ((__warn_unused_result__)); | |
1738 | extern int vsscanf (const char *__restrict __s, | |
1739 | const char *__restrict __format, __gnuc_va_list __arg) | |
1740 | throw () __attribute__ ((__format__ (__scanf__, 2, 0))); | |
1741 | extern int fgetc (FILE *__stream); | |
1742 | extern int getc (FILE *__stream); | |
1743 | extern int getchar (void); | |
1744 | extern int getc_unlocked (FILE *__stream); | |
1745 | extern int getchar_unlocked (void); | |
1746 | extern int fgetc_unlocked (FILE *__stream); | |
1747 | extern int fputc (int __c, FILE *__stream); | |
1748 | extern int putc (int __c, FILE *__stream); | |
1749 | extern int putchar (int __c); | |
1750 | extern int fputc_unlocked (int __c, FILE *__stream); | |
1751 | extern int putc_unlocked (int __c, FILE *__stream); | |
1752 | extern int putchar_unlocked (int __c); | |
1753 | extern int getw (FILE *__stream); | |
1754 | extern int putw (int __w, FILE *__stream); | |
1755 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) | |
1756 | __attribute__ ((__warn_unused_result__)); | |
1757 | extern char *gets (char *__s) __attribute__ ((__warn_unused_result__)) __attribute__ ((__deprecated__)); | |
1758 | extern char *fgets_unlocked (char *__restrict __s, int __n, | |
1759 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1760 | extern __ssize_t __getdelim (char **__restrict __lineptr, | |
1761 | size_t *__restrict __n, int __delimiter, | |
1762 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1763 | extern __ssize_t getdelim (char **__restrict __lineptr, | |
1764 | size_t *__restrict __n, int __delimiter, | |
1765 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1766 | extern __ssize_t getline (char **__restrict __lineptr, | |
1767 | size_t *__restrict __n, | |
1768 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1769 | extern int fputs (const char *__restrict __s, FILE *__restrict __stream); | |
1770 | extern int puts (const char *__s); | |
1771 | extern int ungetc (int __c, FILE *__stream); | |
1772 | extern size_t fread (void *__restrict __ptr, size_t __size, | |
1773 | size_t __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1774 | extern size_t fwrite (const void *__restrict __ptr, size_t __size, | |
1775 | size_t __n, FILE *__restrict __s); | |
1776 | extern int fputs_unlocked (const char *__restrict __s, | |
1777 | FILE *__restrict __stream); | |
1778 | extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, | |
1779 | size_t __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
1780 | extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, | |
1781 | size_t __n, FILE *__restrict __stream); | |
1782 | extern int fseek (FILE *__stream, long int __off, int __whence); | |
1783 | extern long int ftell (FILE *__stream) __attribute__ ((__warn_unused_result__)); | |
1784 | extern void rewind (FILE *__stream); | |
1785 | extern int fseeko (FILE *__stream, __off_t __off, int __whence); | |
1786 | extern __off_t ftello (FILE *__stream) __attribute__ ((__warn_unused_result__)); | |
1787 | extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); | |
1788 | extern int fsetpos (FILE *__stream, const fpos_t *__pos); | |
1789 | extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); | |
1790 | extern __off64_t ftello64 (FILE *__stream) __attribute__ ((__warn_unused_result__)); | |
1791 | extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); | |
1792 | extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); | |
1793 | extern void clearerr (FILE *__stream) throw (); | |
1794 | extern int feof (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1795 | extern int ferror (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1796 | extern void clearerr_unlocked (FILE *__stream) throw (); | |
1797 | extern int feof_unlocked (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1798 | extern int ferror_unlocked (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1799 | extern void perror (const char *__s); | |
1800 | extern int sys_nerr; | |
1801 | extern const char *const sys_errlist[]; | |
1802 | extern int _sys_nerr; | |
1803 | extern const char *const _sys_errlist[]; | |
1804 | extern int fileno (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1805 | extern int fileno_unlocked (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1806 | extern FILE *popen (const char *__command, const char *__modes) __attribute__ ((__warn_unused_result__)); | |
1807 | extern int pclose (FILE *__stream); | |
1808 | extern char *ctermid (char *__s) throw (); | |
1809 | extern char *cuserid (char *__s); | |
1810 | struct obstack; | |
1811 | extern int obstack_printf (struct obstack *__restrict __obstack, | |
1812 | const char *__restrict __format, ...) | |
1813 | throw () __attribute__ ((__format__ (__printf__, 2, 3))); | |
1814 | extern int obstack_vprintf (struct obstack *__restrict __obstack, | |
1815 | const char *__restrict __format, | |
1816 | __gnuc_va_list __args) | |
1817 | throw () __attribute__ ((__format__ (__printf__, 2, 0))); | |
1818 | extern void flockfile (FILE *__stream) throw (); | |
1819 | extern int ftrylockfile (FILE *__stream) throw () __attribute__ ((__warn_unused_result__)); | |
1820 | extern void funlockfile (FILE *__stream) throw (); | |
1821 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1822 | getchar (void) | |
1823 | { | |
1824 | return _IO_getc (stdin); | |
1825 | } | |
1826 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1827 | fgetc_unlocked (FILE *__fp) | |
1828 | { | |
1829 | return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++); | |
1830 | } | |
1831 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1832 | getc_unlocked (FILE *__fp) | |
1833 | { | |
1834 | return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++); | |
1835 | } | |
1836 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1837 | getchar_unlocked (void) | |
1838 | { | |
1839 | return (__builtin_expect (((stdin)->_IO_read_ptr >= (stdin)->_IO_read_end), 0) ? __uflow (stdin) : *(unsigned char *) (stdin)->_IO_read_ptr++); | |
1840 | } | |
1841 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1842 | putchar (int __c) | |
1843 | { | |
1844 | return _IO_putc (__c, stdout); | |
1845 | } | |
1846 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1847 | fputc_unlocked (int __c, FILE *__stream) | |
1848 | { | |
1849 | return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c))); | |
1850 | } | |
1851 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1852 | putc_unlocked (int __c, FILE *__stream) | |
1853 | { | |
1854 | return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c))); | |
1855 | } | |
1856 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1857 | putchar_unlocked (int __c) | |
1858 | { | |
1859 | return (__builtin_expect (((stdout)->_IO_write_ptr >= (stdout)->_IO_write_end), 0) ? __overflow (stdout, (unsigned char) (__c)) : (unsigned char) (*(stdout)->_IO_write_ptr++ = (__c))); | |
1860 | } | |
1861 | extern __inline __attribute__ ((__gnu_inline__)) __ssize_t | |
1862 | getline (char **__lineptr, size_t *__n, FILE *__stream) | |
1863 | { | |
1864 | return __getdelim (__lineptr, __n, '\n', __stream); | |
1865 | } | |
1866 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1867 | __attribute__ ((__leaf__)) feof_unlocked (FILE *__stream) throw () | |
1868 | { | |
1869 | return (((__stream)->_flags & 0x10) != 0); | |
1870 | } | |
1871 | extern __inline __attribute__ ((__gnu_inline__)) int | |
1872 | __attribute__ ((__leaf__)) ferror_unlocked (FILE *__stream) throw () | |
1873 | { | |
1874 | return (((__stream)->_flags & 0x20) != 0); | |
1875 | } | |
1876 | extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, | |
1877 | const char *__restrict __format, ...) throw (); | |
1878 | extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, | |
1879 | const char *__restrict __format, | |
1880 | __gnuc_va_list __ap) throw (); | |
1881 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1882 | __attribute__ ((__leaf__)) sprintf (char *__restrict __s, const char *__restrict __fmt, ...) throw () | |
1883 | { | |
1884 | return __builtin___sprintf_chk (__s, 2 - 1, | |
1885 | __builtin_object_size (__s, 2 > 1), __fmt, __builtin_va_arg_pack ()); | |
1886 | } | |
1887 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1888 | __attribute__ ((__leaf__)) vsprintf (char *__restrict __s, const char *__restrict __fmt, __gnuc_va_list __ap) throw () | |
1889 | { | |
1890 | return __builtin___vsprintf_chk (__s, 2 - 1, | |
1891 | __builtin_object_size (__s, 2 > 1), __fmt, __ap); | |
1892 | } | |
1893 | extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, | |
1894 | size_t __slen, const char *__restrict __format, | |
1895 | ...) throw (); | |
1896 | extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, | |
1897 | size_t __slen, const char *__restrict __format, | |
1898 | __gnuc_va_list __ap) throw (); | |
1899 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1900 | __attribute__ ((__leaf__)) snprintf (char *__restrict __s, size_t __n, const char *__restrict __fmt, ...) throw () | |
1901 | { | |
1902 | return __builtin___snprintf_chk (__s, __n, 2 - 1, | |
1903 | __builtin_object_size (__s, 2 > 1), __fmt, __builtin_va_arg_pack ()); | |
1904 | } | |
1905 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1906 | __attribute__ ((__leaf__)) vsnprintf (char *__restrict __s, size_t __n, const char *__restrict __fmt, __gnuc_va_list __ap) throw () | |
1907 | { | |
1908 | return __builtin___vsnprintf_chk (__s, __n, 2 - 1, | |
1909 | __builtin_object_size (__s, 2 > 1), __fmt, __ap); | |
1910 | } | |
1911 | extern int __fprintf_chk (FILE *__restrict __stream, int __flag, | |
1912 | const char *__restrict __format, ...); | |
1913 | extern int __printf_chk (int __flag, const char *__restrict __format, ...); | |
1914 | extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, | |
1915 | const char *__restrict __format, __gnuc_va_list __ap); | |
1916 | extern int __vprintf_chk (int __flag, const char *__restrict __format, | |
1917 | __gnuc_va_list __ap); | |
1918 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1919 | fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...) | |
1920 | { | |
1921 | return __fprintf_chk (__stream, 2 - 1, __fmt, | |
1922 | __builtin_va_arg_pack ()); | |
1923 | } | |
1924 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1925 | printf (const char *__restrict __fmt, ...) | |
1926 | { | |
1927 | return __printf_chk (2 - 1, __fmt, __builtin_va_arg_pack ()); | |
1928 | } | |
1929 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1930 | vprintf (const char *__restrict __fmt, __gnuc_va_list __ap) | |
1931 | { | |
1932 | return __vfprintf_chk (stdout, 2 - 1, __fmt, __ap); | |
1933 | } | |
1934 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1935 | vfprintf (FILE *__restrict __stream, | |
1936 | const char *__restrict __fmt, __gnuc_va_list __ap) | |
1937 | { | |
1938 | return __vfprintf_chk (__stream, 2 - 1, __fmt, __ap); | |
1939 | } | |
1940 | extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt, | |
1941 | ...) __attribute__ ((__format__ (__printf__, 3, 4))); | |
1942 | extern int __vdprintf_chk (int __fd, int __flag, | |
1943 | const char *__restrict __fmt, __gnuc_va_list __arg) | |
1944 | __attribute__ ((__format__ (__printf__, 3, 0))); | |
1945 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1946 | dprintf (int __fd, const char *__restrict __fmt, ...) | |
1947 | { | |
1948 | return __dprintf_chk (__fd, 2 - 1, __fmt, | |
1949 | __builtin_va_arg_pack ()); | |
1950 | } | |
1951 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1952 | vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap) | |
1953 | { | |
1954 | return __vdprintf_chk (__fd, 2 - 1, __fmt, __ap); | |
1955 | } | |
1956 | extern int __asprintf_chk (char **__restrict __ptr, int __flag, | |
1957 | const char *__restrict __fmt, ...) | |
1958 | throw () __attribute__ ((__format__ (__printf__, 3, 4))) __attribute__ ((__warn_unused_result__)); | |
1959 | extern int __vasprintf_chk (char **__restrict __ptr, int __flag, | |
1960 | const char *__restrict __fmt, __gnuc_va_list __arg) | |
1961 | throw () __attribute__ ((__format__ (__printf__, 3, 0))) __attribute__ ((__warn_unused_result__)); | |
1962 | extern int __obstack_printf_chk (struct obstack *__restrict __obstack, | |
1963 | int __flag, const char *__restrict __format, | |
1964 | ...) | |
1965 | throw () __attribute__ ((__format__ (__printf__, 3, 4))); | |
1966 | extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack, | |
1967 | int __flag, | |
1968 | const char *__restrict __format, | |
1969 | __gnuc_va_list __args) | |
1970 | throw () __attribute__ ((__format__ (__printf__, 3, 0))); | |
1971 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1972 | __attribute__ ((__leaf__)) asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...) throw () | |
1973 | { | |
1974 | return __asprintf_chk (__ptr, 2 - 1, __fmt, | |
1975 | __builtin_va_arg_pack ()); | |
1976 | } | |
1977 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1978 | __attribute__ ((__leaf__)) __asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...) throw () | |
1979 | { | |
1980 | return __asprintf_chk (__ptr, 2 - 1, __fmt, | |
1981 | __builtin_va_arg_pack ()); | |
1982 | } | |
1983 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1984 | __attribute__ ((__leaf__)) obstack_printf (struct obstack *__restrict __obstack, const char *__restrict __fmt, ...) throw () | |
1985 | { | |
1986 | return __obstack_printf_chk (__obstack, 2 - 1, __fmt, | |
1987 | __builtin_va_arg_pack ()); | |
1988 | } | |
1989 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1990 | __attribute__ ((__leaf__)) vasprintf (char **__restrict __ptr, const char *__restrict __fmt, __gnuc_va_list __ap) throw () | |
1991 | { | |
1992 | return __vasprintf_chk (__ptr, 2 - 1, __fmt, __ap); | |
1993 | } | |
1994 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int | |
1995 | __attribute__ ((__leaf__)) obstack_vprintf (struct obstack *__restrict __obstack, const char *__restrict __fmt, __gnuc_va_list __ap) throw () | |
1996 | { | |
1997 | return __obstack_vprintf_chk (__obstack, 2 - 1, __fmt, | |
1998 | __ap); | |
1999 | } | |
2000 | extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, | |
2001 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
2002 | extern char *__fgets_alias (char *__restrict __s, int __n, FILE *__restrict __stream) __asm__ ("" "fgets") | |
2003 | __attribute__ ((__warn_unused_result__)); | |
2004 | extern char *__fgets_chk_warn (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) __asm__ ("" "__fgets_chk") | |
2005 | __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fgets called with bigger size than length " "of destination buffer"))) | |
2006 | ; | |
2007 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char * | |
2008 | fgets (char *__restrict __s, int __n, FILE *__restrict __stream) | |
2009 | { | |
2010 | if (__builtin_object_size (__s, 2 > 1) != (size_t) -1) | |
2011 | { | |
2012 | if (!__builtin_constant_p (__n) || __n <= 0) | |
2013 | return __fgets_chk (__s, __builtin_object_size (__s, 2 > 1), __n, __stream); | |
2014 | if ((size_t) __n > __builtin_object_size (__s, 2 > 1)) | |
2015 | return __fgets_chk_warn (__s, __builtin_object_size (__s, 2 > 1), __n, __stream); | |
2016 | } | |
2017 | return __fgets_alias (__s, __n, __stream); | |
2018 | } | |
2019 | extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, | |
2020 | size_t __size, size_t __n, | |
2021 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
2022 | extern size_t __fread_alias (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "fread") | |
2023 | __attribute__ ((__warn_unused_result__)); | |
2024 | extern size_t __fread_chk_warn (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_chk") | |
2025 | __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fread called with bigger size * nmemb than length " "of destination buffer"))) | |
2026 | ; | |
2027 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) size_t | |
2028 | fread (void *__restrict __ptr, size_t __size, size_t __n, | |
2029 | FILE *__restrict __stream) | |
2030 | { | |
2031 | if (__builtin_object_size (__ptr, 0) != (size_t) -1) | |
2032 | { | |
2033 | if (!__builtin_constant_p (__size) | |
2034 | || !__builtin_constant_p (__n) | |
2035 | || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) | |
2036 | return __fread_chk (__ptr, __builtin_object_size (__ptr, 0), __size, __n, __stream); | |
2037 | if (__size * __n > __builtin_object_size (__ptr, 0)) | |
2038 | return __fread_chk_warn (__ptr, __builtin_object_size (__ptr, 0), __size, __n, __stream); | |
2039 | } | |
2040 | return __fread_alias (__ptr, __size, __n, __stream); | |
2041 | } | |
2042 | extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, | |
2043 | int __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
2044 | extern char *__fgets_unlocked_alias (char *__restrict __s, int __n, FILE *__restrict __stream) __asm__ ("" "fgets_unlocked") | |
2045 | __attribute__ ((__warn_unused_result__)); | |
2046 | extern char *__fgets_unlocked_chk_warn (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) __asm__ ("" "__fgets_unlocked_chk") | |
2047 | __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fgets_unlocked called with bigger size than length " "of destination buffer"))) | |
2048 | ; | |
2049 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char * | |
2050 | fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) | |
2051 | { | |
2052 | if (__builtin_object_size (__s, 2 > 1) != (size_t) -1) | |
2053 | { | |
2054 | if (!__builtin_constant_p (__n) || __n <= 0) | |
2055 | return __fgets_unlocked_chk (__s, __builtin_object_size (__s, 2 > 1), __n, __stream); | |
2056 | if ((size_t) __n > __builtin_object_size (__s, 2 > 1)) | |
2057 | return __fgets_unlocked_chk_warn (__s, __builtin_object_size (__s, 2 > 1), __n, __stream); | |
2058 | } | |
2059 | return __fgets_unlocked_alias (__s, __n, __stream); | |
2060 | } | |
2061 | extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, | |
2062 | size_t __size, size_t __n, | |
2063 | FILE *__restrict __stream) __attribute__ ((__warn_unused_result__)); | |
2064 | extern size_t __fread_unlocked_alias (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "fread_unlocked") | |
2065 | __attribute__ ((__warn_unused_result__)); | |
2066 | extern size_t __fread_unlocked_chk_warn (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_unlocked_chk") | |
2067 | __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fread_unlocked called with bigger size * nmemb than " "length of destination buffer"))) | |
2068 | ; | |
2069 | extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) size_t | |
2070 | fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, | |
2071 | FILE *__restrict __stream) | |
2072 | { | |
2073 | if (__builtin_object_size (__ptr, 0) != (size_t) -1) | |
2074 | { | |
2075 | if (!__builtin_constant_p (__size) | |
2076 | || !__builtin_constant_p (__n) | |
2077 | || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) | |
2078 | return __fread_unlocked_chk (__ptr, __builtin_object_size (__ptr, 0), __size, __n, | |
2079 | __stream); | |
2080 | if (__size * __n > __builtin_object_size (__ptr, 0)) | |
2081 | return __fread_unlocked_chk_warn (__ptr, __builtin_object_size (__ptr, 0), __size, __n, | |
2082 | __stream); | |
2083 | } | |
2084 | if (__builtin_constant_p (__size) | |
2085 | && __builtin_constant_p (__n) | |
2086 | && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) | |
2087 | && __size * __n <= 8) | |
2088 | { | |
2089 | size_t __cnt = __size * __n; | |
2090 | char *__cptr = (char *) __ptr; | |
2091 | if (__cnt == 0) | |
2092 | return 0; | |
2093 | for (; __cnt > 0; --__cnt) | |
2094 | { | |
2095 | int __c = (__builtin_expect (((__stream)->_IO_read_ptr >= (__stream)->_IO_read_end), 0) ? __uflow (__stream) : *(unsigned char *) (__stream)->_IO_read_ptr++); | |
2096 | if (__c == (-1)) | |
2097 | break; | |
2098 | *__cptr++ = __c; | |
2099 | } | |
2100 | return (__cptr - (char *) __ptr) / __size; | |
2101 | } | |
2102 | return __fread_unlocked_alias (__ptr, __size, __n, __stream); | |
2103 | } | |
2104 | } | |
2105 | extern "C" { | |
2106 | extern __attribute__((visibility ("default"))) JSUint32 JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...); | |
2107 | extern __attribute__((visibility ("default"))) char* JS_smprintf(const char *fmt, ...); | |
2108 | extern __attribute__((visibility ("default"))) void JS_smprintf_free(char *mem); | |
2109 | extern __attribute__((visibility ("default"))) char* JS_sprintf_append(char *last, const char *fmt, ...); | |
2110 | typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen); | |
2111 | extern __attribute__((visibility ("default"))) JSUint32 JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...); | |
2112 | extern __attribute__((visibility ("default"))) JSUint32 JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap); | |
2113 | extern __attribute__((visibility ("default"))) char* JS_vsmprintf(const char *fmt, va_list ap); | |
2114 | extern __attribute__((visibility ("default"))) char* JS_vsprintf_append(char *last, const char *fmt, va_list ap); | |
2115 | extern __attribute__((visibility ("default"))) JSUint32 JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); | |
2116 | extern __attribute__((visibility ("default"))) JSInt32 JS_sscanf(const char *buf, const char *fmt, ...); | |
2117 | } | |
2118 | extern "C" { | |
2119 | enum JSValueType | |
2120 | { | |
2121 | JSVAL_TYPE_DOUBLE = 0x00, | |
2122 | JSVAL_TYPE_INT32 = 0x01, | |
2123 | JSVAL_TYPE_UNDEFINED = 0x02, | |
2124 | JSVAL_TYPE_BOOLEAN = 0x03, | |
2125 | JSVAL_TYPE_MAGIC = 0x04, | |
2126 | JSVAL_TYPE_STRING = 0x05, | |
2127 | JSVAL_TYPE_NULL = 0x06, | |
2128 | JSVAL_TYPE_OBJECT = 0x07, | |
2129 | JSVAL_TYPE_NONFUNOBJ = 0x57, | |
2130 | JSVAL_TYPE_FUNOBJ = 0x67, | |
2131 | JSVAL_TYPE_STRORNULL = 0x97, | |
2132 | JSVAL_TYPE_OBJORNULL = 0x98, | |
2133 | JSVAL_TYPE_BOXED = 0x99 | |
2134 | } __attribute__((packed)); | |
2135 | typedef int js_static_assert0[(sizeof(JSValueType) == 1) ? 1 : -1]; | |
2136 | enum JSValueTag | |
2137 | { | |
2138 | JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, | |
2139 | JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, | |
2140 | JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, | |
2141 | JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, | |
2142 | JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, | |
2143 | JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, | |
2144 | JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, | |
2145 | JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT | |
2146 | } __attribute__((packed)); | |
2147 | typedef int js_static_assert1[(sizeof(JSValueTag) == sizeof(uint32)) ? 1 : -1]; | |
2148 | enum JSValueShiftedTag | |
2149 | { | |
2150 | JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64)JSVAL_TAG_MAX_DOUBLE) << 47) | 0xFFFFFFFF), | |
2151 | JSVAL_SHIFTED_TAG_INT32 = (((uint64)JSVAL_TAG_INT32) << 47), | |
2152 | JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64)JSVAL_TAG_UNDEFINED) << 47), | |
2153 | JSVAL_SHIFTED_TAG_STRING = (((uint64)JSVAL_TAG_STRING) << 47), | |
2154 | JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64)JSVAL_TAG_BOOLEAN) << 47), | |
2155 | JSVAL_SHIFTED_TAG_MAGIC = (((uint64)JSVAL_TAG_MAGIC) << 47), | |
2156 | JSVAL_SHIFTED_TAG_NULL = (((uint64)JSVAL_TAG_NULL) << 47), | |
2157 | JSVAL_SHIFTED_TAG_OBJECT = (((uint64)JSVAL_TAG_OBJECT) << 47) | |
2158 | } __attribute__((packed)); | |
2159 | typedef int js_static_assert2[(sizeof(JSValueShiftedTag) == sizeof(uint64)) ? 1 : -1]; | |
2160 | typedef enum JSWhyMagic | |
2161 | { | |
2162 | JS_ARRAY_HOLE, | |
2163 | JS_ARGS_HOLE, | |
2164 | JS_NATIVE_ENUMERATE, | |
2165 | JS_NO_ITER_VALUE, | |
2166 | JS_GENERATOR_CLOSING, | |
2167 | JS_NO_CONSTANT, | |
2168 | JS_THIS_POISON, | |
2169 | JS_ARG_POISON, | |
2170 | JS_SERIALIZE_NO_NODE, | |
2171 | JS_GENERIC_MAGIC | |
2172 | } JSWhyMagic; | |
2173 | typedef struct JSString JSString; | |
2174 | typedef struct JSFlatString JSFlatString; | |
2175 | typedef struct JSObject JSObject; | |
2176 | typedef union jsval_layout | |
2177 | { | |
2178 | uint64 asBits; | |
2179 | struct { | |
2180 | uint64 payload47 : 47; | |
2181 | JSValueTag tag : 17; | |
2182 | } debugView; | |
2183 | struct { | |
2184 | union { | |
2185 | int32 i32; | |
2186 | uint32 u32; | |
2187 | JSWhyMagic why; | |
2188 | jsuword word; | |
2189 | } payload; | |
2190 | } s; | |
2191 | double asDouble; | |
2192 | void *asPtr; | |
2193 | } jsval_layout; | |
2194 | static __attribute__((always_inline)) inline JSBool | |
2195 | JSVAL_IS_DOUBLE_IMPL(jsval_layout l) | |
2196 | { | |
2197 | return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; | |
2198 | } | |
2199 | static __attribute__((always_inline)) inline jsval_layout | |
2200 | DOUBLE_TO_JSVAL_IMPL(double d) | |
2201 | { | |
2202 | jsval_layout l; | |
2203 | l.asDouble = d; | |
2204 | ((void) 0); | |
2205 | return l; | |
2206 | } | |
2207 | static __attribute__((always_inline)) inline JSBool | |
2208 | JSVAL_IS_INT32_IMPL(jsval_layout l) | |
2209 | { | |
2210 | return (uint32)(l.asBits >> 47) == JSVAL_TAG_INT32; | |
2211 | } | |
2212 | static __attribute__((always_inline)) inline int32 | |
2213 | JSVAL_TO_INT32_IMPL(jsval_layout l) | |
2214 | { | |
2215 | return (int32)l.asBits; | |
2216 | } | |
2217 | static __attribute__((always_inline)) inline jsval_layout | |
2218 | INT32_TO_JSVAL_IMPL(int32 i32) | |
2219 | { | |
2220 | jsval_layout l; | |
2221 | l.asBits = ((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32; | |
2222 | return l; | |
2223 | } | |
2224 | static __attribute__((always_inline)) inline JSBool | |
2225 | JSVAL_IS_NUMBER_IMPL(jsval_layout l) | |
2226 | { | |
2227 | return l.asBits < JSVAL_SHIFTED_TAG_UNDEFINED; | |
2228 | } | |
2229 | static __attribute__((always_inline)) inline JSBool | |
2230 | JSVAL_IS_UNDEFINED_IMPL(jsval_layout l) | |
2231 | { | |
2232 | return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; | |
2233 | } | |
2234 | static __attribute__((always_inline)) inline JSBool | |
2235 | JSVAL_IS_STRING_IMPL(jsval_layout l) | |
2236 | { | |
2237 | return (uint32)(l.asBits >> 47) == JSVAL_TAG_STRING; | |
2238 | } | |
2239 | static __attribute__((always_inline)) inline jsval_layout | |
2240 | STRING_TO_JSVAL_IMPL(JSString *str) | |
2241 | { | |
2242 | jsval_layout l; | |
2243 | uint64 strBits = (uint64)str; | |
2244 | ((void) 0); | |
2245 | ((void) 0); | |
2246 | l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING; | |
2247 | return l; | |
2248 | } | |
2249 | static __attribute__((always_inline)) inline JSString * | |
2250 | JSVAL_TO_STRING_IMPL(jsval_layout l) | |
2251 | { | |
2252 | return (JSString *)(l.asBits & 0x00007FFFFFFFFFFFLL); | |
2253 | } | |
2254 | static __attribute__((always_inline)) inline JSBool | |
2255 | JSVAL_IS_BOOLEAN_IMPL(jsval_layout l) | |
2256 | { | |
2257 | return (uint32)(l.asBits >> 47) == JSVAL_TAG_BOOLEAN; | |
2258 | } | |
2259 | static __attribute__((always_inline)) inline JSBool | |
2260 | JSVAL_TO_BOOLEAN_IMPL(jsval_layout l) | |
2261 | { | |
2262 | return (JSBool)l.asBits; | |
2263 | } | |
2264 | static __attribute__((always_inline)) inline jsval_layout | |
2265 | BOOLEAN_TO_JSVAL_IMPL(JSBool b) | |
2266 | { | |
2267 | jsval_layout l; | |
2268 | l.asBits = ((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN; | |
2269 | return l; | |
2270 | } | |
2271 | static __attribute__((always_inline)) inline JSBool | |
2272 | JSVAL_IS_MAGIC_IMPL(jsval_layout l) | |
2273 | { | |
2274 | return (l.asBits >> 47) == JSVAL_TAG_MAGIC; | |
2275 | } | |
2276 | static __attribute__((always_inline)) inline JSObject * | |
2277 | MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(jsval_layout l) | |
2278 | { | |
2279 | uint64 ptrBits = l.asBits & 0x00007FFFFFFFFFFFLL; | |
2280 | ((void) 0); | |
2281 | ((void) 0); | |
2282 | return (JSObject *)ptrBits; | |
2283 | } | |
2284 | static __attribute__((always_inline)) inline JSBool | |
2285 | JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) | |
2286 | { | |
2287 | return l.asBits < JSVAL_SHIFTED_TAG_OBJECT; | |
2288 | } | |
2289 | static __attribute__((always_inline)) inline JSBool | |
2290 | JSVAL_IS_OBJECT_IMPL(jsval_layout l) | |
2291 | { | |
2292 | ((void) 0); | |
2293 | return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT; | |
2294 | } | |
2295 | static __attribute__((always_inline)) inline JSBool | |
2296 | JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l) | |
2297 | { | |
2298 | ((void) 0); | |
2299 | return l.asBits >= JSVAL_SHIFTED_TAG_NULL; | |
2300 | } | |
2301 | static __attribute__((always_inline)) inline JSObject * | |
2302 | JSVAL_TO_OBJECT_IMPL(jsval_layout l) | |
2303 | { | |
2304 | uint64 ptrBits = l.asBits & 0x00007FFFFFFFFFFFLL; | |
2305 | ((void) 0); | |
2306 | return (JSObject *)ptrBits; | |
2307 | } | |
2308 | static __attribute__((always_inline)) inline jsval_layout | |
2309 | OBJECT_TO_JSVAL_IMPL(JSObject *obj) | |
2310 | { | |
2311 | jsval_layout l; | |
2312 | uint64 objBits = (uint64)obj; | |
2313 | ((void) 0); | |
2314 | ((void) 0); | |
2315 | l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT; | |
2316 | return l; | |
2317 | } | |
2318 | static __attribute__((always_inline)) inline JSBool | |
2319 | JSVAL_IS_NULL_IMPL(jsval_layout l) | |
2320 | { | |
2321 | return l.asBits == JSVAL_SHIFTED_TAG_NULL; | |
2322 | } | |
2323 | static __attribute__((always_inline)) inline JSBool | |
2324 | JSVAL_IS_GCTHING_IMPL(jsval_layout l) | |
2325 | { | |
2326 | return l.asBits >= JSVAL_SHIFTED_TAG_STRING; | |
2327 | } | |
2328 | static __attribute__((always_inline)) inline void * | |
2329 | JSVAL_TO_GCTHING_IMPL(jsval_layout l) | |
2330 | { | |
2331 | uint64 ptrBits = l.asBits & 0x00007FFFFFFFFFFFLL; | |
2332 | ((void) 0); | |
2333 | return (void *)ptrBits; | |
2334 | } | |
2335 | static __attribute__((always_inline)) inline JSBool | |
2336 | JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) | |
2337 | { | |
2338 | return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l); | |
2339 | } | |
2340 | static __attribute__((always_inline)) inline uint32 | |
2341 | JSVAL_TRACE_KIND_IMPL(jsval_layout l) | |
2342 | { | |
2343 | return (uint32)(JSBool)!(JSVAL_IS_OBJECT_IMPL(l)); | |
2344 | } | |
2345 | static __attribute__((always_inline)) inline jsval_layout | |
2346 | PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr) | |
2347 | { | |
2348 | jsval_layout l; | |
2349 | uint64 ptrBits = (uint64)ptr; | |
2350 | ((void) 0); | |
2351 | l.asBits = ptrBits >> 1; | |
2352 | ((void) 0); | |
2353 | return l; | |
2354 | } | |
2355 | static __attribute__((always_inline)) inline void * | |
2356 | JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l) | |
2357 | { | |
2358 | ((void) 0); | |
2359 | return (void *)(l.asBits << 1); | |
2360 | } | |
2361 | static __attribute__((always_inline)) inline double | |
2362 | JS_CANONICALIZE_NAN(double d) | |
2363 | { | |
2364 | if ((__builtin_expect((d != d), 0))) { | |
2365 | jsval_layout l; | |
2366 | l.asBits = 0x7FF8000000000000LL; | |
2367 | return l.asDouble; | |
2368 | } | |
2369 | return d; | |
2370 | } | |
2371 | typedef __attribute__((aligned (8))) uint64 jsval; | |
2372 | typedef ptrdiff_t jsid; | |
2373 | } | |
2374 | extern "C" { | |
2375 | typedef JSInt32 jsint; | |
2376 | typedef JSUint32 jsuint; | |
2377 | typedef float64 jsdouble; | |
2378 | typedef JSInt32 jsrefcount; | |
2379 | typedef JSUint16 jschar; | |
2380 | typedef enum JSVersion { | |
2381 | JSVERSION_1_0 = 100, | |
2382 | JSVERSION_1_1 = 110, | |
2383 | JSVERSION_1_2 = 120, | |
2384 | JSVERSION_1_3 = 130, | |
2385 | JSVERSION_1_4 = 140, | |
2386 | JSVERSION_ECMA_3 = 148, | |
2387 | JSVERSION_1_5 = 150, | |
2388 | JSVERSION_1_6 = 160, | |
2389 | JSVERSION_1_7 = 170, | |
2390 | JSVERSION_1_8 = 180, | |
2391 | JSVERSION_ECMA_5 = 185, | |
2392 | JSVERSION_DEFAULT = 0, | |
2393 | JSVERSION_UNKNOWN = -1, | |
2394 | JSVERSION_LATEST = JSVERSION_ECMA_5 | |
2395 | } JSVersion; | |
2396 | typedef enum JSType { | |
2397 | JSTYPE_VOID, | |
2398 | JSTYPE_OBJECT, | |
2399 | JSTYPE_FUNCTION, | |
2400 | JSTYPE_STRING, | |
2401 | JSTYPE_NUMBER, | |
2402 | JSTYPE_BOOLEAN, | |
2403 | JSTYPE_NULL, | |
2404 | JSTYPE_XML, | |
2405 | JSTYPE_LIMIT | |
2406 | } JSType; | |
2407 | typedef enum JSProtoKey { | |
2408 | JSProto_Null = 0, | |
2409 | JSProto_Object = 1, | |
2410 | JSProto_Function = 2, | |
2411 | JSProto_Array = 3, | |
2412 | JSProto_Boolean = 4, | |
2413 | JSProto_JSON = 5, | |
2414 | JSProto_Date = 6, | |
2415 | JSProto_Math = 7, | |
2416 | JSProto_Number = 8, | |
2417 | JSProto_String = 9, | |
2418 | JSProto_RegExp = 10, | |
2419 | JSProto_XML = 11, | |
2420 | JSProto_Namespace = 12, | |
2421 | JSProto_QName = 13, | |
2422 | JSProto_Reflect = 14, | |
2423 | JSProto_ASTNode = 15, | |
2424 | JSProto_Error = 16, | |
2425 | JSProto_InternalError = 17, | |
2426 | JSProto_EvalError = 18, | |
2427 | JSProto_RangeError = 19, | |
2428 | JSProto_ReferenceError = 20, | |
2429 | JSProto_SyntaxError = 21, | |
2430 | JSProto_TypeError = 22, | |
2431 | JSProto_URIError = 23, | |
2432 | JSProto_Generator = 24, | |
2433 | JSProto_Iterator = 25, | |
2434 | JSProto_StopIteration = 26, | |
2435 | JSProto_ArrayBuffer = 27, | |
2436 | JSProto_Int8Array = 28, | |
2437 | JSProto_Uint8Array = 29, | |
2438 | JSProto_Int16Array = 30, | |
2439 | JSProto_Uint16Array = 31, | |
2440 | JSProto_Int32Array = 32, | |
2441 | JSProto_Uint32Array = 33, | |
2442 | JSProto_Float32Array = 34, | |
2443 | JSProto_Float64Array = 35, | |
2444 | JSProto_Uint8ClampedArray = 36, | |
2445 | JSProto_Proxy = 37, | |
2446 | JSProto_AnyName = 38, | |
2447 | JSProto_LIMIT | |
2448 | } JSProtoKey; | |
2449 | typedef enum JSAccessMode { | |
2450 | JSACC_PROTO = 0, | |
2451 | JSACC_PARENT = 1, | |
2452 | JSACC_WATCH = 3, | |
2453 | JSACC_READ = 4, | |
2454 | JSACC_WRITE = 8, | |
2455 | JSACC_LIMIT | |
2456 | } JSAccessMode; | |
2457 | typedef enum JSIterateOp { | |
2458 | JSENUMERATE_INIT, | |
2459 | JSENUMERATE_INIT_ALL, | |
2460 | JSENUMERATE_NEXT, | |
2461 | JSENUMERATE_DESTROY | |
2462 | } JSIterateOp; | |
2463 | typedef struct JSClass JSClass; | |
2464 | typedef struct JSConstDoubleSpec JSConstDoubleSpec; | |
2465 | typedef struct JSContext JSContext; | |
2466 | typedef struct JSErrorReport JSErrorReport; | |
2467 | typedef struct JSFunction JSFunction; | |
2468 | typedef struct JSFunctionSpec JSFunctionSpec; | |
2469 | typedef struct JSTracer JSTracer; | |
2470 | typedef struct JSIdArray JSIdArray; | |
2471 | typedef struct JSPropertyDescriptor JSPropertyDescriptor; | |
2472 | typedef struct JSPropertySpec JSPropertySpec; | |
2473 | typedef struct JSObjectMap JSObjectMap; | |
2474 | typedef struct JSRuntime JSRuntime; | |
2475 | typedef struct JSStackFrame JSStackFrame; | |
2476 | typedef struct JSXDRState JSXDRState; | |
2477 | typedef struct JSExceptionState JSExceptionState; | |
2478 | typedef struct JSLocaleCallbacks JSLocaleCallbacks; | |
2479 | typedef struct JSSecurityCallbacks JSSecurityCallbacks; | |
2480 | typedef struct JSONParser JSONParser; | |
2481 | typedef struct JSCompartment JSCompartment; | |
2482 | typedef struct JSCrossCompartmentCall JSCrossCompartmentCall; | |
2483 | typedef struct JSStructuredCloneWriter JSStructuredCloneWriter; | |
2484 | typedef struct JSStructuredCloneReader JSStructuredCloneReader; | |
2485 | typedef struct JSStructuredCloneCallbacks JSStructuredCloneCallbacks; | |
2486 | typedef class JSWrapper JSWrapper; | |
2487 | typedef class JSCrossCompartmentWrapper JSCrossCompartmentWrapper; | |
2488 | typedef JSBool | |
2489 | (* JSPropertyOp)(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
2490 | typedef JSBool | |
2491 | (* JSStrictPropertyOp)(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); | |
2492 | typedef JSBool | |
2493 | (* JSNewEnumerateOp)(JSContext *cx, JSObject *obj, JSIterateOp enum_op, | |
2494 | jsval *statep, jsid *idp); | |
2495 | typedef JSBool | |
2496 | (* JSEnumerateOp)(JSContext *cx, JSObject *obj); | |
2497 | typedef JSBool | |
2498 | (* JSResolveOp)(JSContext *cx, JSObject *obj, jsid id); | |
2499 | typedef JSBool | |
2500 | (* JSNewResolveOp)(JSContext *cx, JSObject *obj, jsid id, uintN flags, | |
2501 | JSObject **objp); | |
2502 | typedef JSBool | |
2503 | (* JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, jsval *vp); | |
2504 | typedef JSType | |
2505 | (* JSTypeOfOp)(JSContext *cx, JSObject *obj); | |
2506 | typedef void | |
2507 | (* JSFinalizeOp)(JSContext *cx, JSObject *obj); | |
2508 | typedef void | |
2509 | (* JSStringFinalizeOp)(JSContext *cx, JSString *str); | |
2510 | typedef JSBool | |
2511 | (* JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | |
2512 | jsval *vp); | |
2513 | typedef JSBool | |
2514 | (* JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp); | |
2515 | typedef JSBool | |
2516 | (* JSHasInstanceOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); | |
2517 | typedef uint32 | |
2518 | (* JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); | |
2519 | typedef void | |
2520 | (* JSTraceOp)(JSTracer *trc, JSObject *obj); | |
2521 | typedef void | |
2522 | (* JSTraceCallback)(JSTracer *trc, void *thing, uint32 kind); | |
2523 | typedef void | |
2524 | (* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize); | |
2525 | typedef JSBool | |
2526 | (* JSEqualityOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); | |
2527 | typedef JSBool | |
2528 | (* JSNative)(JSContext *cx, uintN argc, jsval *vp); | |
2529 | typedef enum JSContextOp { | |
2530 | JSCONTEXT_NEW, | |
2531 | JSCONTEXT_DESTROY | |
2532 | } JSContextOp; | |
2533 | typedef JSBool | |
2534 | (* JSContextCallback)(JSContext *cx, uintN contextOp); | |
2535 | typedef enum JSGCStatus { | |
2536 | JSGC_BEGIN, | |
2537 | JSGC_END, | |
2538 | JSGC_MARK_END, | |
2539 | JSGC_FINALIZE_END | |
2540 | } JSGCStatus; | |
2541 | typedef JSBool | |
2542 | (* JSGCCallback)(JSContext *cx, JSGCStatus status); | |
2543 | typedef void | |
2544 | (* JSTraceDataOp)(JSTracer *trc, void *data); | |
2545 | typedef JSBool | |
2546 | (* JSOperationCallback)(JSContext *cx); | |
2547 | typedef void | |
2548 | (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report); | |
2549 | typedef enum JSExnType { | |
2550 | JSEXN_NONE = -1, | |
2551 | JSEXN_ERR, | |
2552 | JSEXN_INTERNALERR, | |
2553 | JSEXN_EVALERR, | |
2554 | JSEXN_RANGEERR, | |
2555 | JSEXN_REFERENCEERR, | |
2556 | JSEXN_SYNTAXERR, | |
2557 | JSEXN_TYPEERR, | |
2558 | JSEXN_URIERR, | |
2559 | JSEXN_LIMIT | |
2560 | } JSExnType; | |
2561 | typedef struct JSErrorFormatString { | |
2562 | const char *format; | |
2563 | uint16 argCount; | |
2564 | int16 exnType; | |
2565 | } JSErrorFormatString; | |
2566 | typedef const JSErrorFormatString * | |
2567 | (* JSErrorCallback)(void *userRef, const char *locale, | |
2568 | const uintN errorNumber); | |
2569 | typedef JSBool | |
2570 | (* JSArgumentFormatter)(JSContext *cx, const char *format, JSBool fromJS, | |
2571 | jsval **vpp, va_list *app); | |
2572 | typedef JSBool | |
2573 | (* JSLocaleToUpperCase)(JSContext *cx, JSString *src, jsval *rval); | |
2574 | typedef JSBool | |
2575 | (* JSLocaleToLowerCase)(JSContext *cx, JSString *src, jsval *rval); | |
2576 | typedef JSBool | |
2577 | (* JSLocaleCompare)(JSContext *cx, JSString *src1, JSString *src2, | |
2578 | jsval *rval); | |
2579 | typedef JSBool | |
2580 | (* JSLocaleToUnicode)(JSContext *cx, const char *src, jsval *rval); | |
2581 | typedef struct JSPrincipals JSPrincipals; | |
2582 | typedef JSBool | |
2583 | (* JSPrincipalsTranscoder)(JSXDRState *xdr, JSPrincipals **principalsp); | |
2584 | typedef JSPrincipals * | |
2585 | (* JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj); | |
2586 | typedef JSBool | |
2587 | (* JSCSPEvalChecker)(JSContext *cx); | |
2588 | typedef JSObject * | |
2589 | (* JSWrapObjectCallback)(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, | |
2590 | uintN flags); | |
2591 | typedef JSObject * | |
2592 | (* JSPreWrapCallback)(JSContext *cx, JSObject *scope, JSObject *obj, uintN flags); | |
2593 | typedef enum { | |
2594 | JSCOMPARTMENT_NEW, | |
2595 | JSCOMPARTMENT_DESTROY | |
2596 | } JSCompartmentOp; | |
2597 | typedef JSBool | |
2598 | (* JSCompartmentCallback)(JSContext *cx, JSCompartment *compartment, uintN compartmentOp); | |
2599 | typedef JSObject *(*ReadStructuredCloneOp)(JSContext *cx, JSStructuredCloneReader *r, | |
2600 | uint32 tag, uint32 data, void *closure); | |
2601 | typedef JSBool (*WriteStructuredCloneOp)(JSContext *cx, JSStructuredCloneWriter *w, | |
2602 | JSObject *obj, void *closure); | |
2603 | typedef void (*StructuredCloneErrorOp)(JSContext *cx, uint32 errorid); | |
2604 | } | |
2605 | extern "C" { | |
2606 | static __attribute__((always_inline)) inline JSBool | |
2607 | JSVAL_IS_NULL(jsval v) | |
2608 | { | |
2609 | jsval_layout l; | |
2610 | l.asBits = (v); | |
2611 | return JSVAL_IS_NULL_IMPL(l); | |
2612 | } | |
2613 | static __attribute__((always_inline)) inline JSBool | |
2614 | JSVAL_IS_VOID(jsval v) | |
2615 | { | |
2616 | jsval_layout l; | |
2617 | l.asBits = (v); | |
2618 | return JSVAL_IS_UNDEFINED_IMPL(l); | |
2619 | } | |
2620 | static __attribute__((always_inline)) inline JSBool | |
2621 | JSVAL_IS_INT(jsval v) | |
2622 | { | |
2623 | jsval_layout l; | |
2624 | l.asBits = (v); | |
2625 | return JSVAL_IS_INT32_IMPL(l); | |
2626 | } | |
2627 | static __attribute__((always_inline)) inline jsint | |
2628 | JSVAL_TO_INT(jsval v) | |
2629 | { | |
2630 | jsval_layout l; | |
2631 | ((void) 0); | |
2632 | l.asBits = (v); | |
2633 | return JSVAL_TO_INT32_IMPL(l); | |
2634 | } | |
2635 | static __attribute__((always_inline)) inline jsval | |
2636 | INT_TO_JSVAL(int32 i) | |
2637 | { | |
2638 | return ((INT32_TO_JSVAL_IMPL(i)).asBits); | |
2639 | } | |
2640 | static __attribute__((always_inline)) inline JSBool | |
2641 | JSVAL_IS_DOUBLE(jsval v) | |
2642 | { | |
2643 | jsval_layout l; | |
2644 | l.asBits = (v); | |
2645 | return JSVAL_IS_DOUBLE_IMPL(l); | |
2646 | } | |
2647 | static __attribute__((always_inline)) inline jsdouble | |
2648 | JSVAL_TO_DOUBLE(jsval v) | |
2649 | { | |
2650 | jsval_layout l; | |
2651 | ((void) 0); | |
2652 | l.asBits = (v); | |
2653 | return l.asDouble; | |
2654 | } | |
2655 | static __attribute__((always_inline)) inline jsval | |
2656 | DOUBLE_TO_JSVAL(jsdouble d) | |
2657 | { | |
2658 | d = JS_CANONICALIZE_NAN(d); | |
2659 | return ((DOUBLE_TO_JSVAL_IMPL(d)).asBits); | |
2660 | } | |
2661 | static __attribute__((always_inline)) inline jsval | |
2662 | UINT_TO_JSVAL(uint32 i) | |
2663 | { | |
2664 | if (i <= ((jsint)0x7fffffff)) | |
2665 | return INT_TO_JSVAL((int32)i); | |
2666 | return DOUBLE_TO_JSVAL((jsdouble)i); | |
2667 | } | |
2668 | static __attribute__((always_inline)) inline JSBool | |
2669 | JSVAL_IS_NUMBER(jsval v) | |
2670 | { | |
2671 | jsval_layout l; | |
2672 | l.asBits = (v); | |
2673 | return JSVAL_IS_NUMBER_IMPL(l); | |
2674 | } | |
2675 | static __attribute__((always_inline)) inline JSBool | |
2676 | JSVAL_IS_STRING(jsval v) | |
2677 | { | |
2678 | jsval_layout l; | |
2679 | l.asBits = (v); | |
2680 | return JSVAL_IS_STRING_IMPL(l); | |
2681 | } | |
2682 | static __attribute__((always_inline)) inline JSString * | |
2683 | JSVAL_TO_STRING(jsval v) | |
2684 | { | |
2685 | jsval_layout l; | |
2686 | ((void) 0); | |
2687 | l.asBits = (v); | |
2688 | return JSVAL_TO_STRING_IMPL(l); | |
2689 | } | |
2690 | static __attribute__((always_inline)) inline jsval | |
2691 | STRING_TO_JSVAL(JSString *str) | |
2692 | { | |
2693 | return ((STRING_TO_JSVAL_IMPL(str)).asBits); | |
2694 | } | |
2695 | static __attribute__((always_inline)) inline JSBool | |
2696 | JSVAL_IS_OBJECT(jsval v) | |
2697 | { | |
2698 | jsval_layout l; | |
2699 | l.asBits = (v); | |
2700 | return JSVAL_IS_OBJECT_OR_NULL_IMPL(l); | |
2701 | } | |
2702 | static __attribute__((always_inline)) inline JSObject * | |
2703 | JSVAL_TO_OBJECT(jsval v) | |
2704 | { | |
2705 | jsval_layout l; | |
2706 | ((void) 0); | |
2707 | l.asBits = (v); | |
2708 | return JSVAL_TO_OBJECT_IMPL(l); | |
2709 | } | |
2710 | static __attribute__((always_inline)) inline jsval | |
2711 | OBJECT_TO_JSVAL(JSObject *obj) | |
2712 | { | |
2713 | if (obj) | |
2714 | return ((OBJECT_TO_JSVAL_IMPL(obj)).asBits); | |
2715 | return ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
2716 | } | |
2717 | static __attribute__((always_inline)) inline JSBool | |
2718 | JSVAL_IS_BOOLEAN(jsval v) | |
2719 | { | |
2720 | jsval_layout l; | |
2721 | l.asBits = (v); | |
2722 | return JSVAL_IS_BOOLEAN_IMPL(l); | |
2723 | } | |
2724 | static __attribute__((always_inline)) inline JSBool | |
2725 | JSVAL_TO_BOOLEAN(jsval v) | |
2726 | { | |
2727 | jsval_layout l; | |
2728 | ((void) 0); | |
2729 | l.asBits = (v); | |
2730 | return JSVAL_TO_BOOLEAN_IMPL(l); | |
2731 | } | |
2732 | static __attribute__((always_inline)) inline jsval | |
2733 | BOOLEAN_TO_JSVAL(JSBool b) | |
2734 | { | |
2735 | return ((BOOLEAN_TO_JSVAL_IMPL(b)).asBits); | |
2736 | } | |
2737 | static __attribute__((always_inline)) inline JSBool | |
2738 | JSVAL_IS_PRIMITIVE(jsval v) | |
2739 | { | |
2740 | jsval_layout l; | |
2741 | l.asBits = (v); | |
2742 | return JSVAL_IS_PRIMITIVE_IMPL(l); | |
2743 | } | |
2744 | static __attribute__((always_inline)) inline JSBool | |
2745 | JSVAL_IS_GCTHING(jsval v) | |
2746 | { | |
2747 | jsval_layout l; | |
2748 | l.asBits = (v); | |
2749 | return JSVAL_IS_GCTHING_IMPL(l); | |
2750 | } | |
2751 | static __attribute__((always_inline)) inline void * | |
2752 | JSVAL_TO_GCTHING(jsval v) | |
2753 | { | |
2754 | jsval_layout l; | |
2755 | ((void) 0); | |
2756 | l.asBits = (v); | |
2757 | return JSVAL_TO_GCTHING_IMPL(l); | |
2758 | } | |
2759 | static __attribute__((always_inline)) inline jsval | |
2760 | PRIVATE_TO_JSVAL(void *ptr) | |
2761 | { | |
2762 | return ((PRIVATE_PTR_TO_JSVAL_IMPL(ptr)).asBits); | |
2763 | } | |
2764 | static __attribute__((always_inline)) inline void * | |
2765 | JSVAL_TO_PRIVATE(jsval v) | |
2766 | { | |
2767 | jsval_layout l; | |
2768 | ((void) 0); | |
2769 | l.asBits = (v); | |
2770 | return JSVAL_TO_PRIVATE_PTR_IMPL(l); | |
2771 | } | |
2772 | static __attribute__((always_inline)) inline JSBool | |
2773 | JSID_IS_STRING(jsid iden) | |
2774 | { | |
2775 | return ((iden) & 0x7) == 0; | |
2776 | } | |
2777 | static __attribute__((always_inline)) inline JSString * | |
2778 | JSID_TO_STRING(jsid iden) | |
2779 | { | |
2780 | ((void) 0); | |
2781 | return (JSString *)((iden)); | |
2782 | } | |
2783 | static __attribute__((always_inline)) inline JSBool | |
2784 | JSID_IS_ZERO(jsid iden) | |
2785 | { | |
2786 | return (iden) == 0; | |
2787 | } | |
2788 | __attribute__((visibility ("default"))) JSBool | |
2789 | JS_StringHasBeenInterned(JSString *str); | |
2790 | static __attribute__((always_inline)) inline jsid | |
2791 | INTERNED_STRING_TO_JSID(JSString *str) | |
2792 | { | |
2793 | jsid iden; | |
2794 | ((void) 0); | |
2795 | ((void) 0); | |
2796 | ((void) 0); | |
2797 | (iden) = (size_t)str; | |
2798 | return iden; | |
2799 | } | |
2800 | static __attribute__((always_inline)) inline JSBool | |
2801 | JSID_IS_INT(jsid iden) | |
2802 | { | |
2803 | return !!((iden) & 0x1); | |
2804 | } | |
2805 | static __attribute__((always_inline)) inline int32 | |
2806 | JSID_TO_INT(jsid iden) | |
2807 | { | |
2808 | ((void) 0); | |
2809 | return ((int32)(iden)) >> 1; | |
2810 | } | |
2811 | static __attribute__((always_inline)) inline JSBool | |
2812 | INT_FITS_IN_JSID(int32 i) | |
2813 | { | |
2814 | return ((jsuint)(i) - (jsuint)(-(1 << 30)) <= | |
2815 | (jsuint)(((1 << 30) - 1) - (-(1 << 30)))); | |
2816 | } | |
2817 | static __attribute__((always_inline)) inline jsid | |
2818 | INT_TO_JSID(int32 i) | |
2819 | { | |
2820 | jsid iden; | |
2821 | ((void) 0); | |
2822 | (iden) = ((i << 1) | 0x1); | |
2823 | return iden; | |
2824 | } | |
2825 | static __attribute__((always_inline)) inline JSBool | |
2826 | JSID_IS_OBJECT(jsid iden) | |
2827 | { | |
2828 | return ((iden) & 0x7) == 0x4 && | |
2829 | (size_t)(iden) != 0x4; | |
2830 | } | |
2831 | static __attribute__((always_inline)) inline JSObject * | |
2832 | JSID_TO_OBJECT(jsid iden) | |
2833 | { | |
2834 | ((void) 0); | |
2835 | return (JSObject *)((iden) & ~(size_t)0x7); | |
2836 | } | |
2837 | static __attribute__((always_inline)) inline jsid | |
2838 | OBJECT_TO_JSID(JSObject *obj) | |
2839 | { | |
2840 | jsid iden; | |
2841 | ((void) 0); | |
2842 | ((void) 0); | |
2843 | (iden) = ((size_t)obj | 0x4); | |
2844 | return iden; | |
2845 | } | |
2846 | static __attribute__((always_inline)) inline JSBool | |
2847 | JSID_IS_GCTHING(jsid iden) | |
2848 | { | |
2849 | return JSID_IS_STRING(iden) || JSID_IS_OBJECT(iden); | |
2850 | } | |
2851 | static __attribute__((always_inline)) inline void * | |
2852 | JSID_TO_GCTHING(jsid iden) | |
2853 | { | |
2854 | return (void *)((iden) & ~(size_t)0x7); | |
2855 | } | |
2856 | static __attribute__((always_inline)) inline JSBool | |
2857 | JSID_IS_DEFAULT_XML_NAMESPACE(jsid iden) | |
2858 | { | |
2859 | ((void) 0) | |
2860 | ; | |
2861 | return ((size_t)(iden) == 0x6); | |
2862 | } | |
2863 | static __attribute__((always_inline)) inline JSBool | |
2864 | JSID_IS_VOID(jsid iden) | |
2865 | { | |
2866 | ((void) 0) | |
2867 | ; | |
2868 | return ((size_t)(iden) == 0x2); | |
2869 | } | |
2870 | static __attribute__((always_inline)) inline JSBool | |
2871 | JSID_IS_EMPTY(jsid iden) | |
2872 | { | |
2873 | return ((size_t)(iden) == 0x4); | |
2874 | } | |
2875 | extern __attribute__((visibility ("default"))) int64 | |
2876 | JS_Now(void); | |
2877 | extern __attribute__((visibility ("default"))) jsval | |
2878 | JS_GetNaNValue(JSContext *cx); | |
2879 | extern __attribute__((visibility ("default"))) jsval | |
2880 | JS_GetNegativeInfinityValue(JSContext *cx); | |
2881 | extern __attribute__((visibility ("default"))) jsval | |
2882 | JS_GetPositiveInfinityValue(JSContext *cx); | |
2883 | extern __attribute__((visibility ("default"))) jsval | |
2884 | JS_GetEmptyStringValue(JSContext *cx); | |
2885 | extern __attribute__((visibility ("default"))) JSString * | |
2886 | JS_GetEmptyString(JSRuntime *rt); | |
2887 | extern __attribute__((visibility ("default"))) JSBool | |
2888 | JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format, | |
2889 | ...); | |
2890 | extern __attribute__((visibility ("default"))) JSBool | |
2891 | JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, | |
2892 | const char *format, va_list ap); | |
2893 | extern __attribute__((visibility ("default"))) JSBool | |
2894 | JS_AddArgumentFormatter(JSContext *cx, const char *format, | |
2895 | JSArgumentFormatter formatter); | |
2896 | extern __attribute__((visibility ("default"))) void | |
2897 | JS_RemoveArgumentFormatter(JSContext *cx, const char *format); | |
2898 | extern __attribute__((visibility ("default"))) JSBool | |
2899 | JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp); | |
2900 | extern __attribute__((visibility ("default"))) JSBool | |
2901 | JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp); | |
2902 | extern __attribute__((visibility ("default"))) JSFunction * | |
2903 | JS_ValueToFunction(JSContext *cx, jsval v); | |
2904 | extern __attribute__((visibility ("default"))) JSFunction * | |
2905 | JS_ValueToConstructor(JSContext *cx, jsval v); | |
2906 | extern __attribute__((visibility ("default"))) JSString * | |
2907 | JS_ValueToString(JSContext *cx, jsval v); | |
2908 | extern __attribute__((visibility ("default"))) JSString * | |
2909 | JS_ValueToSource(JSContext *cx, jsval v); | |
2910 | extern __attribute__((visibility ("default"))) JSBool | |
2911 | JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp); | |
2912 | extern __attribute__((visibility ("default"))) JSBool | |
2913 | JS_DoubleIsInt32(jsdouble d, jsint *ip); | |
2914 | extern __attribute__((visibility ("default"))) JSBool | |
2915 | JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip); | |
2916 | extern __attribute__((visibility ("default"))) JSBool | |
2917 | JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip); | |
2918 | extern __attribute__((visibility ("default"))) JSBool | |
2919 | JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip); | |
2920 | extern __attribute__((visibility ("default"))) JSBool | |
2921 | JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip); | |
2922 | extern __attribute__((visibility ("default"))) JSBool | |
2923 | JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp); | |
2924 | extern __attribute__((visibility ("default"))) JSType | |
2925 | JS_TypeOfValue(JSContext *cx, jsval v); | |
2926 | extern __attribute__((visibility ("default"))) const char * | |
2927 | JS_GetTypeName(JSContext *cx, JSType type); | |
2928 | extern __attribute__((visibility ("default"))) JSBool | |
2929 | JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal); | |
2930 | extern __attribute__((visibility ("default"))) JSBool | |
2931 | JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same); | |
2932 | extern __attribute__((visibility ("default"))) JSRuntime * | |
2933 | JS_Init(uint32 maxbytes); | |
2934 | extern __attribute__((visibility ("default"))) void | |
2935 | JS_Finish(JSRuntime *rt); | |
2936 | extern __attribute__((visibility ("default"))) void | |
2937 | JS_ShutDown(void); | |
2938 | __attribute__((visibility ("default"))) void * | |
2939 | JS_GetRuntimePrivate(JSRuntime *rt); | |
2940 | __attribute__((visibility ("default"))) void | |
2941 | JS_SetRuntimePrivate(JSRuntime *rt, void *data); | |
2942 | extern __attribute__((visibility ("default"))) void | |
2943 | JS_BeginRequest(JSContext *cx); | |
2944 | extern __attribute__((visibility ("default"))) void | |
2945 | JS_EndRequest(JSContext *cx); | |
2946 | extern __attribute__((visibility ("default"))) void | |
2947 | JS_YieldRequest(JSContext *cx); | |
2948 | extern __attribute__((visibility ("default"))) jsrefcount | |
2949 | JS_SuspendRequest(JSContext *cx); | |
2950 | extern __attribute__((visibility ("default"))) void | |
2951 | JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth); | |
2952 | extern __attribute__((visibility ("default"))) JSBool | |
2953 | JS_IsInRequest(JSContext *cx); | |
2954 | } | |
2955 | class JSAutoRequest { | |
2956 | public: | |
2957 | JSAutoRequest(JSContext *cx ) | |
2958 | : mContext(cx), mSaveDepth(0) { | |
2959 | do { } while (0); | |
2960 | JS_BeginRequest(mContext); | |
2961 | } | |
2962 | ~JSAutoRequest() { | |
2963 | JS_EndRequest(mContext); | |
2964 | } | |
2965 | void suspend() { | |
2966 | mSaveDepth = JS_SuspendRequest(mContext); | |
2967 | } | |
2968 | void resume() { | |
2969 | JS_ResumeRequest(mContext, mSaveDepth); | |
2970 | } | |
2971 | protected: | |
2972 | JSContext *mContext; | |
2973 | jsrefcount mSaveDepth; | |
2974 | ||
2975 | }; | |
2976 | class JSAutoSuspendRequest { | |
2977 | public: | |
2978 | JSAutoSuspendRequest(JSContext *cx ) | |
2979 | : mContext(cx), mSaveDepth(0) { | |
2980 | do { } while (0); | |
2981 | if (mContext) { | |
2982 | mSaveDepth = JS_SuspendRequest(mContext); | |
2983 | } | |
2984 | } | |
2985 | ~JSAutoSuspendRequest() { | |
2986 | resume(); | |
2987 | } | |
2988 | void resume() { | |
2989 | if (mContext) { | |
2990 | JS_ResumeRequest(mContext, mSaveDepth); | |
2991 | mContext = 0; | |
2992 | } | |
2993 | } | |
2994 | protected: | |
2995 | JSContext *mContext; | |
2996 | jsrefcount mSaveDepth; | |
2997 | ||
2998 | }; | |
2999 | class JSAutoCheckRequest { | |
3000 | public: | |
3001 | JSAutoCheckRequest(JSContext *cx ) { | |
3002 | do { } while (0); | |
3003 | } | |
3004 | ~JSAutoCheckRequest() { | |
3005 | } | |
3006 | private: | |
3007 | ||
3008 | }; | |
3009 | extern "C" { | |
3010 | extern __attribute__((visibility ("default"))) void | |
3011 | JS_Lock(JSRuntime *rt); | |
3012 | extern __attribute__((visibility ("default"))) void | |
3013 | JS_Unlock(JSRuntime *rt); | |
3014 | extern __attribute__((visibility ("default"))) JSContextCallback | |
3015 | JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback); | |
3016 | extern __attribute__((visibility ("default"))) JSContext * | |
3017 | JS_NewContext(JSRuntime *rt, size_t stackChunkSize); | |
3018 | extern __attribute__((visibility ("default"))) void | |
3019 | JS_DestroyContext(JSContext *cx); | |
3020 | extern __attribute__((visibility ("default"))) void | |
3021 | JS_DestroyContextNoGC(JSContext *cx); | |
3022 | extern __attribute__((visibility ("default"))) void | |
3023 | JS_DestroyContextMaybeGC(JSContext *cx); | |
3024 | extern __attribute__((visibility ("default"))) void * | |
3025 | JS_GetContextPrivate(JSContext *cx); | |
3026 | extern __attribute__((visibility ("default"))) void | |
3027 | JS_SetContextPrivate(JSContext *cx, void *data); | |
3028 | extern __attribute__((visibility ("default"))) JSRuntime * | |
3029 | JS_GetRuntime(JSContext *cx); | |
3030 | extern __attribute__((visibility ("default"))) JSContext * | |
3031 | JS_ContextIterator(JSRuntime *rt, JSContext **iterp); | |
3032 | extern __attribute__((visibility ("default"))) JSVersion | |
3033 | JS_GetVersion(JSContext *cx); | |
3034 | extern __attribute__((visibility ("default"))) JSVersion | |
3035 | JS_SetVersion(JSContext *cx, JSVersion version); | |
3036 | extern __attribute__((visibility ("default"))) const char * | |
3037 | JS_VersionToString(JSVersion version); | |
3038 | extern __attribute__((visibility ("default"))) JSVersion | |
3039 | JS_StringToVersion(const char *string); | |
3040 | extern __attribute__((visibility ("default"))) uint32 | |
3041 | JS_GetOptions(JSContext *cx); | |
3042 | extern __attribute__((visibility ("default"))) uint32 | |
3043 | JS_SetOptions(JSContext *cx, uint32 options); | |
3044 | extern __attribute__((visibility ("default"))) uint32 | |
3045 | JS_ToggleOptions(JSContext *cx, uint32 options); | |
3046 | extern __attribute__((visibility ("default"))) const char * | |
3047 | JS_GetImplementationVersion(void); | |
3048 | extern __attribute__((visibility ("default"))) JSCompartmentCallback | |
3049 | JS_SetCompartmentCallback(JSRuntime *rt, JSCompartmentCallback callback); | |
3050 | extern __attribute__((visibility ("default"))) JSWrapObjectCallback | |
3051 | JS_SetWrapObjectCallbacks(JSRuntime *rt, | |
3052 | JSWrapObjectCallback callback, | |
3053 | JSPreWrapCallback precallback); | |
3054 | extern __attribute__((visibility ("default"))) JSCrossCompartmentCall * | |
3055 | JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target); | |
3056 | extern __attribute__((visibility ("default"))) void | |
3057 | JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call); | |
3058 | extern __attribute__((visibility ("default"))) void * | |
3059 | JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data); | |
3060 | extern __attribute__((visibility ("default"))) void * | |
3061 | JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment); | |
3062 | extern __attribute__((visibility ("default"))) JSBool | |
3063 | JS_WrapObject(JSContext *cx, JSObject **objp); | |
3064 | extern __attribute__((visibility ("default"))) JSBool | |
3065 | JS_WrapValue(JSContext *cx, jsval *vp); | |
3066 | extern __attribute__((visibility ("default"))) JSObject * | |
3067 | JS_TransplantObject(JSContext *cx, JSObject *origobj, JSObject *target); | |
3068 | extern __attribute__((visibility ("default"))) JSObject * | |
3069 | js_TransplantObjectWithWrapper(JSContext *cx, | |
3070 | JSObject *origobj, | |
3071 | JSObject *origwrapper, | |
3072 | JSObject *targetobj, | |
3073 | JSObject *targetwrapper); | |
3074 | extern __attribute__((visibility ("default"))) JSObject * | |
3075 | js_TransplantObjectWithWrapper(JSContext *cx, | |
3076 | JSObject *origobj, | |
3077 | JSObject *origwrapper, | |
3078 | JSObject *targetobj, | |
3079 | JSObject *targetwrapper); | |
3080 | } | |
3081 | class __attribute__((visibility ("default"))) JSAutoEnterCompartment | |
3082 | { | |
3083 | JSCrossCompartmentCall *call; | |
3084 | public: | |
3085 | JSAutoEnterCompartment() : call(__null) {} | |
3086 | bool enter(JSContext *cx, JSObject *target); | |
3087 | void enterAndIgnoreErrors(JSContext *cx, JSObject *target); | |
3088 | bool entered() const { return call != __null; } | |
3089 | ~JSAutoEnterCompartment() { | |
3090 | if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1)) | |
3091 | JS_LeaveCrossCompartmentCall(call); | |
3092 | } | |
3093 | void swap(JSAutoEnterCompartment &other) { | |
3094 | JSCrossCompartmentCall *tmp = call; | |
3095 | call = other.call; | |
3096 | other.call = tmp; | |
3097 | } | |
3098 | }; | |
3099 | extern "C" { | |
3100 | extern __attribute__((visibility ("default"))) JSObject * | |
3101 | JS_GetGlobalObject(JSContext *cx); | |
3102 | extern __attribute__((visibility ("default"))) void | |
3103 | JS_SetGlobalObject(JSContext *cx, JSObject *obj); | |
3104 | extern __attribute__((visibility ("default"))) JSBool | |
3105 | JS_InitStandardClasses(JSContext *cx, JSObject *obj); | |
3106 | extern __attribute__((visibility ("default"))) JSBool | |
3107 | JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, | |
3108 | JSBool *resolved); | |
3109 | extern __attribute__((visibility ("default"))) JSBool | |
3110 | JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj); | |
3111 | extern __attribute__((visibility ("default"))) JSIdArray * | |
3112 | JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, | |
3113 | JSIdArray *ida); | |
3114 | extern __attribute__((visibility ("default"))) JSBool | |
3115 | JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | |
3116 | JSObject **objp); | |
3117 | extern __attribute__((visibility ("default"))) JSObject * | |
3118 | JS_GetScopeChain(JSContext *cx); | |
3119 | extern __attribute__((visibility ("default"))) JSObject * | |
3120 | JS_GetGlobalForObject(JSContext *cx, JSObject *obj); | |
3121 | extern __attribute__((visibility ("default"))) JSObject * | |
3122 | JS_GetGlobalForScopeChain(JSContext *cx); | |
3123 | extern __attribute__((visibility ("default"))) jsval | |
3124 | JS_ComputeThis(JSContext *cx, jsval *vp); | |
3125 | static inline jsval | |
3126 | JS_THIS(JSContext *cx, jsval *vp) | |
3127 | { | |
3128 | return JSVAL_IS_PRIMITIVE(vp[1]) ? JS_ComputeThis(cx, vp) : vp[1]; | |
3129 | } | |
3130 | extern __attribute__((visibility ("default"))) void * | |
3131 | JS_malloc(JSContext *cx, size_t nbytes); | |
3132 | extern __attribute__((visibility ("default"))) void * | |
3133 | JS_realloc(JSContext *cx, void *p, size_t nbytes); | |
3134 | extern __attribute__((visibility ("default"))) void | |
3135 | JS_free(JSContext *cx, void *p); | |
3136 | extern __attribute__((visibility ("default"))) void | |
3137 | JS_updateMallocCounter(JSContext *cx, size_t nbytes); | |
3138 | extern __attribute__((visibility ("default"))) char * | |
3139 | JS_strdup(JSContext *cx, const char *s); | |
3140 | extern __attribute__((visibility ("default"))) JSBool | |
3141 | JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); | |
3142 | extern __attribute__((visibility ("default"))) JSBool | |
3143 | JS_AddValueRoot(JSContext *cx, jsval *vp); | |
3144 | extern __attribute__((visibility ("default"))) JSBool | |
3145 | JS_AddStringRoot(JSContext *cx, JSString **rp); | |
3146 | extern __attribute__((visibility ("default"))) JSBool | |
3147 | JS_AddObjectRoot(JSContext *cx, JSObject **rp); | |
3148 | extern __attribute__((visibility ("default"))) JSBool | |
3149 | JS_AddGCThingRoot(JSContext *cx, void **rp); | |
3150 | extern __attribute__((visibility ("default"))) JSBool | |
3151 | JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name); | |
3152 | extern __attribute__((visibility ("default"))) JSBool | |
3153 | JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name); | |
3154 | extern __attribute__((visibility ("default"))) JSBool | |
3155 | JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name); | |
3156 | extern __attribute__((visibility ("default"))) JSBool | |
3157 | JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name); | |
3158 | extern __attribute__((visibility ("default"))) JSBool | |
3159 | JS_RemoveValueRoot(JSContext *cx, jsval *vp); | |
3160 | extern __attribute__((visibility ("default"))) JSBool | |
3161 | JS_RemoveStringRoot(JSContext *cx, JSString **rp); | |
3162 | extern __attribute__((visibility ("default"))) JSBool | |
3163 | JS_RemoveObjectRoot(JSContext *cx, JSObject **rp); | |
3164 | extern __attribute__((visibility ("default"))) JSBool | |
3165 | JS_RemoveGCThingRoot(JSContext *cx, void **rp); | |
3166 | extern __attribute__((visibility ("default"))) JSBool | |
3167 | js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name); | |
3168 | extern __attribute__((visibility ("default"))) JSBool | |
3169 | js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name); | |
3170 | extern __attribute__((visibility ("default"))) JSBool | |
3171 | js_RemoveRoot(JSRuntime *rt, void *rp); | |
3172 | } | |
3173 | namespace JS { | |
3174 | template<typename T> class AnchorPermitted; | |
3175 | template<> class AnchorPermitted<JSObject *> { }; | |
3176 | template<> class AnchorPermitted<const JSObject *> { }; | |
3177 | template<> class AnchorPermitted<JSFunction *> { }; | |
3178 | template<> class AnchorPermitted<const JSFunction *> { }; | |
3179 | template<> class AnchorPermitted<JSString *> { }; | |
3180 | template<> class AnchorPermitted<const JSString *> { }; | |
3181 | template<> class AnchorPermitted<jsval> { }; | |
3182 | template<typename T> | |
3183 | class Anchor: AnchorPermitted<T> { | |
3184 | public: | |
3185 | Anchor() { } | |
3186 | explicit Anchor(T t) { hold = t; } | |
3187 | inline ~Anchor(); | |
3188 | T &get() { return hold; } | |
3189 | void set(const T &t) { hold = t; } | |
3190 | void clear() { hold = 0; } | |
3191 | private: | |
3192 | T hold; | |
3193 | Anchor(const Anchor &); | |
3194 | const Anchor &operator=(const Anchor &); | |
3195 | }; | |
3196 | template<typename T> | |
3197 | inline Anchor<T>::~Anchor() { | |
3198 | asm volatile("":: "g" (hold) : "memory"); | |
3199 | } | |
3200 | } | |
3201 | extern "C" { | |
3202 | extern __attribute__((noinline)) __attribute__((visibility ("default"))) void | |
3203 | JS_AnchorPtr(void *p); | |
3204 | typedef enum JSGCRootType { | |
3205 | JS_GC_ROOT_VALUE_PTR, | |
3206 | JS_GC_ROOT_GCTHING_PTR | |
3207 | } JSGCRootType; | |
3208 | typedef intN | |
3209 | (* JSGCRootMapFun)(void *rp, JSGCRootType type, const char *name, void *data); | |
3210 | extern __attribute__((visibility ("default"))) uint32 | |
3211 | JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); | |
3212 | extern __attribute__((visibility ("default"))) JSBool | |
3213 | JS_LockGCThing(JSContext *cx, void *thing); | |
3214 | extern __attribute__((visibility ("default"))) JSBool | |
3215 | JS_LockGCThingRT(JSRuntime *rt, void *thing); | |
3216 | extern __attribute__((visibility ("default"))) JSBool | |
3217 | JS_UnlockGCThing(JSContext *cx, void *thing); | |
3218 | extern __attribute__((visibility ("default"))) JSBool | |
3219 | JS_UnlockGCThingRT(JSRuntime *rt, void *thing); | |
3220 | extern __attribute__((visibility ("default"))) void | |
3221 | JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data); | |
3222 | extern __attribute__((visibility ("default"))) void | |
3223 | JS_MarkGCThing(JSContext *cx, jsval v, const char *name, void *arg); | |
3224 | static __attribute__((always_inline)) inline JSBool | |
3225 | JSVAL_IS_TRACEABLE(jsval v) | |
3226 | { | |
3227 | jsval_layout l; | |
3228 | l.asBits = (v); | |
3229 | return JSVAL_IS_TRACEABLE_IMPL(l); | |
3230 | } | |
3231 | static __attribute__((always_inline)) inline void * | |
3232 | JSVAL_TO_TRACEABLE(jsval v) | |
3233 | { | |
3234 | return JSVAL_TO_GCTHING(v); | |
3235 | } | |
3236 | static __attribute__((always_inline)) inline uint32 | |
3237 | JSVAL_TRACE_KIND(jsval v) | |
3238 | { | |
3239 | jsval_layout l; | |
3240 | ((void) 0); | |
3241 | l.asBits = (v); | |
3242 | return JSVAL_TRACE_KIND_IMPL(l); | |
3243 | } | |
3244 | struct JSTracer { | |
3245 | JSContext *context; | |
3246 | JSTraceCallback callback; | |
3247 | JSTraceNamePrinter debugPrinter; | |
3248 | const void *debugPrintArg; | |
3249 | size_t debugPrintIndex; | |
3250 | }; | |
3251 | extern __attribute__((visibility ("default"))) void | |
3252 | JS_CallTracer(JSTracer *trc, void *thing, uint32 kind); | |
3253 | extern __attribute__((visibility ("default"))) void | |
3254 | JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind); | |
3255 | extern __attribute__((visibility ("default"))) void | |
3256 | JS_TraceRuntime(JSTracer *trc); | |
3257 | extern __attribute__((visibility ("default"))) void | |
3258 | JS_GC(JSContext *cx); | |
3259 | extern __attribute__((visibility ("default"))) void | |
3260 | JS_MaybeGC(JSContext *cx); | |
3261 | extern __attribute__((visibility ("default"))) JSGCCallback | |
3262 | JS_SetGCCallback(JSContext *cx, JSGCCallback cb); | |
3263 | extern __attribute__((visibility ("default"))) JSGCCallback | |
3264 | JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); | |
3265 | extern __attribute__((visibility ("default"))) JSBool | |
3266 | JS_IsGCMarkingTracer(JSTracer *trc); | |
3267 | extern __attribute__((visibility ("default"))) JSBool | |
3268 | JS_IsAboutToBeFinalized(JSContext *cx, void *thing); | |
3269 | typedef enum JSGCParamKey { | |
3270 | JSGC_MAX_BYTES = 0, | |
3271 | JSGC_MAX_MALLOC_BYTES = 1, | |
3272 | JSGC_STACKPOOL_LIFESPAN = 2, | |
3273 | JSGC_TRIGGER_FACTOR = 3, | |
3274 | JSGC_BYTES = 4, | |
3275 | JSGC_NUMBER = 5, | |
3276 | JSGC_MAX_CODE_CACHE_BYTES = 6, | |
3277 | JSGC_MODE = 7, | |
3278 | JSGC_UNUSED_CHUNKS = 8 | |
3279 | } JSGCParamKey; | |
3280 | typedef enum JSGCMode { | |
3281 | JSGC_MODE_GLOBAL = 0, | |
3282 | JSGC_MODE_COMPARTMENT = 1 | |
3283 | } JSGCMode; | |
3284 | extern __attribute__((visibility ("default"))) void | |
3285 | JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value); | |
3286 | extern __attribute__((visibility ("default"))) uint32 | |
3287 | JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key); | |
3288 | extern __attribute__((visibility ("default"))) void | |
3289 | JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32 value); | |
3290 | extern __attribute__((visibility ("default"))) uint32 | |
3291 | JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key); | |
3292 | extern __attribute__((visibility ("default"))) void | |
3293 | JS_FlushCaches(JSContext *cx); | |
3294 | extern __attribute__((visibility ("default"))) intN | |
3295 | JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer); | |
3296 | extern __attribute__((visibility ("default"))) intN | |
3297 | JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer); | |
3298 | extern __attribute__((visibility ("default"))) JSString * | |
3299 | JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type); | |
3300 | extern __attribute__((visibility ("default"))) intN | |
3301 | JS_GetExternalStringGCType(JSRuntime *rt, JSString *str); | |
3302 | extern __attribute__((visibility ("default"))) void | |
3303 | JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr); | |
3304 | extern __attribute__((visibility ("default"))) void | |
3305 | JS_SetNativeStackQuota(JSContext *cx, size_t stackSize); | |
3306 | extern __attribute__((visibility ("default"))) void | |
3307 | JS_SetScriptStackQuota(JSContext *cx, size_t quota); | |
3308 | typedef void (*JSClassInternal)(); | |
3309 | struct JSClass { | |
3310 | const char *name; | |
3311 | uint32 flags; | |
3312 | JSPropertyOp addProperty; | |
3313 | JSPropertyOp delProperty; | |
3314 | JSPropertyOp getProperty; | |
3315 | JSStrictPropertyOp setProperty; | |
3316 | JSEnumerateOp enumerate; | |
3317 | JSResolveOp resolve; | |
3318 | JSConvertOp convert; | |
3319 | JSFinalizeOp finalize; | |
3320 | JSClassInternal reserved0; | |
3321 | JSCheckAccessOp checkAccess; | |
3322 | JSNative call; | |
3323 | JSNative construct; | |
3324 | JSXDRObjectOp xdrObject; | |
3325 | JSHasInstanceOp hasInstance; | |
3326 | JSMarkOp mark; | |
3327 | JSClassInternal reserved1; | |
3328 | void *reserved[19]; | |
3329 | }; | |
3330 | struct JSIdArray { | |
3331 | jsint length; | |
3332 | jsid vector[1]; | |
3333 | }; | |
3334 | extern __attribute__((visibility ("default"))) void | |
3335 | JS_DestroyIdArray(JSContext *cx, JSIdArray *ida); | |
3336 | extern __attribute__((visibility ("default"))) JSBool | |
3337 | JS_ValueToId(JSContext *cx, jsval v, jsid *idp); | |
3338 | extern __attribute__((visibility ("default"))) JSBool | |
3339 | JS_IdToValue(JSContext *cx, jsid id, jsval *vp); | |
3340 | extern __attribute__((visibility ("default"))) JSBool | |
3341 | JS_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
3342 | extern __attribute__((visibility ("default"))) JSBool | |
3343 | JS_StrictPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); | |
3344 | extern __attribute__((visibility ("default"))) JSBool | |
3345 | JS_EnumerateStub(JSContext *cx, JSObject *obj); | |
3346 | extern __attribute__((visibility ("default"))) JSBool | |
3347 | JS_ResolveStub(JSContext *cx, JSObject *obj, jsid id); | |
3348 | extern __attribute__((visibility ("default"))) JSBool | |
3349 | JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp); | |
3350 | extern __attribute__((visibility ("default"))) void | |
3351 | JS_FinalizeStub(JSContext *cx, JSObject *obj); | |
3352 | struct JSConstDoubleSpec { | |
3353 | jsdouble dval; | |
3354 | const char *name; | |
3355 | uint8 flags; | |
3356 | uint8 spare[3]; | |
3357 | }; | |
3358 | struct JSPropertySpec { | |
3359 | const char *name; | |
3360 | int8 tinyid; | |
3361 | uint8 flags; | |
3362 | JSPropertyOp getter; | |
3363 | JSStrictPropertyOp setter; | |
3364 | }; | |
3365 | struct JSFunctionSpec { | |
3366 | const char *name; | |
3367 | JSNative call; | |
3368 | uint16 nargs; | |
3369 | uint16 flags; | |
3370 | }; | |
3371 | extern __attribute__((visibility ("default"))) JSObject * | |
3372 | JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, | |
3373 | JSClass *clasp, JSNative constructor, uintN nargs, | |
3374 | JSPropertySpec *ps, JSFunctionSpec *fs, | |
3375 | JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | |
3376 | extern __attribute__((visibility ("default"))) JSClass * | |
3377 | JS_GetClass(JSContext *cx, JSObject *obj); | |
3378 | extern __attribute__((visibility ("default"))) JSBool | |
3379 | JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv); | |
3380 | extern __attribute__((visibility ("default"))) JSBool | |
3381 | JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); | |
3382 | extern __attribute__((visibility ("default"))) void * | |
3383 | JS_GetPrivate(JSContext *cx, JSObject *obj); | |
3384 | extern __attribute__((visibility ("default"))) JSBool | |
3385 | JS_SetPrivate(JSContext *cx, JSObject *obj, void *data); | |
3386 | extern __attribute__((visibility ("default"))) void * | |
3387 | JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, | |
3388 | jsval *argv); | |
3389 | extern __attribute__((visibility ("default"))) JSObject * | |
3390 | JS_GetPrototype(JSContext *cx, JSObject *obj); | |
3391 | extern __attribute__((visibility ("default"))) JSBool | |
3392 | JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto); | |
3393 | extern __attribute__((visibility ("default"))) JSObject * | |
3394 | JS_GetParent(JSContext *cx, JSObject *obj); | |
3395 | extern __attribute__((visibility ("default"))) JSBool | |
3396 | JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent); | |
3397 | extern __attribute__((visibility ("default"))) JSObject * | |
3398 | JS_GetConstructor(JSContext *cx, JSObject *proto); | |
3399 | extern __attribute__((visibility ("default"))) JSBool | |
3400 | JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); | |
3401 | extern __attribute__((visibility ("default"))) JSObject * | |
3402 | JS_NewGlobalObject(JSContext *cx, JSClass *clasp); | |
3403 | extern __attribute__((visibility ("default"))) JSObject * | |
3404 | JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals); | |
3405 | extern __attribute__((visibility ("default"))) JSObject * | |
3406 | JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); | |
3407 | extern __attribute__((visibility ("default"))) JSBool | |
3408 | JS_IsExtensible(JSObject *obj); | |
3409 | extern __attribute__((visibility ("default"))) JSObject * | |
3410 | JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, | |
3411 | JSObject *parent); | |
3412 | extern __attribute__((visibility ("default"))) JSBool | |
3413 | JS_DeepFreezeObject(JSContext *cx, JSObject *obj); | |
3414 | extern __attribute__((visibility ("default"))) JSBool | |
3415 | JS_FreezeObject(JSContext *cx, JSObject *obj); | |
3416 | extern __attribute__((visibility ("default"))) JSObject * | |
3417 | JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, | |
3418 | JSObject *parent); | |
3419 | extern __attribute__((visibility ("default"))) JSObject * | |
3420 | JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto, | |
3421 | JSObject *parent, uintN argc, jsval *argv); | |
3422 | extern __attribute__((visibility ("default"))) JSObject * | |
3423 | JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv); | |
3424 | extern __attribute__((visibility ("default"))) JSObject * | |
3425 | JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp, | |
3426 | JSObject *proto, uintN attrs); | |
3427 | extern __attribute__((visibility ("default"))) JSBool | |
3428 | JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds); | |
3429 | extern __attribute__((visibility ("default"))) JSBool | |
3430 | JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps); | |
3431 | extern __attribute__((visibility ("default"))) JSBool | |
3432 | JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, | |
3433 | JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); | |
3434 | extern __attribute__((visibility ("default"))) JSBool | |
3435 | JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value, | |
3436 | JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); | |
3437 | extern __attribute__((visibility ("default"))) JSBool | |
3438 | JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp); | |
3439 | extern __attribute__((visibility ("default"))) JSBool | |
3440 | JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, | |
3441 | uintN *attrsp, JSBool *foundp); | |
3442 | extern __attribute__((visibility ("default"))) JSBool | |
3443 | JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, | |
3444 | const char *name, | |
3445 | uintN *attrsp, JSBool *foundp, | |
3446 | JSPropertyOp *getterp, | |
3447 | JSStrictPropertyOp *setterp); | |
3448 | extern __attribute__((visibility ("default"))) JSBool | |
3449 | JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *obj, | |
3450 | jsid id, | |
3451 | uintN *attrsp, JSBool *foundp, | |
3452 | JSPropertyOp *getterp, | |
3453 | JSStrictPropertyOp *setterp); | |
3454 | extern __attribute__((visibility ("default"))) JSBool | |
3455 | JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, | |
3456 | uintN attrs, JSBool *foundp); | |
3457 | extern __attribute__((visibility ("default"))) JSBool | |
3458 | JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, | |
3459 | int8 tinyid, jsval value, | |
3460 | JSPropertyOp getter, JSStrictPropertyOp setter, | |
3461 | uintN attrs); | |
3462 | extern __attribute__((visibility ("default"))) JSBool | |
3463 | JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, | |
3464 | const char *alias); | |
3465 | extern __attribute__((visibility ("default"))) JSBool | |
3466 | JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, | |
3467 | JSBool *foundp); | |
3468 | extern __attribute__((visibility ("default"))) JSBool | |
3469 | JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id, | |
3470 | JSBool *foundp); | |
3471 | extern __attribute__((visibility ("default"))) JSBool | |
3472 | JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp); | |
3473 | extern __attribute__((visibility ("default"))) JSBool | |
3474 | JS_HasPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp); | |
3475 | extern __attribute__((visibility ("default"))) JSBool | |
3476 | JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); | |
3477 | extern __attribute__((visibility ("default"))) JSBool | |
3478 | JS_LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
3479 | extern __attribute__((visibility ("default"))) JSBool | |
3480 | JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, | |
3481 | uintN flags, jsval *vp); | |
3482 | extern __attribute__((visibility ("default"))) JSBool | |
3483 | JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id, | |
3484 | uintN flags, JSObject **objp, jsval *vp); | |
3485 | struct JSPropertyDescriptor { | |
3486 | JSObject *obj; | |
3487 | uintN attrs; | |
3488 | JSPropertyOp getter; | |
3489 | JSStrictPropertyOp setter; | |
3490 | jsval value; | |
3491 | uintN shortid; | |
3492 | }; | |
3493 | extern __attribute__((visibility ("default"))) JSBool | |
3494 | JS_GetPropertyDescriptorById(JSContext *cx, JSObject *obj, jsid id, uintN flags, | |
3495 | JSPropertyDescriptor *desc); | |
3496 | extern __attribute__((visibility ("default"))) JSBool | |
3497 | JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
3498 | extern __attribute__((visibility ("default"))) JSBool | |
3499 | JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); | |
3500 | extern __attribute__((visibility ("default"))) JSBool | |
3501 | JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp); | |
3502 | extern __attribute__((visibility ("default"))) JSBool | |
3503 | JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
3504 | extern __attribute__((visibility ("default"))) JSBool | |
3505 | JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp); | |
3506 | extern __attribute__((visibility ("default"))) JSBool | |
3507 | JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |
3508 | jsval *vp); | |
3509 | extern __attribute__((visibility ("default"))) JSBool | |
3510 | JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, | |
3511 | jsval *vp); | |
3512 | extern __attribute__((visibility ("default"))) JSBool | |
3513 | JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); | |
3514 | extern __attribute__((visibility ("default"))) JSBool | |
3515 | JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
3516 | extern __attribute__((visibility ("default"))) JSBool | |
3517 | JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name); | |
3518 | extern __attribute__((visibility ("default"))) JSBool | |
3519 | JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, | |
3520 | jsval *rval); | |
3521 | extern __attribute__((visibility ("default"))) JSBool | |
3522 | JS_DeletePropertyById(JSContext *cx, JSObject *obj, jsid id); | |
3523 | extern __attribute__((visibility ("default"))) JSBool | |
3524 | JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval); | |
3525 | extern __attribute__((visibility ("default"))) JSBool | |
3526 | JS_DefineUCProperty(JSContext *cx, JSObject *obj, | |
3527 | const jschar *name, size_t namelen, jsval value, | |
3528 | JSPropertyOp getter, JSStrictPropertyOp setter, | |
3529 | uintN attrs); | |
3530 | extern __attribute__((visibility ("default"))) JSBool | |
3531 | JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, | |
3532 | const jschar *name, size_t namelen, | |
3533 | uintN *attrsp, JSBool *foundp); | |
3534 | extern __attribute__((visibility ("default"))) JSBool | |
3535 | JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, | |
3536 | const jschar *name, size_t namelen, | |
3537 | uintN *attrsp, JSBool *foundp, | |
3538 | JSPropertyOp *getterp, | |
3539 | JSStrictPropertyOp *setterp); | |
3540 | extern __attribute__((visibility ("default"))) JSBool | |
3541 | JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, | |
3542 | const jschar *name, size_t namelen, | |
3543 | uintN attrs, JSBool *foundp); | |
3544 | extern __attribute__((visibility ("default"))) JSBool | |
3545 | JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, | |
3546 | const jschar *name, size_t namelen, | |
3547 | int8 tinyid, jsval value, | |
3548 | JSPropertyOp getter, JSStrictPropertyOp setter, | |
3549 | uintN attrs); | |
3550 | extern __attribute__((visibility ("default"))) JSBool | |
3551 | JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, | |
3552 | size_t namelen, JSBool *foundp); | |
3553 | extern __attribute__((visibility ("default"))) JSBool | |
3554 | JS_HasUCProperty(JSContext *cx, JSObject *obj, | |
3555 | const jschar *name, size_t namelen, | |
3556 | JSBool *vp); | |
3557 | extern __attribute__((visibility ("default"))) JSBool | |
3558 | JS_LookupUCProperty(JSContext *cx, JSObject *obj, | |
3559 | const jschar *name, size_t namelen, | |
3560 | jsval *vp); | |
3561 | extern __attribute__((visibility ("default"))) JSBool | |
3562 | JS_GetUCProperty(JSContext *cx, JSObject *obj, | |
3563 | const jschar *name, size_t namelen, | |
3564 | jsval *vp); | |
3565 | extern __attribute__((visibility ("default"))) JSBool | |
3566 | JS_SetUCProperty(JSContext *cx, JSObject *obj, | |
3567 | const jschar *name, size_t namelen, | |
3568 | jsval *vp); | |
3569 | extern __attribute__((visibility ("default"))) JSBool | |
3570 | JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, | |
3571 | const jschar *name, size_t namelen, | |
3572 | jsval *rval); | |
3573 | extern __attribute__((visibility ("default"))) JSObject * | |
3574 | JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector); | |
3575 | extern __attribute__((visibility ("default"))) JSBool | |
3576 | JS_IsArrayObject(JSContext *cx, JSObject *obj); | |
3577 | extern __attribute__((visibility ("default"))) JSBool | |
3578 | JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); | |
3579 | extern __attribute__((visibility ("default"))) JSBool | |
3580 | JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length); | |
3581 | extern __attribute__((visibility ("default"))) JSBool | |
3582 | JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); | |
3583 | extern __attribute__((visibility ("default"))) JSBool | |
3584 | JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, | |
3585 | JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); | |
3586 | extern __attribute__((visibility ("default"))) JSBool | |
3587 | JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias); | |
3588 | extern __attribute__((visibility ("default"))) JSBool | |
3589 | JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, | |
3590 | JSBool *foundp); | |
3591 | extern __attribute__((visibility ("default"))) JSBool | |
3592 | JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp); | |
3593 | extern __attribute__((visibility ("default"))) JSBool | |
3594 | JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |
3595 | extern __attribute__((visibility ("default"))) JSBool | |
3596 | JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |
3597 | extern __attribute__((visibility ("default"))) JSBool | |
3598 | JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |
3599 | extern __attribute__((visibility ("default"))) JSBool | |
3600 | JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index); | |
3601 | extern __attribute__((visibility ("default"))) JSBool | |
3602 | JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval); | |
3603 | extern __attribute__((visibility ("default"))) void | |
3604 | JS_ClearScope(JSContext *cx, JSObject *obj); | |
3605 | extern __attribute__((visibility ("default"))) JSIdArray * | |
3606 | JS_Enumerate(JSContext *cx, JSObject *obj); | |
3607 | extern __attribute__((visibility ("default"))) JSObject * | |
3608 | JS_NewPropertyIterator(JSContext *cx, JSObject *obj); | |
3609 | extern __attribute__((visibility ("default"))) JSBool | |
3610 | JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp); | |
3611 | extern __attribute__((visibility ("default"))) JSBool | |
3612 | JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | |
3613 | jsval *vp, uintN *attrsp); | |
3614 | extern __attribute__((visibility ("default"))) JSBool | |
3615 | JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); | |
3616 | extern __attribute__((visibility ("default"))) JSBool | |
3617 | JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v); | |
3618 | struct JSPrincipals { | |
3619 | char *codebase; | |
3620 | void * (* getPrincipalArray)(JSContext *cx, JSPrincipals *); | |
3621 | JSBool (* globalPrivilegesEnabled)(JSContext *cx, JSPrincipals *); | |
3622 | jsrefcount refcount; | |
3623 | void (* destroy)(JSContext *cx, JSPrincipals *); | |
3624 | JSBool (* subsume)(JSPrincipals *, JSPrincipals *); | |
3625 | }; | |
3626 | extern __attribute__((visibility ("default"))) jsrefcount | |
3627 | JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals); | |
3628 | extern __attribute__((visibility ("default"))) jsrefcount | |
3629 | JS_DropPrincipals(JSContext *cx, JSPrincipals *principals); | |
3630 | struct JSSecurityCallbacks { | |
3631 | JSCheckAccessOp checkObjectAccess; | |
3632 | JSPrincipalsTranscoder principalsTranscoder; | |
3633 | JSObjectPrincipalsFinder findObjectPrincipals; | |
3634 | JSCSPEvalChecker contentSecurityPolicyAllows; | |
3635 | }; | |
3636 | extern __attribute__((visibility ("default"))) JSSecurityCallbacks * | |
3637 | JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks); | |
3638 | extern __attribute__((visibility ("default"))) JSSecurityCallbacks * | |
3639 | JS_GetRuntimeSecurityCallbacks(JSRuntime *rt); | |
3640 | extern __attribute__((visibility ("default"))) JSSecurityCallbacks * | |
3641 | JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks); | |
3642 | extern __attribute__((visibility ("default"))) JSSecurityCallbacks * | |
3643 | JS_GetSecurityCallbacks(JSContext *cx); | |
3644 | extern __attribute__((visibility ("default"))) JSFunction * | |
3645 | JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags, | |
3646 | JSObject *parent, const char *name); | |
3647 | extern __attribute__((visibility ("default"))) JSFunction * | |
3648 | JS_NewFunctionById(JSContext *cx, JSNative call, uintN nargs, uintN flags, | |
3649 | JSObject *parent, jsid id); | |
3650 | extern __attribute__((visibility ("default"))) JSObject * | |
3651 | JS_GetFunctionObject(JSFunction *fun); | |
3652 | extern __attribute__((visibility ("default"))) JSString * | |
3653 | JS_GetFunctionId(JSFunction *fun); | |
3654 | extern __attribute__((visibility ("default"))) uintN | |
3655 | JS_GetFunctionFlags(JSFunction *fun); | |
3656 | extern __attribute__((visibility ("default"))) uint16 | |
3657 | JS_GetFunctionArity(JSFunction *fun); | |
3658 | extern __attribute__((visibility ("default"))) JSBool | |
3659 | JS_ObjectIsFunction(JSContext *cx, JSObject *obj); | |
3660 | extern __attribute__((visibility ("default"))) JSBool | |
3661 | JS_ObjectIsCallable(JSContext *cx, JSObject *obj); | |
3662 | extern __attribute__((visibility ("default"))) JSBool | |
3663 | JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs); | |
3664 | extern __attribute__((visibility ("default"))) JSFunction * | |
3665 | JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call, | |
3666 | uintN nargs, uintN attrs); | |
3667 | extern __attribute__((visibility ("default"))) JSFunction * | |
3668 | JS_DefineUCFunction(JSContext *cx, JSObject *obj, | |
3669 | const jschar *name, size_t namelen, JSNative call, | |
3670 | uintN nargs, uintN attrs); | |
3671 | extern __attribute__((visibility ("default"))) JSFunction * | |
3672 | JS_DefineFunctionById(JSContext *cx, JSObject *obj, jsid id, JSNative call, | |
3673 | uintN nargs, uintN attrs); | |
3674 | extern __attribute__((visibility ("default"))) JSObject * | |
3675 | JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); | |
3676 | extern __attribute__((visibility ("default"))) JSBool | |
3677 | JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, | |
3678 | const char *bytes, size_t length); | |
3679 | extern __attribute__((visibility ("default"))) JSObject * | |
3680 | JS_CompileScript(JSContext *cx, JSObject *obj, | |
3681 | const char *bytes, size_t length, | |
3682 | const char *filename, uintN lineno); | |
3683 | extern __attribute__((visibility ("default"))) JSObject * | |
3684 | JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj, | |
3685 | JSPrincipals *principals, | |
3686 | const char *bytes, size_t length, | |
3687 | const char *filename, uintN lineno); | |
3688 | extern __attribute__((visibility ("default"))) JSObject * | |
3689 | JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3690 | JSPrincipals *principals, | |
3691 | const char *bytes, size_t length, | |
3692 | const char *filename, uintN lineno, | |
3693 | JSVersion version); | |
3694 | extern __attribute__((visibility ("default"))) JSObject * | |
3695 | JS_CompileUCScript(JSContext *cx, JSObject *obj, | |
3696 | const jschar *chars, size_t length, | |
3697 | const char *filename, uintN lineno); | |
3698 | extern __attribute__((visibility ("default"))) JSObject * | |
3699 | JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, | |
3700 | JSPrincipals *principals, | |
3701 | const jschar *chars, size_t length, | |
3702 | const char *filename, uintN lineno); | |
3703 | extern __attribute__((visibility ("default"))) JSObject * | |
3704 | JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3705 | JSPrincipals *principals, | |
3706 | const jschar *chars, size_t length, | |
3707 | const char *filename, uintN lineno, | |
3708 | JSVersion version); | |
3709 | extern __attribute__((visibility ("default"))) JSObject * | |
3710 | JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename); | |
3711 | extern __attribute__((visibility ("default"))) JSObject * | |
3712 | JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, | |
3713 | FILE *fh); | |
3714 | extern __attribute__((visibility ("default"))) JSObject * | |
3715 | JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, | |
3716 | const char *filename, FILE *fh, | |
3717 | JSPrincipals *principals); | |
3718 | extern __attribute__((visibility ("default"))) JSObject * | |
3719 | JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3720 | const char *filename, FILE *fh, | |
3721 | JSPrincipals *principals, | |
3722 | JSVersion version); | |
3723 | extern __attribute__((visibility ("default"))) JSFunction * | |
3724 | JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name, | |
3725 | uintN nargs, const char **argnames, | |
3726 | const char *bytes, size_t length, | |
3727 | const char *filename, uintN lineno); | |
3728 | extern __attribute__((visibility ("default"))) JSFunction * | |
3729 | JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj, | |
3730 | JSPrincipals *principals, const char *name, | |
3731 | uintN nargs, const char **argnames, | |
3732 | const char *bytes, size_t length, | |
3733 | const char *filename, uintN lineno); | |
3734 | extern __attribute__((visibility ("default"))) JSFunction * | |
3735 | JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name, | |
3736 | uintN nargs, const char **argnames, | |
3737 | const jschar *chars, size_t length, | |
3738 | const char *filename, uintN lineno); | |
3739 | extern __attribute__((visibility ("default"))) JSFunction * | |
3740 | JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, | |
3741 | JSPrincipals *principals, const char *name, | |
3742 | uintN nargs, const char **argnames, | |
3743 | const jschar *chars, size_t length, | |
3744 | const char *filename, uintN lineno); | |
3745 | extern __attribute__((visibility ("default"))) JSFunction * | |
3746 | JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3747 | JSPrincipals *principals, const char *name, | |
3748 | uintN nargs, const char **argnames, | |
3749 | const jschar *chars, size_t length, | |
3750 | const char *filename, uintN lineno, | |
3751 | JSVersion version); | |
3752 | extern __attribute__((visibility ("default"))) JSString * | |
3753 | JS_DecompileScriptObject(JSContext *cx, JSObject *scriptObj, const char *name, uintN indent); | |
3754 | extern __attribute__((visibility ("default"))) JSString * | |
3755 | JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent); | |
3756 | extern __attribute__((visibility ("default"))) JSString * | |
3757 | JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent); | |
3758 | extern __attribute__((visibility ("default"))) JSBool | |
3759 | JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval); | |
3760 | extern __attribute__((visibility ("default"))) JSBool | |
3761 | JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval, | |
3762 | JSVersion version); | |
3763 | typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart; | |
3764 | extern __attribute__((visibility ("default"))) JSBool | |
3765 | JS_EvaluateScript(JSContext *cx, JSObject *obj, | |
3766 | const char *bytes, uintN length, | |
3767 | const char *filename, uintN lineno, | |
3768 | jsval *rval); | |
3769 | extern __attribute__((visibility ("default"))) JSBool | |
3770 | JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj, | |
3771 | JSPrincipals *principals, | |
3772 | const char *bytes, uintN length, | |
3773 | const char *filename, uintN lineno, | |
3774 | jsval *rval); | |
3775 | extern __attribute__((visibility ("default"))) JSBool | |
3776 | JS_EvaluateScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3777 | JSPrincipals *principals, | |
3778 | const char *bytes, uintN length, | |
3779 | const char *filename, uintN lineno, | |
3780 | jsval *rval, JSVersion version); | |
3781 | extern __attribute__((visibility ("default"))) JSBool | |
3782 | JS_EvaluateUCScript(JSContext *cx, JSObject *obj, | |
3783 | const jschar *chars, uintN length, | |
3784 | const char *filename, uintN lineno, | |
3785 | jsval *rval); | |
3786 | extern __attribute__((visibility ("default"))) JSBool | |
3787 | JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, | |
3788 | JSPrincipals *principals, | |
3789 | const jschar *chars, uintN length, | |
3790 | const char *filename, uintN lineno, | |
3791 | jsval *rval, JSVersion version); | |
3792 | extern __attribute__((visibility ("default"))) JSBool | |
3793 | JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj, | |
3794 | JSPrincipals *principals, | |
3795 | const jschar *chars, uintN length, | |
3796 | const char *filename, uintN lineno, | |
3797 | jsval *rval); | |
3798 | extern __attribute__((visibility ("default"))) JSBool | |
3799 | JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, | |
3800 | jsval *argv, jsval *rval); | |
3801 | extern __attribute__((visibility ("default"))) JSBool | |
3802 | JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, | |
3803 | jsval *argv, jsval *rval); | |
3804 | extern __attribute__((visibility ("default"))) JSBool | |
3805 | JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, | |
3806 | jsval *argv, jsval *rval); | |
3807 | } | |
3808 | namespace JS { | |
3809 | static inline | |
3810 | bool | |
3811 | Call(JSContext *cx, JSObject *thisObj, JSFunction *fun, uintN argc, jsval *argv, jsval *rval) { | |
3812 | return !!JS_CallFunction(cx, thisObj, fun, argc, argv, rval); | |
3813 | } | |
3814 | static inline | |
3815 | bool | |
3816 | Call(JSContext *cx, JSObject *thisObj, const char *name, uintN argc, jsval *argv, jsval *rval) { | |
3817 | return !!JS_CallFunctionName(cx, thisObj, name, argc, argv, rval); | |
3818 | } | |
3819 | static inline | |
3820 | bool | |
3821 | Call(JSContext *cx, JSObject *thisObj, jsval fun, uintN argc, jsval *argv, jsval *rval) { | |
3822 | return !!JS_CallFunctionValue(cx, thisObj, fun, argc, argv, rval); | |
3823 | } | |
3824 | extern __attribute__((visibility ("default"))) bool | |
3825 | Call(JSContext *cx, jsval thisv, jsval fun, uintN argc, jsval *argv, jsval *rval); | |
3826 | static inline | |
3827 | bool | |
3828 | Call(JSContext *cx, jsval thisv, JSObject *funObj, uintN argc, jsval *argv, jsval *rval) { | |
3829 | return Call(cx, thisv, OBJECT_TO_JSVAL(funObj), argc, argv, rval); | |
3830 | } | |
3831 | } | |
3832 | extern "C" { | |
3833 | extern __attribute__((visibility ("default"))) JSOperationCallback | |
3834 | JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback); | |
3835 | extern __attribute__((visibility ("default"))) JSOperationCallback | |
3836 | JS_GetOperationCallback(JSContext *cx); | |
3837 | extern __attribute__((visibility ("default"))) void | |
3838 | JS_TriggerOperationCallback(JSContext *cx); | |
3839 | extern __attribute__((visibility ("default"))) void | |
3840 | JS_TriggerAllOperationCallbacks(JSRuntime *rt); | |
3841 | extern __attribute__((visibility ("default"))) JSBool | |
3842 | JS_IsRunning(JSContext *cx); | |
3843 | extern __attribute__((visibility ("default"))) JSStackFrame * | |
3844 | JS_SaveFrameChain(JSContext *cx); | |
3845 | extern __attribute__((visibility ("default"))) void | |
3846 | JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp); | |
3847 | extern __attribute__((visibility ("default"))) JSString * | |
3848 | JS_NewStringCopyN(JSContext *cx, const char *s, size_t n); | |
3849 | extern __attribute__((visibility ("default"))) JSString * | |
3850 | JS_NewStringCopyZ(JSContext *cx, const char *s); | |
3851 | extern __attribute__((visibility ("default"))) JSString * | |
3852 | JS_InternJSString(JSContext *cx, JSString *str); | |
3853 | extern __attribute__((visibility ("default"))) JSString * | |
3854 | JS_InternString(JSContext *cx, const char *s); | |
3855 | extern __attribute__((visibility ("default"))) JSString * | |
3856 | JS_NewUCString(JSContext *cx, jschar *chars, size_t length); | |
3857 | extern __attribute__((visibility ("default"))) JSString * | |
3858 | JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n); | |
3859 | extern __attribute__((visibility ("default"))) JSString * | |
3860 | JS_NewUCStringCopyZ(JSContext *cx, const jschar *s); | |
3861 | extern __attribute__((visibility ("default"))) JSString * | |
3862 | JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length); | |
3863 | extern __attribute__((visibility ("default"))) JSString * | |
3864 | JS_InternUCString(JSContext *cx, const jschar *s); | |
3865 | extern __attribute__((visibility ("default"))) JSBool | |
3866 | JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result); | |
3867 | extern __attribute__((visibility ("default"))) JSBool | |
3868 | JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, JSBool *match); | |
3869 | extern __attribute__((visibility ("default"))) size_t | |
3870 | JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote); | |
3871 | extern __attribute__((visibility ("default"))) JSBool | |
3872 | JS_FileEscapedString(FILE *fp, JSString *str, char quote); | |
3873 | extern __attribute__((visibility ("default"))) size_t | |
3874 | JS_GetStringLength(JSString *str); | |
3875 | extern __attribute__((visibility ("default"))) const jschar * | |
3876 | JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length); | |
3877 | extern __attribute__((visibility ("default"))) const jschar * | |
3878 | JS_GetInternedStringChars(JSString *str); | |
3879 | extern __attribute__((visibility ("default"))) const jschar * | |
3880 | JS_GetInternedStringCharsAndLength(JSString *str, size_t *length); | |
3881 | extern __attribute__((visibility ("default"))) const jschar * | |
3882 | JS_GetStringCharsZ(JSContext *cx, JSString *str); | |
3883 | extern __attribute__((visibility ("default"))) const jschar * | |
3884 | JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length); | |
3885 | extern __attribute__((visibility ("default"))) JSFlatString * | |
3886 | JS_FlattenString(JSContext *cx, JSString *str); | |
3887 | extern __attribute__((visibility ("default"))) const jschar * | |
3888 | JS_GetFlatStringChars(JSFlatString *str); | |
3889 | static __attribute__((always_inline)) inline JSFlatString * | |
3890 | JSID_TO_FLAT_STRING(jsid id) | |
3891 | { | |
3892 | ((void) 0); | |
3893 | return (JSFlatString *)((id)); | |
3894 | } | |
3895 | static __attribute__((always_inline)) inline JSFlatString * | |
3896 | JS_ASSERT_STRING_IS_FLAT(JSString *str) | |
3897 | { | |
3898 | ((void) 0); | |
3899 | return (JSFlatString *)str; | |
3900 | } | |
3901 | static __attribute__((always_inline)) inline JSString * | |
3902 | JS_FORGET_STRING_FLATNESS(JSFlatString *fstr) | |
3903 | { | |
3904 | return (JSString *)fstr; | |
3905 | } | |
3906 | extern __attribute__((visibility ("default"))) JSBool | |
3907 | JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes); | |
3908 | extern __attribute__((visibility ("default"))) size_t | |
3909 | JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote); | |
3910 | extern __attribute__((visibility ("default"))) JSString * | |
3911 | JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length); | |
3912 | extern __attribute__((visibility ("default"))) JSString * | |
3913 | JS_NewDependentString(JSContext *cx, JSString *str, size_t start, | |
3914 | size_t length); | |
3915 | extern __attribute__((visibility ("default"))) JSString * | |
3916 | JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right); | |
3917 | extern __attribute__((visibility ("default"))) const jschar * | |
3918 | JS_UndependString(JSContext *cx, JSString *str); | |
3919 | extern __attribute__((visibility ("default"))) JSBool | |
3920 | JS_MakeStringImmutable(JSContext *cx, JSString *str); | |
3921 | __attribute__((visibility ("default"))) JSBool | |
3922 | JS_CStringsAreUTF8(void); | |
3923 | __attribute__((visibility ("default"))) void | |
3924 | JS_SetCStringsAreUTF8(void); | |
3925 | __attribute__((visibility ("default"))) JSBool | |
3926 | JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst, | |
3927 | size_t *dstlenp); | |
3928 | __attribute__((visibility ("default"))) JSBool | |
3929 | JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, | |
3930 | size_t *dstlenp); | |
3931 | __attribute__((visibility ("default"))) char * | |
3932 | JS_EncodeString(JSContext *cx, JSString *str); | |
3933 | __attribute__((visibility ("default"))) size_t | |
3934 | JS_GetStringEncodingLength(JSContext *cx, JSString *str); | |
3935 | __attribute__((visibility ("default"))) size_t | |
3936 | JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length); | |
3937 | class JSAutoByteString { | |
3938 | public: | |
3939 | JSAutoByteString(JSContext *cx, JSString *str ) | |
3940 | : mBytes(JS_EncodeString(cx, str)) { | |
3941 | ((void) 0); | |
3942 | do { } while (0); | |
3943 | } | |
3944 | JSAutoByteString() | |
3945 | : mBytes(__null) { | |
3946 | do { } while (0); | |
3947 | } | |
3948 | ~JSAutoByteString() { | |
3949 | js_free(mBytes); | |
3950 | } | |
3951 | void initBytes(char *bytes) { | |
3952 | ((void) 0); | |
3953 | mBytes = bytes; | |
3954 | } | |
3955 | char *encode(JSContext *cx, JSString *str) { | |
3956 | ((void) 0); | |
3957 | ((void) 0); | |
3958 | mBytes = JS_EncodeString(cx, str); | |
3959 | return mBytes; | |
3960 | } | |
3961 | void clear() { | |
3962 | js_free(mBytes); | |
3963 | mBytes = __null; | |
3964 | } | |
3965 | char *ptr() const { | |
3966 | return mBytes; | |
3967 | } | |
3968 | bool operator!() const { | |
3969 | return !mBytes; | |
3970 | } | |
3971 | private: | |
3972 | char *mBytes; | |
3973 | ||
3974 | JSAutoByteString(const JSAutoByteString &another); | |
3975 | JSAutoByteString &operator=(const JSAutoByteString &another); | |
3976 | }; | |
3977 | typedef JSBool (* JSONWriteCallback)(const jschar *buf, uint32 len, void *data); | |
3978 | __attribute__((visibility ("default"))) JSBool | |
3979 | JS_Stringify(JSContext *cx, jsval *vp, JSObject *replacer, jsval space, | |
3980 | JSONWriteCallback callback, void *data); | |
3981 | __attribute__((visibility ("default"))) JSBool | |
3982 | JS_TryJSON(JSContext *cx, jsval *vp); | |
3983 | __attribute__((visibility ("default"))) JSONParser * | |
3984 | JS_BeginJSONParse(JSContext *cx, jsval *vp); | |
3985 | __attribute__((visibility ("default"))) JSBool | |
3986 | JS_ConsumeJSONText(JSContext *cx, JSONParser *jp, const jschar *data, uint32 len); | |
3987 | __attribute__((visibility ("default"))) JSBool | |
3988 | JS_FinishJSONParse(JSContext *cx, JSONParser *jp, jsval reviver); | |
3989 | struct JSStructuredCloneCallbacks { | |
3990 | ReadStructuredCloneOp read; | |
3991 | WriteStructuredCloneOp write; | |
3992 | StructuredCloneErrorOp reportError; | |
3993 | }; | |
3994 | __attribute__((visibility ("default"))) JSBool | |
3995 | JS_ReadStructuredClone(JSContext *cx, const uint64 *data, size_t nbytes, | |
3996 | uint32 version, jsval *vp, | |
3997 | const JSStructuredCloneCallbacks *optionalCallbacks, | |
3998 | void *closure); | |
3999 | __attribute__((visibility ("default"))) JSBool | |
4000 | JS_WriteStructuredClone(JSContext *cx, jsval v, uint64 **datap, size_t *nbytesp, | |
4001 | const JSStructuredCloneCallbacks *optionalCallbacks, | |
4002 | void *closure); | |
4003 | __attribute__((visibility ("default"))) JSBool | |
4004 | JS_StructuredClone(JSContext *cx, jsval v, jsval *vp, | |
4005 | const JSStructuredCloneCallbacks *optionalCallbacks, | |
4006 | void *closure); | |
4007 | class JSAutoStructuredCloneBuffer { | |
4008 | JSContext *cx_; | |
4009 | uint64 *data_; | |
4010 | size_t nbytes_; | |
4011 | uint32 version_; | |
4012 | public: | |
4013 | JSAutoStructuredCloneBuffer() | |
4014 | : cx_(__null), data_(__null), nbytes_(0), version_(1) {} | |
4015 | ~JSAutoStructuredCloneBuffer() { clear(); } | |
4016 | JSContext *cx() const { return cx_; } | |
4017 | uint64 *data() const { return data_; } | |
4018 | size_t nbytes() const { return nbytes_; } | |
4019 | void clear(JSContext *cx=__null) { | |
4020 | if (data_) { | |
4021 | if (!cx) | |
4022 | cx = cx_; | |
4023 | ((void) 0); | |
4024 | JS_free(cx, data_); | |
4025 | cx_ = __null; | |
4026 | data_ = __null; | |
4027 | nbytes_ = 0; | |
4028 | version_ = 0; | |
4029 | } | |
4030 | } | |
4031 | void adopt(JSContext *cx, uint64 *data, size_t nbytes, | |
4032 | uint32 version=1) { | |
4033 | clear(cx); | |
4034 | cx_ = cx; | |
4035 | data_ = data; | |
4036 | nbytes_ = nbytes; | |
4037 | version_ = version; | |
4038 | } | |
4039 | void steal(uint64 **datap, size_t *nbytesp, JSContext **cxp=__null, | |
4040 | uint32 *versionp=__null) { | |
4041 | *datap = data_; | |
4042 | *nbytesp = nbytes_; | |
4043 | if (cxp) | |
4044 | *cxp = cx_; | |
4045 | if (versionp) | |
4046 | *versionp = version_; | |
4047 | cx_ = __null; | |
4048 | data_ = __null; | |
4049 | nbytes_ = 0; | |
4050 | version_ = 0; | |
4051 | } | |
4052 | bool read(jsval *vp, JSContext *cx=__null, | |
4053 | const JSStructuredCloneCallbacks *optionalCallbacks=__null, | |
4054 | void *closure=__null) const { | |
4055 | if (!cx) | |
4056 | cx = cx_; | |
4057 | ((void) 0); | |
4058 | ((void) 0); | |
4059 | return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp, | |
4060 | optionalCallbacks, closure); | |
4061 | } | |
4062 | bool write(JSContext *cx, jsval v, | |
4063 | const JSStructuredCloneCallbacks *optionalCallbacks=__null, | |
4064 | void *closure=__null) { | |
4065 | clear(cx); | |
4066 | cx_ = cx; | |
4067 | bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_, | |
4068 | optionalCallbacks, closure); | |
4069 | if (!ok) { | |
4070 | data_ = __null; | |
4071 | nbytes_ = 0; | |
4072 | version_ = 1; | |
4073 | } | |
4074 | return ok; | |
4075 | } | |
4076 | void swap(JSAutoStructuredCloneBuffer &other) { | |
4077 | JSContext *cx = other.cx_; | |
4078 | uint64 *data = other.data_; | |
4079 | size_t nbytes = other.nbytes_; | |
4080 | uint32 version = other.version_; | |
4081 | other.cx_ = this->cx_; | |
4082 | other.data_ = this->data_; | |
4083 | other.nbytes_ = this->nbytes_; | |
4084 | other.version_ = this->version_; | |
4085 | this->cx_ = cx; | |
4086 | this->data_ = data; | |
4087 | this->nbytes_ = nbytes; | |
4088 | this->version_ = version; | |
4089 | } | |
4090 | private: | |
4091 | JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer &other); | |
4092 | JSAutoStructuredCloneBuffer &operator=(const JSAutoStructuredCloneBuffer &other); | |
4093 | }; | |
4094 | __attribute__((visibility ("default"))) void | |
4095 | JS_SetStructuredCloneCallbacks(JSRuntime *rt, const JSStructuredCloneCallbacks *callbacks); | |
4096 | __attribute__((visibility ("default"))) JSBool | |
4097 | JS_ReadUint32Pair(JSStructuredCloneReader *r, uint32 *p1, uint32 *p2); | |
4098 | __attribute__((visibility ("default"))) JSBool | |
4099 | JS_ReadBytes(JSStructuredCloneReader *r, void *p, size_t len); | |
4100 | __attribute__((visibility ("default"))) JSBool | |
4101 | JS_WriteUint32Pair(JSStructuredCloneWriter *w, uint32 tag, uint32 data); | |
4102 | __attribute__((visibility ("default"))) JSBool | |
4103 | JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len); | |
4104 | struct JSLocaleCallbacks { | |
4105 | JSLocaleToUpperCase localeToUpperCase; | |
4106 | JSLocaleToLowerCase localeToLowerCase; | |
4107 | JSLocaleCompare localeCompare; | |
4108 | JSLocaleToUnicode localeToUnicode; | |
4109 | JSErrorCallback localeGetErrorMessage; | |
4110 | }; | |
4111 | extern __attribute__((visibility ("default"))) void | |
4112 | JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks); | |
4113 | extern __attribute__((visibility ("default"))) JSLocaleCallbacks * | |
4114 | JS_GetLocaleCallbacks(JSContext *cx); | |
4115 | extern __attribute__((visibility ("default"))) void | |
4116 | JS_ReportError(JSContext *cx, const char *format, ...); | |
4117 | extern __attribute__((visibility ("default"))) void | |
4118 | JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback, | |
4119 | void *userRef, const uintN errorNumber, ...); | |
4120 | extern __attribute__((visibility ("default"))) void | |
4121 | JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback, | |
4122 | void *userRef, const uintN errorNumber, ...); | |
4123 | extern __attribute__((visibility ("default"))) JSBool | |
4124 | JS_ReportWarning(JSContext *cx, const char *format, ...); | |
4125 | extern __attribute__((visibility ("default"))) JSBool | |
4126 | JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags, | |
4127 | JSErrorCallback errorCallback, void *userRef, | |
4128 | const uintN errorNumber, ...); | |
4129 | extern __attribute__((visibility ("default"))) JSBool | |
4130 | JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, | |
4131 | JSErrorCallback errorCallback, void *userRef, | |
4132 | const uintN errorNumber, ...); | |
4133 | extern __attribute__((visibility ("default"))) void | |
4134 | JS_ReportOutOfMemory(JSContext *cx); | |
4135 | extern __attribute__((visibility ("default"))) void | |
4136 | JS_ReportAllocationOverflow(JSContext *cx); | |
4137 | struct JSErrorReport { | |
4138 | const char *filename; | |
4139 | uintN lineno; | |
4140 | const char *linebuf; | |
4141 | const char *tokenptr; | |
4142 | const jschar *uclinebuf; | |
4143 | const jschar *uctokenptr; | |
4144 | uintN flags; | |
4145 | uintN errorNumber; | |
4146 | const jschar *ucmessage; | |
4147 | const jschar **messageArgs; | |
4148 | }; | |
4149 | extern __attribute__((visibility ("default"))) JSErrorReporter | |
4150 | JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); | |
4151 | extern __attribute__((visibility ("default"))) JSObject * | |
4152 | JS_NewDateObject(JSContext *cx, int year, int mon, int mday, int hour, int min, int sec); | |
4153 | extern __attribute__((visibility ("default"))) JSObject * | |
4154 | JS_NewDateObjectMsec(JSContext *cx, jsdouble msec); | |
4155 | extern __attribute__((visibility ("default"))) JSBool | |
4156 | JS_ObjectIsDate(JSContext *cx, JSObject *obj); | |
4157 | extern __attribute__((visibility ("default"))) JSObject * | |
4158 | JS_NewRegExpObject(JSContext *cx, JSObject *obj, char *bytes, size_t length, uintN flags); | |
4159 | extern __attribute__((visibility ("default"))) JSObject * | |
4160 | JS_NewUCRegExpObject(JSContext *cx, JSObject *obj, jschar *chars, size_t length, uintN flags); | |
4161 | extern __attribute__((visibility ("default"))) void | |
4162 | JS_SetRegExpInput(JSContext *cx, JSObject *obj, JSString *input, JSBool multiline); | |
4163 | extern __attribute__((visibility ("default"))) void | |
4164 | JS_ClearRegExpStatics(JSContext *cx, JSObject *obj); | |
4165 | extern __attribute__((visibility ("default"))) JSBool | |
4166 | JS_ExecuteRegExp(JSContext *cx, JSObject *obj, JSObject *reobj, jschar *chars, size_t length, | |
4167 | size_t *indexp, JSBool test, jsval *rval); | |
4168 | extern __attribute__((visibility ("default"))) JSObject * | |
4169 | JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, uintN flags); | |
4170 | extern __attribute__((visibility ("default"))) JSObject * | |
4171 | JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, uintN flags); | |
4172 | extern __attribute__((visibility ("default"))) JSBool | |
4173 | JS_ExecuteRegExpNoStatics(JSContext *cx, JSObject *reobj, jschar *chars, size_t length, | |
4174 | size_t *indexp, JSBool test, jsval *rval); | |
4175 | extern __attribute__((visibility ("default"))) JSBool | |
4176 | JS_IsExceptionPending(JSContext *cx); | |
4177 | extern __attribute__((visibility ("default"))) JSBool | |
4178 | JS_GetPendingException(JSContext *cx, jsval *vp); | |
4179 | extern __attribute__((visibility ("default"))) void | |
4180 | JS_SetPendingException(JSContext *cx, jsval v); | |
4181 | extern __attribute__((visibility ("default"))) void | |
4182 | JS_ClearPendingException(JSContext *cx); | |
4183 | extern __attribute__((visibility ("default"))) JSBool | |
4184 | JS_ReportPendingException(JSContext *cx); | |
4185 | extern __attribute__((visibility ("default"))) JSExceptionState * | |
4186 | JS_SaveExceptionState(JSContext *cx); | |
4187 | extern __attribute__((visibility ("default"))) void | |
4188 | JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state); | |
4189 | extern __attribute__((visibility ("default"))) void | |
4190 | JS_DropExceptionState(JSContext *cx, JSExceptionState *state); | |
4191 | extern __attribute__((visibility ("default"))) JSErrorReport * | |
4192 | JS_ErrorFromException(JSContext *cx, jsval v); | |
4193 | extern __attribute__((visibility ("default"))) JSBool | |
4194 | JS_ThrowReportedError(JSContext *cx, const char *message, | |
4195 | JSErrorReport *reportp); | |
4196 | extern __attribute__((visibility ("default"))) JSBool | |
4197 | JS_ThrowStopIteration(JSContext *cx); | |
4198 | extern __attribute__((visibility ("default"))) jsword | |
4199 | JS_GetContextThread(JSContext *cx); | |
4200 | extern __attribute__((visibility ("default"))) jsword | |
4201 | JS_SetContextThread(JSContext *cx); | |
4202 | extern __attribute__((visibility ("default"))) jsword | |
4203 | JS_ClearContextThread(JSContext *cx); | |
4204 | static __attribute__((always_inline)) inline JSBool | |
4205 | JS_IsConstructing(JSContext *cx, const jsval *vp) | |
4206 | { | |
4207 | jsval_layout l; | |
4208 | l.asBits = (vp[1]); | |
4209 | return JSVAL_IS_MAGIC_IMPL(l); | |
4210 | } | |
4211 | static __attribute__((always_inline)) inline JSBool | |
4212 | JS_IsConstructing_PossiblyWithGivenThisObject(JSContext *cx, const jsval *vp, | |
4213 | JSObject **maybeThis) | |
4214 | { | |
4215 | jsval_layout l; | |
4216 | JSBool isCtor; | |
4217 | l.asBits = (vp[1]); | |
4218 | isCtor = JSVAL_IS_MAGIC_IMPL(l); | |
4219 | if (isCtor) | |
4220 | *maybeThis = MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(l); | |
4221 | return isCtor; | |
4222 | } | |
4223 | extern __attribute__((visibility ("default"))) JSObject * | |
4224 | JS_NewObjectForConstructor(JSContext *cx, const jsval *vp); | |
4225 | } | |
4226 | extern "C" { | |
4227 | static const uintN JS_GCTHING_ALIGN = 8; | |
4228 | static const uintN JS_GCTHING_ZEROBITS = 3; | |
4229 | typedef uint8 jsbytecode; | |
4230 | typedef uint8 jssrcnote; | |
4231 | typedef uint32 jsatomid; | |
4232 | typedef struct JSArgumentFormatMap JSArgumentFormatMap; | |
4233 | typedef struct JSCodeGenerator JSCodeGenerator; | |
4234 | typedef struct JSGCThing JSGCThing; | |
4235 | typedef struct JSGenerator JSGenerator; | |
4236 | typedef struct JSNativeEnumerator JSNativeEnumerator; | |
4237 | typedef struct JSFunctionBox JSFunctionBox; | |
4238 | typedef struct JSObjectBox JSObjectBox; | |
4239 | typedef struct JSParseNode JSParseNode; | |
4240 | typedef struct JSProperty JSProperty; | |
4241 | typedef struct JSScript JSScript; | |
4242 | typedef struct JSSharpObjectMap JSSharpObjectMap; | |
4243 | typedef struct JSThread JSThread; | |
4244 | typedef struct JSThreadData JSThreadData; | |
4245 | typedef struct JSTreeContext JSTreeContext; | |
4246 | typedef struct JSTryNote JSTryNote; | |
4247 | typedef struct JSLinearString JSLinearString; | |
4248 | typedef struct JSAtom JSAtom; | |
4249 | typedef struct JSAtomList JSAtomList; | |
4250 | typedef struct JSAtomListElement JSAtomListElement; | |
4251 | typedef struct JSAtomMap JSAtomMap; | |
4252 | typedef struct JSAtomState JSAtomState; | |
4253 | typedef struct JSCodeSpec JSCodeSpec; | |
4254 | typedef struct JSPrinter JSPrinter; | |
4255 | typedef struct JSRegExpStatics JSRegExpStatics; | |
4256 | typedef struct JSStackHeader JSStackHeader; | |
4257 | typedef struct JSSubString JSSubString; | |
4258 | typedef struct JSNativeTraceInfo JSNativeTraceInfo; | |
4259 | typedef struct JSSpecializedNative JSSpecializedNative; | |
4260 | typedef struct JSXML JSXML; | |
4261 | typedef struct JSXMLArray JSXMLArray; | |
4262 | typedef struct JSXMLArrayCursor JSXMLArrayCursor; | |
4263 | extern "C++" { | |
4264 | namespace js { | |
4265 | struct ArgumentsData; | |
4266 | class RegExp; | |
4267 | class RegExpStatics; | |
4268 | class AutoStringRooter; | |
4269 | class ExecuteArgsGuard; | |
4270 | class InvokeFrameGuard; | |
4271 | class InvokeArgsGuard; | |
4272 | class InvokeSessionGuard; | |
4273 | class TraceRecorder; | |
4274 | struct TraceMonitor; | |
4275 | class StackSpace; | |
4276 | class StackSegment; | |
4277 | class FrameRegsIter; | |
4278 | class StringBuffer; | |
4279 | struct Compiler; | |
4280 | struct Parser; | |
4281 | class TokenStream; | |
4282 | struct Token; | |
4283 | struct TokenPos; | |
4284 | struct TokenPtr; | |
4285 | class ContextAllocPolicy; | |
4286 | class SystemAllocPolicy; | |
4287 | template <class T, | |
4288 | size_t MinInlineCapacity = 0, | |
4289 | class AllocPolicy = ContextAllocPolicy> | |
4290 | class Vector; | |
4291 | template <class> | |
4292 | struct DefaultHasher; | |
4293 | template <class Key, | |
4294 | class Value, | |
4295 | class HashPolicy = DefaultHasher<Key>, | |
4296 | class AllocPolicy = ContextAllocPolicy> | |
4297 | class HashMap; | |
4298 | template <class T, | |
4299 | class HashPolicy = DefaultHasher<T>, | |
4300 | class AllocPolicy = ContextAllocPolicy> | |
4301 | class HashSet; | |
4302 | class PropertyCache; | |
4303 | struct PropertyCacheEntry; | |
4304 | struct Shape; | |
4305 | struct EmptyShape; | |
4306 | } | |
4307 | } | |
4308 | typedef enum JSTrapStatus { | |
4309 | JSTRAP_ERROR, | |
4310 | JSTRAP_CONTINUE, | |
4311 | JSTRAP_RETURN, | |
4312 | JSTRAP_THROW, | |
4313 | JSTRAP_LIMIT | |
4314 | } JSTrapStatus; | |
4315 | typedef JSTrapStatus | |
4316 | (* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, | |
4317 | jsval closure); | |
4318 | typedef JSTrapStatus | |
4319 | (* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, | |
4320 | void *closure); | |
4321 | typedef JSTrapStatus | |
4322 | (* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, | |
4323 | void *closure); | |
4324 | typedef JSTrapStatus | |
4325 | (* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, | |
4326 | void *closure); | |
4327 | typedef JSBool | |
4328 | (* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, jsval old, | |
4329 | jsval *newp, void *closure); | |
4330 | typedef void | |
4331 | (* JSNewScriptHook)(JSContext *cx, | |
4332 | const char *filename, | |
4333 | uintN lineno, | |
4334 | JSScript *script, | |
4335 | JSFunction *fun, | |
4336 | void *callerdata); | |
4337 | typedef void | |
4338 | (* JSDestroyScriptHook)(JSContext *cx, | |
4339 | JSScript *script, | |
4340 | void *callerdata); | |
4341 | typedef void | |
4342 | (* JSSourceHandler)(const char *filename, uintN lineno, jschar *str, | |
4343 | size_t length, void **listenerTSData, void *closure); | |
4344 | typedef void * | |
4345 | (* JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before, | |
4346 | JSBool *ok, void *closure); | |
4347 | typedef JSBool | |
4348 | (* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report, | |
4349 | void *closure); | |
4350 | typedef struct JSDebugHooks { | |
4351 | JSInterruptHook interruptHook; | |
4352 | void *interruptHookData; | |
4353 | JSNewScriptHook newScriptHook; | |
4354 | void *newScriptHookData; | |
4355 | JSDestroyScriptHook destroyScriptHook; | |
4356 | void *destroyScriptHookData; | |
4357 | JSDebuggerHandler debuggerHandler; | |
4358 | void *debuggerHandlerData; | |
4359 | JSSourceHandler sourceHandler; | |
4360 | void *sourceHandlerData; | |
4361 | JSInterpreterHook executeHook; | |
4362 | void *executeHookData; | |
4363 | JSInterpreterHook callHook; | |
4364 | void *callHookData; | |
4365 | JSThrowHook throwHook; | |
4366 | void *throwHookData; | |
4367 | JSDebugErrorHook debugErrorHook; | |
4368 | void *debugErrorHookData; | |
4369 | } JSDebugHooks; | |
4370 | typedef JSBool | |
4371 | (* JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |
4372 | JSProperty **propp); | |
4373 | typedef JSBool | |
4374 | (* JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); | |
4375 | typedef JSObject * | |
4376 | (* JSObjectOp)(JSContext *cx, JSObject *obj); | |
4377 | typedef JSObject * | |
4378 | (* JSIteratorOp)(JSContext *cx, JSObject *obj, JSBool keysonly); | |
4379 | extern JSBool js_CStringsAreUTF8; | |
4380 | extern __attribute__((visibility ("default"))) JSObject * | |
4381 | js_ObjectToOuterObject(JSContext *cx, JSObject *obj); | |
4382 | } | |
4383 | extern "C" { | |
4384 | typedef uint32 JSHashNumber; | |
4385 | typedef struct JSHashEntry JSHashEntry; | |
4386 | typedef struct JSHashTable JSHashTable; | |
4387 | typedef JSHashNumber (* JSHashFunction)(const void *key); | |
4388 | typedef intN (* JSHashComparator)(const void *v1, const void *v2); | |
4389 | typedef intN (* JSHashEnumerator)(JSHashEntry *he, intN i, void *arg); | |
4390 | typedef struct JSHashAllocOps { | |
4391 | void * (*allocTable)(void *pool, size_t size); | |
4392 | void (*freeTable)(void *pool, void *item, size_t size); | |
4393 | JSHashEntry * (*allocEntry)(void *pool, const void *key); | |
4394 | void (*freeEntry)(void *pool, JSHashEntry *he, uintN flag); | |
4395 | } JSHashAllocOps; | |
4396 | struct JSHashEntry { | |
4397 | JSHashEntry *next; | |
4398 | JSHashNumber keyHash; | |
4399 | const void *key; | |
4400 | void *value; | |
4401 | }; | |
4402 | struct JSHashTable { | |
4403 | JSHashEntry **buckets; | |
4404 | uint32 nentries; | |
4405 | uint32 shift; | |
4406 | JSHashFunction keyHash; | |
4407 | JSHashComparator keyCompare; | |
4408 | JSHashComparator valueCompare; | |
4409 | JSHashAllocOps *allocOps; | |
4410 | void *allocPriv; | |
4411 | }; | |
4412 | extern __attribute__((visibility ("default"))) JSHashTable * | |
4413 | JS_NewHashTable(uint32 n, JSHashFunction keyHash, | |
4414 | JSHashComparator keyCompare, JSHashComparator valueCompare, | |
4415 | JSHashAllocOps *allocOps, void *allocPriv); | |
4416 | extern __attribute__((visibility ("default"))) void | |
4417 | JS_HashTableDestroy(JSHashTable *ht); | |
4418 | extern __attribute__((visibility ("default"))) JSHashEntry ** | |
4419 | JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key); | |
4420 | extern __attribute__((visibility ("default"))) JSHashEntry * | |
4421 | JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **&hep, JSHashNumber keyHash, | |
4422 | const void *key, void *value); | |
4423 | extern __attribute__((visibility ("default"))) void | |
4424 | JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he); | |
4425 | extern __attribute__((visibility ("default"))) JSHashEntry * | |
4426 | JS_HashTableAdd(JSHashTable *ht, const void *key, void *value); | |
4427 | extern __attribute__((visibility ("default"))) JSBool | |
4428 | JS_HashTableRemove(JSHashTable *ht, const void *key); | |
4429 | extern __attribute__((visibility ("default"))) intN | |
4430 | JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg); | |
4431 | extern __attribute__((visibility ("default"))) void * | |
4432 | JS_HashTableLookup(JSHashTable *ht, const void *key); | |
4433 | extern __attribute__((visibility ("default"))) intN | |
4434 | JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp); | |
4435 | extern __attribute__((visibility ("default"))) JSHashNumber | |
4436 | JS_HashString(const void *key); | |
4437 | extern __attribute__((visibility ("default"))) intN | |
4438 | JS_CompareValues(const void *v1, const void *v2); | |
4439 | } | |
4440 | ||
4441 | namespace std | |
4442 | { | |
4443 | typedef long unsigned int size_t; | |
4444 | typedef long int ptrdiff_t; | |
4445 | } | |
4446 | namespace std | |
4447 | { | |
4448 | inline namespace __gnu_cxx_ldbl128 { } | |
4449 | } | |
4450 | ||
4451 | ||
4452 | extern "C++" { | |
4453 | namespace std | |
4454 | { | |
4455 | class exception | |
4456 | { | |
4457 | public: | |
4458 | exception() throw() { } | |
4459 | virtual ~exception() throw(); | |
4460 | virtual const char* what() const throw(); | |
4461 | }; | |
4462 | class bad_exception : public exception | |
4463 | { | |
4464 | public: | |
4465 | bad_exception() throw() { } | |
4466 | virtual ~bad_exception() throw(); | |
4467 | virtual const char* what() const throw(); | |
4468 | }; | |
4469 | typedef void (*terminate_handler) (); | |
4470 | typedef void (*unexpected_handler) (); | |
4471 | terminate_handler set_terminate(terminate_handler) throw(); | |
4472 | void terminate() throw() __attribute__ ((__noreturn__)); | |
4473 | unexpected_handler set_unexpected(unexpected_handler) throw(); | |
4474 | void unexpected() __attribute__ ((__noreturn__)); | |
4475 | bool uncaught_exception() throw() __attribute__ ((__pure__)); | |
4476 | } | |
4477 | namespace __gnu_cxx | |
4478 | { | |
4479 | void __verbose_terminate_handler(); | |
4480 | } | |
4481 | } | |
4482 | extern "C++" { | |
4483 | namespace std | |
4484 | { | |
4485 | class bad_alloc : public exception | |
4486 | { | |
4487 | public: | |
4488 | bad_alloc() throw() { } | |
4489 | virtual ~bad_alloc() throw(); | |
4490 | virtual const char* what() const throw(); | |
4491 | }; | |
4492 | class bad_array_length : public bad_alloc | |
4493 | { | |
4494 | public: | |
4495 | bad_array_length() throw() { }; | |
4496 | virtual ~bad_array_length() throw(); | |
4497 | virtual const char* what() const throw(); | |
4498 | }; | |
4499 | struct nothrow_t { }; | |
4500 | extern const nothrow_t nothrow; | |
4501 | typedef void (*new_handler)(); | |
4502 | new_handler set_new_handler(new_handler) throw(); | |
4503 | } | |
4504 | void* operator new(std::size_t) throw(std::bad_alloc) | |
4505 | __attribute__((__externally_visible__)); | |
4506 | void* operator new[](std::size_t) throw(std::bad_alloc) | |
4507 | __attribute__((__externally_visible__)); | |
4508 | void operator delete(void*) throw() | |
4509 | __attribute__((__externally_visible__)); | |
4510 | void operator delete[](void*) throw() | |
4511 | __attribute__((__externally_visible__)); | |
4512 | void* operator new(std::size_t, const std::nothrow_t&) throw() | |
4513 | __attribute__((__externally_visible__)); | |
4514 | void* operator new[](std::size_t, const std::nothrow_t&) throw() | |
4515 | __attribute__((__externally_visible__)); | |
4516 | void operator delete(void*, const std::nothrow_t&) throw() | |
4517 | __attribute__((__externally_visible__)); | |
4518 | void operator delete[](void*, const std::nothrow_t&) throw() | |
4519 | __attribute__((__externally_visible__)); | |
4520 | inline void* operator new(std::size_t, void* __p) throw() | |
4521 | { return __p; } | |
4522 | inline void* operator new[](std::size_t, void* __p) throw() | |
4523 | { return __p; } | |
4524 | inline void operator delete (void*, void*) throw() { } | |
4525 | inline void operator delete[](void*, void*) throw() { } | |
4526 | } | |
4527 | namespace js { | |
4528 | namespace tl { | |
4529 | template <size_t i, size_t j> struct Min { | |
4530 | static const size_t result = i < j ? i : j; | |
4531 | }; | |
4532 | template <size_t i, size_t j> struct Max { | |
4533 | static const size_t result = i > j ? i : j; | |
4534 | }; | |
4535 | template <size_t i, size_t min, size_t max> struct Clamp { | |
4536 | static const size_t result = i < min ? min : (i > max ? max : i); | |
4537 | }; | |
4538 | template <size_t x, size_t y> struct Pow { | |
4539 | static const size_t result = x * Pow<x, y - 1>::result; | |
4540 | }; | |
4541 | template <size_t x> struct Pow<x,0> { | |
4542 | static const size_t result = 1; | |
4543 | }; | |
4544 | template <size_t i> struct FloorLog2 { | |
4545 | static const size_t result = 1 + FloorLog2<i / 2>::result; | |
4546 | }; | |
4547 | template <> struct FloorLog2<0> { }; | |
4548 | template <> struct FloorLog2<1> { static const size_t result = 0; }; | |
4549 | template <size_t i> struct CeilingLog2 { | |
4550 | static const size_t result = FloorLog2<2 * i - 1>::result; | |
4551 | }; | |
4552 | template <size_t i> struct RoundUpPow2 { | |
4553 | static const size_t result = 1u << CeilingLog2<i>::result; | |
4554 | }; | |
4555 | template <> struct RoundUpPow2<0> { | |
4556 | static const size_t result = 1; | |
4557 | }; | |
4558 | template <class T> struct BitSize { | |
4559 | static const size_t result = sizeof(T) * 8; | |
4560 | }; | |
4561 | template <bool> struct StaticAssert {}; | |
4562 | template <> struct StaticAssert<true> { typedef int result; }; | |
4563 | template <class T, class U> struct IsSameType { | |
4564 | static const bool result = false; | |
4565 | }; | |
4566 | template <class T> struct IsSameType<T,T> { | |
4567 | static const bool result = true; | |
4568 | }; | |
4569 | template <size_t N> struct NBitMask { | |
4570 | typedef typename StaticAssert<N < BitSize<size_t>::result>::result _; | |
4571 | static const size_t result = (size_t(1) << N) - 1; | |
4572 | }; | |
4573 | template <> struct NBitMask<BitSize<size_t>::result> { | |
4574 | static const size_t result = size_t(-1); | |
4575 | }; | |
4576 | template <size_t N> struct MulOverflowMask { | |
4577 | static const size_t result = | |
4578 | ~NBitMask<BitSize<size_t>::result - CeilingLog2<N>::result>::result; | |
4579 | }; | |
4580 | template <> struct MulOverflowMask<0> { }; | |
4581 | template <> struct MulOverflowMask<1> { static const size_t result = 0; }; | |
4582 | template <class T> struct UnsafeRangeSizeMask { | |
4583 | static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; | |
4584 | }; | |
4585 | template <class T> struct StripConst { typedef T result; }; | |
4586 | template <class T> struct StripConst<const T> { typedef T result; }; | |
4587 | template <class T> struct IsPodType { static const bool result = false; }; | |
4588 | template <> struct IsPodType<char> { static const bool result = true; }; | |
4589 | template <> struct IsPodType<signed char> { static const bool result = true; }; | |
4590 | template <> struct IsPodType<unsigned char> { static const bool result = true; }; | |
4591 | template <> struct IsPodType<short> { static const bool result = true; }; | |
4592 | template <> struct IsPodType<unsigned short> { static const bool result = true; }; | |
4593 | template <> struct IsPodType<int> { static const bool result = true; }; | |
4594 | template <> struct IsPodType<unsigned int> { static const bool result = true; }; | |
4595 | template <> struct IsPodType<long> { static const bool result = true; }; | |
4596 | template <> struct IsPodType<unsigned long> { static const bool result = true; }; | |
4597 | template <> struct IsPodType<float> { static const bool result = true; }; | |
4598 | template <> struct IsPodType<double> { static const bool result = true; }; | |
4599 | template <class T, size_t N> inline T *ArraySize(T (&)[N]) { return N; } | |
4600 | template <class T, size_t N> inline T *ArrayEnd(T (&arr)[N]) { return arr + N; } | |
4601 | } | |
4602 | class ReentrancyGuard | |
4603 | { | |
4604 | ReentrancyGuard(const ReentrancyGuard &); | |
4605 | void operator=(const ReentrancyGuard &); | |
4606 | public: | |
4607 | template <class T> | |
4608 | ReentrancyGuard(T & ) | |
4609 | { | |
4610 | } | |
4611 | ~ReentrancyGuard() | |
4612 | { | |
4613 | } | |
4614 | }; | |
4615 | __attribute__((always_inline)) inline size_t | |
4616 | RoundUpPow2(size_t x) | |
4617 | { | |
4618 | size_t log2 = ((x) <= 1 ? 0 : 1 + (((void) 0), ((size_t)((8 * 8) - 1 - __builtin_clzll((x) - 1))))); | |
4619 | ((void) 0); | |
4620 | size_t result = size_t(1) << log2; | |
4621 | return result; | |
4622 | } | |
4623 | template <class T> | |
4624 | __attribute__((always_inline)) inline size_t | |
4625 | PointerRangeSize(T *begin, T *end) | |
4626 | { | |
4627 | return (size_t(end) - size_t(begin)) / sizeof(T); | |
4628 | } | |
4629 | class SystemAllocPolicy | |
4630 | { | |
4631 | public: | |
4632 | void *malloc(size_t bytes) { return js_malloc(bytes); } | |
4633 | void *realloc(void *p, size_t bytes) { return js_realloc(p, bytes); } | |
4634 | void free(void *p) { js_free(p); } | |
4635 | void reportAllocOverflow() const {} | |
4636 | }; | |
4637 | template <size_t nbytes> | |
4638 | struct AlignedStorage | |
4639 | { | |
4640 | union U { | |
4641 | char bytes[nbytes]; | |
4642 | uint64 _; | |
4643 | } u; | |
4644 | const void *addr() const { return u.bytes; } | |
4645 | void *addr() { return u.bytes; } | |
4646 | }; | |
4647 | template <class T> | |
4648 | struct AlignedStorage2 | |
4649 | { | |
4650 | union U { | |
4651 | char bytes[sizeof(T)]; | |
4652 | uint64 _; | |
4653 | } u; | |
4654 | const T *addr() const { return (const T *)u.bytes; } | |
4655 | T *addr() { return (T *)u.bytes; } | |
4656 | }; | |
4657 | template <class T> | |
4658 | class LazilyConstructed | |
4659 | { | |
4660 | AlignedStorage2<T> storage; | |
4661 | bool constructed; | |
4662 | T &asT() { return *storage.addr(); } | |
4663 | public: | |
4664 | LazilyConstructed() { constructed = false; } | |
4665 | ~LazilyConstructed() { if (constructed) asT().~T(); } | |
4666 | bool empty() const { return !constructed; } | |
4667 | void construct() { | |
4668 | ((void) 0); | |
4669 | new(storage.addr()) T(); | |
4670 | constructed = true; | |
4671 | } | |
4672 | template <class T1> | |
4673 | void construct(const T1 &t1) { | |
4674 | ((void) 0); | |
4675 | new(storage.addr()) T(t1); | |
4676 | constructed = true; | |
4677 | } | |
4678 | template <class T1, class T2> | |
4679 | void construct(const T1 &t1, const T2 &t2) { | |
4680 | ((void) 0); | |
4681 | new(storage.addr()) T(t1, t2); | |
4682 | constructed = true; | |
4683 | } | |
4684 | template <class T1, class T2, class T3> | |
4685 | void construct(const T1 &t1, const T2 &t2, const T3 &t3) { | |
4686 | ((void) 0); | |
4687 | new(storage.addr()) T(t1, t2, t3); | |
4688 | constructed = true; | |
4689 | } | |
4690 | template <class T1, class T2, class T3, class T4> | |
4691 | void construct(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { | |
4692 | ((void) 0); | |
4693 | new(storage.addr()) T(t1, t2, t3, t4); | |
4694 | constructed = true; | |
4695 | } | |
4696 | T *addr() { | |
4697 | ((void) 0); | |
4698 | return &asT(); | |
4699 | } | |
4700 | T &ref() { | |
4701 | ((void) 0); | |
4702 | return asT(); | |
4703 | } | |
4704 | void destroy() { | |
4705 | ref().~T(); | |
4706 | constructed = false; | |
4707 | } | |
4708 | }; | |
4709 | template <class T> | |
4710 | class Conditionally { | |
4711 | LazilyConstructed<T> t; | |
4712 | public: | |
4713 | Conditionally(bool b) { if (b) t.construct(); } | |
4714 | template <class T1> | |
4715 | Conditionally(bool b, const T1 &t1) { if (b) t.construct(t1); } | |
4716 | template <class T1, class T2> | |
4717 | Conditionally(bool b, const T1 &t1, const T2 &t2) { if (b) t.construct(t1, t2); } | |
4718 | }; | |
4719 | template <class T> | |
4720 | class AlignedPtrAndFlag | |
4721 | { | |
4722 | uintptr_t bits; | |
4723 | public: | |
4724 | AlignedPtrAndFlag(T *t, bool flag) { | |
4725 | ((void) 0); | |
4726 | bits = uintptr_t(t) | uintptr_t(flag); | |
4727 | } | |
4728 | T *ptr() const { | |
4729 | return (T *)(bits & ~uintptr_t(1)); | |
4730 | } | |
4731 | bool flag() const { | |
4732 | return (bits & 1) != 0; | |
4733 | } | |
4734 | void setPtr(T *t) { | |
4735 | ((void) 0); | |
4736 | bits = uintptr_t(t) | uintptr_t(flag()); | |
4737 | } | |
4738 | void setFlag() { | |
4739 | bits |= 1; | |
4740 | } | |
4741 | void unsetFlag() { | |
4742 | bits &= ~uintptr_t(1); | |
4743 | } | |
4744 | void set(T *t, bool flag) { | |
4745 | ((void) 0); | |
4746 | bits = uintptr_t(t) | flag; | |
4747 | } | |
4748 | }; | |
4749 | template <class T> | |
4750 | static inline void | |
4751 | Reverse(T *beg, T *end) | |
4752 | { | |
4753 | while (beg != end) { | |
4754 | if (--end == beg) | |
4755 | return; | |
4756 | T tmp = *beg; | |
4757 | *beg = *end; | |
4758 | *end = tmp; | |
4759 | ++beg; | |
4760 | } | |
4761 | } | |
4762 | template <class T> | |
4763 | static inline T * | |
4764 | Find(T *beg, T *end, const T &v) | |
4765 | { | |
4766 | for (T *p = beg; p != end; ++p) { | |
4767 | if (*p == v) | |
4768 | return p; | |
4769 | } | |
4770 | return end; | |
4771 | } | |
4772 | template <class Container> | |
4773 | static inline typename Container::ElementType * | |
4774 | Find(Container &c, const typename Container::ElementType &v) | |
4775 | { | |
4776 | return Find(c.begin(), c.end(), v); | |
4777 | } | |
4778 | template <typename InputIterT, typename CallableT> | |
4779 | void | |
4780 | ForEach(InputIterT begin, InputIterT end, CallableT f) | |
4781 | { | |
4782 | for (; begin != end; ++begin) | |
4783 | f(*begin); | |
4784 | } | |
4785 | template <class T> | |
4786 | static inline T | |
4787 | Min(T t1, T t2) | |
4788 | { | |
4789 | return t1 < t2 ? t1 : t2; | |
4790 | } | |
4791 | template <class T> | |
4792 | static inline T | |
4793 | Max(T t1, T t2) | |
4794 | { | |
4795 | return t1 > t2 ? t1 : t2; | |
4796 | } | |
4797 | template <class T> | |
4798 | static T& | |
4799 | InitConst(const T &t) | |
4800 | { | |
4801 | return const_cast<T &>(t); | |
4802 | } | |
4803 | } | |
4804 | namespace js { | |
4805 | typedef uint32 HashNumber; | |
4806 | namespace detail { | |
4807 | template <class T, class HashPolicy, class AllocPolicy> | |
4808 | class HashTable : AllocPolicy | |
4809 | { | |
4810 | typedef typename tl::StripConst<T>::result NonConstT; | |
4811 | typedef typename HashPolicy::KeyType Key; | |
4812 | typedef typename HashPolicy::Lookup Lookup; | |
4813 | static void assignT(NonConstT &dst, const T &src) { dst = src; } | |
4814 | public: | |
4815 | class Entry { | |
4816 | HashNumber keyHash; | |
4817 | public: | |
4818 | Entry() : keyHash(0), t() {} | |
4819 | void operator=(const Entry &rhs) { keyHash = rhs.keyHash; assignT(t, rhs.t); } | |
4820 | NonConstT t; | |
4821 | bool isFree() const { return keyHash == sFreeKey; } | |
4822 | void setFree() { keyHash = sFreeKey; assignT(t, T()); } | |
4823 | bool isRemoved() const { return keyHash == sRemovedKey; } | |
4824 | void setRemoved() { keyHash = sRemovedKey; assignT(t, T()); } | |
4825 | bool isLive() const { return isLiveHash(keyHash); } | |
4826 | void setLive(HashNumber hn) { ((void) 0); keyHash = hn; } | |
4827 | void setCollision() { ((void) 0); keyHash |= sCollisionBit; } | |
4828 | void setCollision(HashNumber collisionBit) { | |
4829 | ((void) 0); keyHash |= collisionBit; | |
4830 | } | |
4831 | void unsetCollision() { ((void) 0); keyHash &= ~sCollisionBit; } | |
4832 | bool hasCollision() const { ((void) 0); return keyHash & sCollisionBit; } | |
4833 | bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; } | |
4834 | HashNumber getKeyHash() const { ((void) 0); return keyHash; } | |
4835 | }; | |
4836 | class Ptr | |
4837 | { | |
4838 | friend class HashTable; | |
4839 | typedef void (Ptr::* ConvertibleToBool)(); | |
4840 | void nonNull() {} | |
4841 | Entry *entry; | |
4842 | protected: | |
4843 | Ptr(Entry &entry) : entry(&entry) {} | |
4844 | public: | |
4845 | bool found() const { return entry->isLive(); } | |
4846 | operator ConvertibleToBool() const { return found() ? &Ptr::nonNull : 0; } | |
4847 | bool operator==(const Ptr &rhs) const { ((void) 0); return entry == rhs.entry; } | |
4848 | bool operator!=(const Ptr &rhs) const { return !(*this == rhs); } | |
4849 | T &operator*() const { return entry->t; } | |
4850 | T *operator->() const { return &entry->t; } | |
4851 | }; | |
4852 | class AddPtr : public Ptr | |
4853 | { | |
4854 | friend class HashTable; | |
4855 | HashNumber keyHash; | |
4856 | AddPtr(Entry &entry, HashNumber hn) : Ptr(entry), keyHash(hn) {} | |
4857 | }; | |
4858 | class Range | |
4859 | { | |
4860 | protected: | |
4861 | friend class HashTable; | |
4862 | Range(Entry *c, Entry *e) : cur(c), end(e) { | |
4863 | while (cur != end && !cur->isLive()) | |
4864 | ++cur; | |
4865 | } | |
4866 | Entry *cur, *end; | |
4867 | public: | |
4868 | bool empty() const { | |
4869 | return cur == end; | |
4870 | } | |
4871 | T &front() const { | |
4872 | ((void) 0); | |
4873 | return cur->t; | |
4874 | } | |
4875 | void popFront() { | |
4876 | ((void) 0); | |
4877 | while (++cur != end && !cur->isLive()); | |
4878 | } | |
4879 | }; | |
4880 | class Enum : public Range | |
4881 | { | |
4882 | friend class HashTable; | |
4883 | HashTable &table; | |
4884 | bool removed; | |
4885 | Enum(const Enum &); | |
4886 | void operator=(const Enum &); | |
4887 | public: | |
4888 | template<class Map> explicit | |
4889 | Enum(Map &map) : Range(map.all()), table(map.impl), removed(false) {} | |
4890 | void removeFront() { | |
4891 | table.remove(*this->cur); | |
4892 | removed = true; | |
4893 | } | |
4894 | ~Enum() { | |
4895 | if (removed) | |
4896 | table.checkUnderloaded(); | |
4897 | } | |
4898 | void endEnumeration() { | |
4899 | if (removed) { | |
4900 | table.checkUnderloaded(); | |
4901 | removed = false; | |
4902 | } | |
4903 | } | |
4904 | }; | |
4905 | private: | |
4906 | uint32 hashShift; | |
4907 | uint32 tableCapacity; | |
4908 | uint32 entryCount; | |
4909 | uint32 gen; | |
4910 | uint32 removedCount; | |
4911 | Entry *table; | |
4912 | void setTableSizeLog2(unsigned sizeLog2) { | |
4913 | hashShift = sHashBits - sizeLog2; | |
4914 | tableCapacity = ((JSUint32)1 << (sizeLog2)); | |
4915 | } | |
4916 | static const unsigned sMinSizeLog2 = 4; | |
4917 | static const unsigned sMinSize = 1 << sMinSizeLog2; | |
4918 | static const unsigned sSizeLimit = ((JSUint32)1 << (24)); | |
4919 | static const unsigned sHashBits = tl::BitSize<HashNumber>::result; | |
4920 | static const uint8 sMinAlphaFrac = 64; | |
4921 | static const uint8 sMaxAlphaFrac = 192; | |
4922 | static const uint8 sInvMaxAlpha = 171; | |
4923 | static const HashNumber sGoldenRatio = 0x9E3779B9U; | |
4924 | static const HashNumber sCollisionBit = 1; | |
4925 | static const HashNumber sFreeKey = 0; | |
4926 | static const HashNumber sRemovedKey = 1; | |
4927 | static bool isLiveHash(HashNumber hash) | |
4928 | { | |
4929 | return hash > sRemovedKey; | |
4930 | } | |
4931 | static HashNumber prepareHash(const Lookup& l) | |
4932 | { | |
4933 | HashNumber keyHash = HashPolicy::hash(l); | |
4934 | keyHash *= sGoldenRatio; | |
4935 | if (!isLiveHash(keyHash)) | |
4936 | keyHash -= (sRemovedKey + 1); | |
4937 | return keyHash & ~sCollisionBit; | |
4938 | } | |
4939 | static Entry *createTable(AllocPolicy &alloc, uint32 capacity) | |
4940 | { | |
4941 | Entry *newTable = (Entry *)alloc.malloc(capacity * sizeof(Entry)); | |
4942 | if (!newTable) | |
4943 | return __null; | |
4944 | for (Entry *e = newTable, *end = e + capacity; e != end; ++e) | |
4945 | new(e) Entry(); | |
4946 | return newTable; | |
4947 | } | |
4948 | static void destroyTable(AllocPolicy &alloc, Entry *oldTable, uint32 capacity) | |
4949 | { | |
4950 | for (Entry *e = oldTable, *end = e + capacity; e != end; ++e) | |
4951 | e->~Entry(); | |
4952 | alloc.free(oldTable); | |
4953 | } | |
4954 | public: | |
4955 | HashTable(AllocPolicy ap) | |
4956 | : AllocPolicy(ap), | |
4957 | entryCount(0), | |
4958 | gen(0), | |
4959 | removedCount(0), | |
4960 | table(__null) | |
4961 | {} | |
4962 | bool init(uint32 length) | |
4963 | { | |
4964 | ((void) 0); | |
4965 | ((void) 0); | |
4966 | uint32 capacity = (length * sInvMaxAlpha) >> 7; | |
4967 | if (capacity < sMinSize) | |
4968 | capacity = sMinSize; | |
4969 | uint32 roundUp = sMinSize, roundUpLog2 = sMinSizeLog2; | |
4970 | while (roundUp < capacity) { | |
4971 | roundUp <<= 1; | |
4972 | ++roundUpLog2; | |
4973 | } | |
4974 | capacity = roundUp; | |
4975 | if (capacity >= sSizeLimit) { | |
4976 | this->reportAllocOverflow(); | |
4977 | return false; | |
4978 | } | |
4979 | table = createTable(*this, capacity); | |
4980 | if (!table) | |
4981 | return false; | |
4982 | setTableSizeLog2(roundUpLog2); | |
4983 | ; | |
4984 | return true; | |
4985 | } | |
4986 | bool initialized() const | |
4987 | { | |
4988 | return !!table; | |
4989 | } | |
4990 | ~HashTable() | |
4991 | { | |
4992 | if (table) | |
4993 | destroyTable(*this, table, tableCapacity); | |
4994 | } | |
4995 | private: | |
4996 | static HashNumber hash1(HashNumber hash0, uint32 shift) { | |
4997 | return hash0 >> shift; | |
4998 | } | |
4999 | static HashNumber hash2(HashNumber hash0, uint32 log2, uint32 shift) { | |
5000 | return ((hash0 << log2) >> shift) | 1; | |
5001 | } | |
5002 | bool overloaded() { | |
5003 | return entryCount + removedCount >= ((sMaxAlphaFrac * tableCapacity) >> 8); | |
5004 | } | |
5005 | bool underloaded() { | |
5006 | return tableCapacity > sMinSize && | |
5007 | entryCount <= ((sMinAlphaFrac * tableCapacity) >> 8); | |
5008 | } | |
5009 | static bool match(Entry &e, const Lookup &l) { | |
5010 | return HashPolicy::match(HashPolicy::getKey(e.t), l); | |
5011 | } | |
5012 | Entry &lookup(const Lookup &l, HashNumber keyHash, unsigned collisionBit) const | |
5013 | { | |
5014 | ((void) 0); | |
5015 | ((void) 0); | |
5016 | ((void) 0); | |
5017 | ((void) 0); | |
5018 | ; | |
5019 | HashNumber h1 = hash1(keyHash, hashShift); | |
5020 | Entry *entry = &table[h1]; | |
5021 | if (entry->isFree()) { | |
5022 | ; | |
5023 | return *entry; | |
5024 | } | |
5025 | if (entry->matchHash(keyHash) && match(*entry, l)) { | |
5026 | ; | |
5027 | return *entry; | |
5028 | } | |
5029 | unsigned sizeLog2 = sHashBits - hashShift; | |
5030 | HashNumber h2 = hash2(keyHash, sizeLog2, hashShift); | |
5031 | HashNumber sizeMask = (HashNumber(1) << sizeLog2) - 1; | |
5032 | Entry *firstRemoved = __null; | |
5033 | while(true) { | |
5034 | if ((__builtin_expect((entry->isRemoved()), 0))) { | |
5035 | if (!firstRemoved) | |
5036 | firstRemoved = entry; | |
5037 | } else { | |
5038 | entry->setCollision(collisionBit); | |
5039 | } | |
5040 | ; | |
5041 | h1 -= h2; | |
5042 | h1 &= sizeMask; | |
5043 | entry = &table[h1]; | |
5044 | if (entry->isFree()) { | |
5045 | ; | |
5046 | return firstRemoved ? *firstRemoved : *entry; | |
5047 | } | |
5048 | if (entry->matchHash(keyHash) && match(*entry, l)) { | |
5049 | ; | |
5050 | return *entry; | |
5051 | } | |
5052 | } | |
5053 | } | |
5054 | Entry &findFreeEntry(HashNumber keyHash) | |
5055 | { | |
5056 | ; | |
5057 | ((void) 0); | |
5058 | HashNumber h1 = hash1(keyHash, hashShift); | |
5059 | Entry *entry = &table[h1]; | |
5060 | if (entry->isFree()) { | |
5061 | ; | |
5062 | return *entry; | |
5063 | } | |
5064 | unsigned sizeLog2 = sHashBits - hashShift; | |
5065 | HashNumber h2 = hash2(keyHash, sizeLog2, hashShift); | |
5066 | HashNumber sizeMask = (HashNumber(1) << sizeLog2) - 1; | |
5067 | while(true) { | |
5068 | ((void) 0); | |
5069 | entry->setCollision(); | |
5070 | ; | |
5071 | h1 -= h2; | |
5072 | h1 &= sizeMask; | |
5073 | entry = &table[h1]; | |
5074 | if (entry->isFree()) { | |
5075 | ; | |
5076 | return *entry; | |
5077 | } | |
5078 | } | |
5079 | } | |
5080 | bool changeTableSize(int deltaLog2) | |
5081 | { | |
5082 | Entry *oldTable = table; | |
5083 | uint32 oldCap = tableCapacity; | |
5084 | uint32 newLog2 = sHashBits - hashShift + deltaLog2; | |
5085 | uint32 newCapacity = ((JSUint32)1 << (newLog2)); | |
5086 | if (newCapacity >= sSizeLimit) { | |
5087 | this->reportAllocOverflow(); | |
5088 | return false; | |
5089 | } | |
5090 | Entry *newTable = createTable(*this, newCapacity); | |
5091 | if (!newTable) | |
5092 | return false; | |
5093 | setTableSizeLog2(newLog2); | |
5094 | removedCount = 0; | |
5095 | gen++; | |
5096 | table = newTable; | |
5097 | for (Entry *src = oldTable, *end = src + oldCap; src != end; ++src) { | |
5098 | if (src->isLive()) { | |
5099 | src->unsetCollision(); | |
5100 | findFreeEntry(src->getKeyHash()) = *src; | |
5101 | } | |
5102 | } | |
5103 | destroyTable(*this, oldTable, oldCap); | |
5104 | return true; | |
5105 | } | |
5106 | void remove(Entry &e) | |
5107 | { | |
5108 | ; | |
5109 | if (e.hasCollision()) { | |
5110 | e.setRemoved(); | |
5111 | removedCount++; | |
5112 | } else { | |
5113 | ; | |
5114 | e.setFree(); | |
5115 | } | |
5116 | entryCount--; | |
5117 | } | |
5118 | void checkUnderloaded() | |
5119 | { | |
5120 | if (underloaded()) { | |
5121 | ; | |
5122 | (void) changeTableSize(-1); | |
5123 | } | |
5124 | } | |
5125 | public: | |
5126 | void clear() | |
5127 | { | |
5128 | for (Entry *e = table, *end = table + tableCapacity; e != end; ++e) | |
5129 | *e = Entry(); | |
5130 | removedCount = 0; | |
5131 | entryCount = 0; | |
5132 | } | |
5133 | Range all() const { | |
5134 | return Range(table, table + tableCapacity); | |
5135 | } | |
5136 | bool empty() const { | |
5137 | return !entryCount; | |
5138 | } | |
5139 | uint32 count() const{ | |
5140 | return entryCount; | |
5141 | } | |
5142 | uint32 generation() const { | |
5143 | return gen; | |
5144 | } | |
5145 | Ptr lookup(const Lookup &l) const { | |
5146 | ReentrancyGuard g(*this); | |
5147 | HashNumber keyHash = prepareHash(l); | |
5148 | return Ptr(lookup(l, keyHash, 0)); | |
5149 | } | |
5150 | AddPtr lookupForAdd(const Lookup &l) const { | |
5151 | ReentrancyGuard g(*this); | |
5152 | HashNumber keyHash = prepareHash(l); | |
5153 | Entry &entry = lookup(l, keyHash, sCollisionBit); | |
5154 | return AddPtr(entry, keyHash); | |
5155 | } | |
5156 | bool add(AddPtr &p) | |
5157 | { | |
5158 | ReentrancyGuard g(*this); | |
5159 | ((void) 0); | |
5160 | ((void) 0); | |
5161 | ((void) 0); | |
5162 | ((void) 0); | |
5163 | if (p.entry->isRemoved()) { | |
5164 | ; | |
5165 | removedCount--; | |
5166 | p.keyHash |= sCollisionBit; | |
5167 | } else { | |
5168 | if (overloaded()) { | |
5169 | int deltaLog2; | |
5170 | if (removedCount >= (tableCapacity >> 2)) { | |
5171 | ; | |
5172 | deltaLog2 = 0; | |
5173 | } else { | |
5174 | ; | |
5175 | deltaLog2 = 1; | |
5176 | } | |
5177 | if (!changeTableSize(deltaLog2)) | |
5178 | return false; | |
5179 | p.entry = &findFreeEntry(p.keyHash); | |
5180 | } | |
5181 | } | |
5182 | p.entry->setLive(p.keyHash); | |
5183 | entryCount++; | |
5184 | return true; | |
5185 | } | |
5186 | bool add(AddPtr &p, T** pentry) | |
5187 | { | |
5188 | if (!add(p)) | |
5189 | return false; | |
5190 | *pentry = &p.entry->t; | |
5191 | return true; | |
5192 | } | |
5193 | bool add(AddPtr &p, const T &t) | |
5194 | { | |
5195 | if (!add(p)) | |
5196 | return false; | |
5197 | p.entry->t = t; | |
5198 | return true; | |
5199 | } | |
5200 | bool relookupOrAdd(AddPtr& p, const Lookup &l, const T& t) | |
5201 | { | |
5202 | { | |
5203 | ReentrancyGuard g(*this); | |
5204 | p.entry = &lookup(l, p.keyHash, sCollisionBit); | |
5205 | } | |
5206 | return p.found() || add(p, t); | |
5207 | } | |
5208 | void remove(Ptr p) | |
5209 | { | |
5210 | ReentrancyGuard g(*this); | |
5211 | ((void) 0); | |
5212 | remove(*p.entry); | |
5213 | checkUnderloaded(); | |
5214 | } | |
5215 | }; | |
5216 | } | |
5217 | template <class Key> | |
5218 | struct DefaultHasher | |
5219 | { | |
5220 | typedef Key Lookup; | |
5221 | static HashNumber hash(const Lookup &l) { | |
5222 | return l; | |
5223 | } | |
5224 | static bool match(const Key &k, const Lookup &l) { | |
5225 | return k == l; | |
5226 | } | |
5227 | }; | |
5228 | template <class T> | |
5229 | struct DefaultHasher<T *> | |
5230 | { | |
5231 | typedef T *Lookup; | |
5232 | static HashNumber hash(T *l) { | |
5233 | return HashNumber(reinterpret_cast<size_t>(l) >> | |
5234 | tl::FloorLog2<sizeof(void *)>::result); | |
5235 | } | |
5236 | static bool match(T *k, T *l) { | |
5237 | return k == l; | |
5238 | } | |
5239 | }; | |
5240 | template <class Key, class Value, class HashPolicy, class AllocPolicy> | |
5241 | class HashMap | |
5242 | { | |
5243 | public: | |
5244 | typedef typename HashPolicy::Lookup Lookup; | |
5245 | class Entry | |
5246 | { | |
5247 | template <class, class, class> friend class detail::HashTable; | |
5248 | void operator=(const Entry &rhs) { | |
5249 | const_cast<Key &>(key) = rhs.key; | |
5250 | value = rhs.value; | |
5251 | } | |
5252 | public: | |
5253 | Entry() : key(), value() {} | |
5254 | Entry(const Key &k, const Value &v) : key(k), value(v) {} | |
5255 | const Key key; | |
5256 | Value value; | |
5257 | }; | |
5258 | private: | |
5259 | struct MapHashPolicy : HashPolicy | |
5260 | { | |
5261 | typedef Key KeyType; | |
5262 | static const Key &getKey(Entry &e) { return e.key; } | |
5263 | }; | |
5264 | typedef detail::HashTable<Entry, MapHashPolicy, AllocPolicy> Impl; | |
5265 | friend class Impl::Enum; | |
5266 | HashMap(const HashMap &); | |
5267 | HashMap &operator=(const HashMap &); | |
5268 | Impl impl; | |
5269 | public: | |
5270 | HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} | |
5271 | bool init(uint32 len = 0) { return impl.init(len); } | |
5272 | bool initialized() const { return impl.initialized(); } | |
5273 | typedef typename Impl::Ptr Ptr; | |
5274 | Ptr lookup(const Lookup &l) const { return impl.lookup(l); } | |
5275 | void remove(Ptr p) { impl.remove(p); } | |
5276 | typedef typename Impl::AddPtr AddPtr; | |
5277 | AddPtr lookupForAdd(const Lookup &l) const { | |
5278 | return impl.lookupForAdd(l); | |
5279 | } | |
5280 | bool add(AddPtr &p, const Key &k, const Value &v) { | |
5281 | Entry *pentry; | |
5282 | if (!impl.add(p, &pentry)) | |
5283 | return false; | |
5284 | const_cast<Key &>(pentry->key) = k; | |
5285 | pentry->value = v; | |
5286 | return true; | |
5287 | } | |
5288 | bool add(AddPtr &p, const Key &k) { | |
5289 | Entry *pentry; | |
5290 | if (!impl.add(p, &pentry)) | |
5291 | return false; | |
5292 | const_cast<Key &>(pentry->key) = k; | |
5293 | return true; | |
5294 | } | |
5295 | bool relookupOrAdd(AddPtr &p, const Key &k, const Value &v) { | |
5296 | return impl.relookupOrAdd(p, k, Entry(k, v)); | |
5297 | } | |
5298 | typedef typename Impl::Range Range; | |
5299 | Range all() const { return impl.all(); } | |
5300 | size_t count() const { return impl.count(); } | |
5301 | typedef typename Impl::Enum Enum; | |
5302 | void clear() { impl.clear(); } | |
5303 | bool empty() const { return impl.empty(); } | |
5304 | unsigned generation() const { return impl.generation(); } | |
5305 | bool has(const Lookup &l) const { | |
5306 | return impl.lookup(l) != __null; | |
5307 | } | |
5308 | Entry *put(const Key &k, const Value &v) { | |
5309 | AddPtr p = lookupForAdd(k); | |
5310 | if (p) { | |
5311 | p->value = v; | |
5312 | return &*p; | |
5313 | } | |
5314 | return add(p, k, v) ? &*p : __null; | |
5315 | } | |
5316 | void remove(const Lookup &l) { | |
5317 | if (Ptr p = lookup(l)) | |
5318 | remove(p); | |
5319 | } | |
5320 | }; | |
5321 | template <class T, class HashPolicy, class AllocPolicy> | |
5322 | class HashSet | |
5323 | { | |
5324 | typedef typename HashPolicy::Lookup Lookup; | |
5325 | struct SetOps : HashPolicy { | |
5326 | typedef T KeyType; | |
5327 | static const KeyType &getKey(const T &t) { return t; } | |
5328 | }; | |
5329 | typedef detail::HashTable<const T, SetOps, AllocPolicy> Impl; | |
5330 | friend class Impl::Enum; | |
5331 | HashSet(const HashSet &); | |
5332 | HashSet &operator=(const HashSet &); | |
5333 | Impl impl; | |
5334 | public: | |
5335 | HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} | |
5336 | bool init(uint32 len = 0) { return impl.init(len); } | |
5337 | bool initialized() const { return impl.initialized(); } | |
5338 | typedef typename Impl::Ptr Ptr; | |
5339 | Ptr lookup(const Lookup &l) const { return impl.lookup(l); } | |
5340 | void remove(Ptr p) { impl.remove(p); } | |
5341 | typedef typename Impl::AddPtr AddPtr; | |
5342 | AddPtr lookupForAdd(const Lookup &l) const { | |
5343 | return impl.lookupForAdd(l); | |
5344 | } | |
5345 | bool add(AddPtr &p, const T &t) { | |
5346 | return impl.add(p, t); | |
5347 | } | |
5348 | bool relookupOrAdd(AddPtr &p, const Lookup &l, const T &t) { | |
5349 | return impl.relookupOrAdd(p, l, t); | |
5350 | } | |
5351 | typedef typename Impl::Range Range; | |
5352 | Range all() const { return impl.all(); } | |
5353 | size_t count() const { return impl.count(); } | |
5354 | typedef typename Impl::Enum Enum; | |
5355 | void clear() { impl.clear(); } | |
5356 | bool empty() const { return impl.empty(); } | |
5357 | unsigned generation() const { return impl.generation(); } | |
5358 | bool has(const Lookup &l) const { | |
5359 | return impl.lookup(l) != __null; | |
5360 | } | |
5361 | const T *put(const T &t) { | |
5362 | AddPtr p = lookupForAdd(t); | |
5363 | return p ? &*p : (add(p, t) ? &*p : __null); | |
5364 | } | |
5365 | void remove(const Lookup &l) { | |
5366 | if (Ptr p = lookup(l)) | |
5367 | remove(p); | |
5368 | } | |
5369 | }; | |
5370 | } | |
5371 | extern "C" { | |
5372 | enum | |
5373 | { | |
5374 | _ISupper = (1 << (0)), | |
5375 | _ISlower = (1 << (1)), | |
5376 | _ISalpha = (1 << (2)), | |
5377 | _ISdigit = (1 << (3)), | |
5378 | _ISxdigit = (1 << (4)), | |
5379 | _ISspace = (1 << (5)), | |
5380 | _ISprint = (1 << (6)), | |
5381 | _ISgraph = (1 << (7)), | |
5382 | _ISblank = (1 << (8)), | |
5383 | _IScntrl = (1 << (9)), | |
5384 | _ISpunct = (1 << (10)), | |
5385 | _ISalnum = (1 << (11)) | |
5386 | }; | |
5387 | extern const unsigned short int **__ctype_b_loc (void) | |
5388 | throw () __attribute__ ((__const__)); | |
5389 | extern const __int32_t **__ctype_tolower_loc (void) | |
5390 | throw () __attribute__ ((__const__)); | |
5391 | extern const __int32_t **__ctype_toupper_loc (void) | |
5392 | throw () __attribute__ ((__const__)); | |
5393 | extern int isalnum (int) throw (); | |
5394 | extern int isalpha (int) throw (); | |
5395 | extern int iscntrl (int) throw (); | |
5396 | extern int isdigit (int) throw (); | |
5397 | extern int islower (int) throw (); | |
5398 | extern int isgraph (int) throw (); | |
5399 | extern int isprint (int) throw (); | |
5400 | extern int ispunct (int) throw (); | |
5401 | extern int isspace (int) throw (); | |
5402 | extern int isupper (int) throw (); | |
5403 | extern int isxdigit (int) throw (); | |
5404 | extern int tolower (int __c) throw (); | |
5405 | extern int toupper (int __c) throw (); | |
5406 | extern int isblank (int) throw (); | |
5407 | extern int isctype (int __c, int __mask) throw (); | |
5408 | extern int isascii (int __c) throw (); | |
5409 | extern int toascii (int __c) throw (); | |
5410 | extern int _toupper (int) throw (); | |
5411 | extern int _tolower (int) throw (); | |
5412 | extern int isalnum_l (int, __locale_t) throw (); | |
5413 | extern int isalpha_l (int, __locale_t) throw (); | |
5414 | extern int iscntrl_l (int, __locale_t) throw (); | |
5415 | extern int isdigit_l (int, __locale_t) throw (); | |
5416 | extern int islower_l (int, __locale_t) throw (); | |
5417 | extern int isgraph_l (int, __locale_t) throw (); | |
5418 | extern int isprint_l (int, __locale_t) throw (); | |
5419 | extern int ispunct_l (int, __locale_t) throw (); | |
5420 | extern int isspace_l (int, __locale_t) throw (); | |
5421 | extern int isupper_l (int, __locale_t) throw (); | |
5422 | extern int isxdigit_l (int, __locale_t) throw (); | |
5423 | extern int isblank_l (int, __locale_t) throw (); | |
5424 | extern int __tolower_l (int __c, __locale_t __l) throw (); | |
5425 | extern int tolower_l (int __c, __locale_t __l) throw (); | |
5426 | extern int __toupper_l (int __c, __locale_t __l) throw (); | |
5427 | extern int toupper_l (int __c, __locale_t __l) throw (); | |
5428 | } | |
5429 | extern "C" { | |
5430 | typedef unsigned char PRUint8; | |
5431 | typedef signed char PRInt8; | |
5432 | typedef unsigned short PRUint16; | |
5433 | typedef short PRInt16; | |
5434 | typedef unsigned int PRUint32; | |
5435 | typedef int PRInt32; | |
5436 | typedef long PRInt64; | |
5437 | typedef unsigned long PRUint64; | |
5438 | typedef int PRIntn; | |
5439 | typedef unsigned int PRUintn; | |
5440 | typedef double PRFloat64; | |
5441 | typedef size_t PRSize; | |
5442 | typedef PRInt32 PROffset32; | |
5443 | typedef PRInt64 PROffset64; | |
5444 | typedef ptrdiff_t PRPtrdiff; | |
5445 | typedef unsigned long PRUptrdiff; | |
5446 | typedef PRIntn PRBool; | |
5447 | typedef PRUint8 PRPackedBool; | |
5448 | typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; | |
5449 | typedef PRUint16 PRUnichar; | |
5450 | typedef long PRWord; | |
5451 | typedef unsigned long PRUword; | |
5452 | } | |
5453 | extern "C" { | |
5454 | typedef struct PRLock PRLock; | |
5455 | extern __attribute__((visibility("default"))) PRLock* PR_NewLock(void); | |
5456 | extern __attribute__((visibility("default"))) void PR_DestroyLock(PRLock *lock); | |
5457 | extern __attribute__((visibility("default"))) void PR_Lock(PRLock *lock); | |
5458 | extern __attribute__((visibility("default"))) PRStatus PR_Unlock(PRLock *lock); | |
5459 | extern __attribute__((visibility("default"))) void PR_AssertCurrentThreadOwnsLock(PRLock *lock); | |
5460 | } | |
5461 | extern "C" { | |
5462 | extern __attribute__((visibility("default"))) PRInt32 PR_AtomicIncrement(PRInt32 *val); | |
5463 | extern __attribute__((visibility("default"))) PRInt32 PR_AtomicDecrement(PRInt32 *val); | |
5464 | extern __attribute__((visibility("default"))) PRInt32 PR_AtomicSet(PRInt32 *val, PRInt32 newval); | |
5465 | extern __attribute__((visibility("default"))) PRInt32 PR_AtomicAdd(PRInt32 *ptr, PRInt32 val); | |
5466 | typedef struct PRStackElemStr PRStackElem; | |
5467 | struct PRStackElemStr { | |
5468 | PRStackElem *prstk_elem_next; | |
5469 | }; | |
5470 | typedef struct PRStackStr PRStack; | |
5471 | extern __attribute__((visibility("default"))) PRStack * PR_CreateStack(const char *stack_name); | |
5472 | extern __attribute__((visibility("default"))) void PR_StackPush(PRStack *stack, PRStackElem *stack_elem); | |
5473 | extern __attribute__((visibility("default"))) PRStackElem * PR_StackPop(PRStack *stack); | |
5474 | extern __attribute__((visibility("default"))) PRStatus PR_DestroyStack(PRStack *stack); | |
5475 | } | |
5476 | extern "C" { | |
5477 | typedef PRUint32 PRIntervalTime; | |
5478 | extern __attribute__((visibility("default"))) PRIntervalTime PR_IntervalNow(void); | |
5479 | extern __attribute__((visibility("default"))) PRUint32 PR_TicksPerSecond(void); | |
5480 | extern __attribute__((visibility("default"))) PRIntervalTime PR_SecondsToInterval(PRUint32 seconds); | |
5481 | extern __attribute__((visibility("default"))) PRIntervalTime PR_MillisecondsToInterval(PRUint32 milli); | |
5482 | extern __attribute__((visibility("default"))) PRIntervalTime PR_MicrosecondsToInterval(PRUint32 micro); | |
5483 | extern __attribute__((visibility("default"))) PRUint32 PR_IntervalToSeconds(PRIntervalTime ticks); | |
5484 | extern __attribute__((visibility("default"))) PRUint32 PR_IntervalToMilliseconds(PRIntervalTime ticks); | |
5485 | extern __attribute__((visibility("default"))) PRUint32 PR_IntervalToMicroseconds(PRIntervalTime ticks); | |
5486 | } | |
5487 | extern "C" { | |
5488 | typedef struct PRCondVar PRCondVar; | |
5489 | extern __attribute__((visibility("default"))) PRCondVar* PR_NewCondVar(PRLock *lock); | |
5490 | extern __attribute__((visibility("default"))) void PR_DestroyCondVar(PRCondVar *cvar); | |
5491 | extern __attribute__((visibility("default"))) PRStatus PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout); | |
5492 | extern __attribute__((visibility("default"))) PRStatus PR_NotifyCondVar(PRCondVar *cvar); | |
5493 | extern __attribute__((visibility("default"))) PRStatus PR_NotifyAllCondVar(PRCondVar *cvar); | |
5494 | } | |
5495 | extern "C" { | |
5496 | typedef struct PRThread PRThread; | |
5497 | typedef struct PRThreadStack PRThreadStack; | |
5498 | typedef enum PRThreadType { | |
5499 | PR_USER_THREAD, | |
5500 | PR_SYSTEM_THREAD | |
5501 | } PRThreadType; | |
5502 | typedef enum PRThreadScope { | |
5503 | PR_LOCAL_THREAD, | |
5504 | PR_GLOBAL_THREAD, | |
5505 | PR_GLOBAL_BOUND_THREAD | |
5506 | } PRThreadScope; | |
5507 | typedef enum PRThreadState { | |
5508 | PR_JOINABLE_THREAD, | |
5509 | PR_UNJOINABLE_THREAD | |
5510 | } PRThreadState; | |
5511 | typedef enum PRThreadPriority | |
5512 | { | |
5513 | PR_PRIORITY_FIRST = 0, | |
5514 | PR_PRIORITY_LOW = 0, | |
5515 | PR_PRIORITY_NORMAL = 1, | |
5516 | PR_PRIORITY_HIGH = 2, | |
5517 | PR_PRIORITY_URGENT = 3, | |
5518 | PR_PRIORITY_LAST = 3 | |
5519 | } PRThreadPriority; | |
5520 | extern __attribute__((visibility("default"))) PRThread* PR_CreateThread(PRThreadType type, | |
5521 | void ( *start)(void *arg), | |
5522 | void *arg, | |
5523 | PRThreadPriority priority, | |
5524 | PRThreadScope scope, | |
5525 | PRThreadState state, | |
5526 | PRUint32 stackSize); | |
5527 | extern __attribute__((visibility("default"))) PRStatus PR_JoinThread(PRThread *thread); | |
5528 | extern __attribute__((visibility("default"))) PRThread* PR_GetCurrentThread(void); | |
5529 | extern __attribute__((visibility("default"))) PRThreadPriority PR_GetThreadPriority(const PRThread *thread); | |
5530 | extern __attribute__((visibility("default"))) void PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority); | |
5531 | extern __attribute__((visibility("default"))) PRStatus PR_SetCurrentThreadName(const char *name); | |
5532 | extern __attribute__((visibility("default"))) const char * PR_GetThreadName(const PRThread *thread); | |
5533 | typedef void ( *PRThreadPrivateDTOR)(void *priv); | |
5534 | extern __attribute__((visibility("default"))) PRStatus PR_NewThreadPrivateIndex( | |
5535 | PRUintn *newIndex, PRThreadPrivateDTOR destructor); | |
5536 | extern __attribute__((visibility("default"))) PRStatus PR_SetThreadPrivate(PRUintn tpdIndex, void *priv); | |
5537 | extern __attribute__((visibility("default"))) void* PR_GetThreadPrivate(PRUintn tpdIndex); | |
5538 | extern __attribute__((visibility("default"))) PRStatus PR_Interrupt(PRThread *thread); | |
5539 | extern __attribute__((visibility("default"))) void PR_ClearInterrupt(void); | |
5540 | extern __attribute__((visibility("default"))) void PR_BlockInterrupt(void); | |
5541 | extern __attribute__((visibility("default"))) void PR_UnblockInterrupt(void); | |
5542 | extern __attribute__((visibility("default"))) PRStatus PR_Sleep(PRIntervalTime ticks); | |
5543 | extern __attribute__((visibility("default"))) PRThreadScope PR_GetThreadScope(const PRThread *thread); | |
5544 | extern __attribute__((visibility("default"))) PRThreadType PR_GetThreadType(const PRThread *thread); | |
5545 | extern __attribute__((visibility("default"))) PRThreadState PR_GetThreadState(const PRThread *thread); | |
5546 | } | |
5547 | extern "C" { | |
5548 | typedef struct JSFatLock JSFatLock; | |
5549 | typedef struct JSThinLock { | |
5550 | jsword owner; | |
5551 | JSFatLock *fat; | |
5552 | } JSThinLock; | |
5553 | typedef PRLock JSLock; | |
5554 | extern void js_Lock(JSContext *cx, JSThinLock *tl); | |
5555 | extern void js_Unlock(JSContext *cx, JSThinLock *tl); | |
5556 | extern void js_LockRuntime(JSRuntime *rt); | |
5557 | extern void js_UnlockRuntime(JSRuntime *rt); | |
5558 | extern int js_SetupLocks(int,int); | |
5559 | extern void js_CleanupLocks(); | |
5560 | extern void js_InitLock(JSThinLock *); | |
5561 | extern void js_FinishLock(JSThinLock *); | |
5562 | extern JSBool | |
5563 | js_CompareAndSwap(volatile jsword *w, jsword ov, jsword nv); | |
5564 | extern void | |
5565 | js_AtomicSetMask(volatile jsword *w, jsword mask); | |
5566 | extern void | |
5567 | js_AtomicClearMask(volatile jsword *w, jsword mask); | |
5568 | } | |
5569 | namespace js { | |
5570 | class AutoLock { | |
5571 | private: | |
5572 | JSLock *lock; | |
5573 | public: | |
5574 | AutoLock(JSLock *lock) : lock(lock) { PR_Lock(lock); } | |
5575 | ~AutoLock() { PR_Unlock(lock); } | |
5576 | }; | |
5577 | } | |
5578 | static inline int | |
5579 | JSDOUBLE_IS_NEGZERO(jsdouble d) | |
5580 | { | |
5581 | return (d == 0 && (sizeof (d) == sizeof (float) ? __signbitf (d) : sizeof (d) == sizeof (double) ? __signbit (d) : __signbitl (d))); | |
5582 | } | |
5583 | static inline | |
5584 | bool | |
5585 | JSDOUBLE_IS_INT32(jsdouble d, int32_t* pi) | |
5586 | { | |
5587 | if (JSDOUBLE_IS_NEGZERO(d)) | |
5588 | return false; | |
5589 | return d == (*pi = int32_t(d)); | |
5590 | } | |
5591 | static __attribute__((always_inline)) inline JSBool | |
5592 | JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32) | |
5593 | { | |
5594 | return l.asBits == (((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32); | |
5595 | } | |
5596 | static __attribute__((always_inline)) inline JSBool | |
5597 | JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b) | |
5598 | { | |
5599 | return l.asBits == (((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN); | |
5600 | } | |
5601 | static __attribute__((always_inline)) inline jsval_layout | |
5602 | MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) | |
5603 | { | |
5604 | jsval_layout l; | |
5605 | l.asBits = ((uint64)(uint32)why) | JSVAL_SHIFTED_TAG_MAGIC; | |
5606 | return l; | |
5607 | } | |
5608 | static __attribute__((always_inline)) inline jsval_layout | |
5609 | MAGIC_TO_JSVAL_IMPL(JSObject *obj) | |
5610 | { | |
5611 | jsval_layout l; | |
5612 | l.asBits = ((uint64)obj) | JSVAL_SHIFTED_TAG_MAGIC; | |
5613 | return l; | |
5614 | } | |
5615 | static __attribute__((always_inline)) inline JSBool | |
5616 | JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) | |
5617 | { | |
5618 | uint64 lbits = lhs.asBits, rbits = rhs.asBits; | |
5619 | return (lbits <= JSVAL_TAG_MAX_DOUBLE && rbits <= JSVAL_TAG_MAX_DOUBLE) || | |
5620 | (((lbits ^ rbits) & 0xFFFF800000000000LL) == 0); | |
5621 | } | |
5622 | static __attribute__((always_inline)) inline jsval_layout | |
5623 | PRIVATE_UINT32_TO_JSVAL_IMPL(uint32 ui) | |
5624 | { | |
5625 | jsval_layout l; | |
5626 | l.asBits = (uint64)ui; | |
5627 | ((void) 0); | |
5628 | return l; | |
5629 | } | |
5630 | static __attribute__((always_inline)) inline uint32 | |
5631 | JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l) | |
5632 | { | |
5633 | ((void) 0); | |
5634 | return (uint32)l.asBits; | |
5635 | } | |
5636 | static __attribute__((always_inline)) inline JSValueType | |
5637 | JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) | |
5638 | { | |
5639 | uint64 type = (l.asBits >> 47) & 0xF; | |
5640 | ((void) 0); | |
5641 | return (JSValueType)type; | |
5642 | } | |
5643 | static __attribute__((always_inline)) inline JSValueTag | |
5644 | JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(jsval_layout l) | |
5645 | { | |
5646 | uint64 tag = l.asBits >> 47; | |
5647 | ((void) 0); | |
5648 | return (JSValueTag)tag; | |
5649 | } | |
5650 | typedef int js_static_assert3[(__builtin_offsetof (jsval_layout, s.payload) == 0) ? 1 : -1]; | |
5651 | typedef int js_static_assert4[((JSVAL_TYPE_NONFUNOBJ & 0xF) == JSVAL_TYPE_OBJECT) ? 1 : -1]; | |
5652 | typedef int js_static_assert5[((JSVAL_TYPE_FUNOBJ & 0xF) == JSVAL_TYPE_OBJECT) ? 1 : -1]; | |
5653 | static __attribute__((always_inline)) inline jsval_layout | |
5654 | BOX_NON_DOUBLE_JSVAL(JSValueType type, uint64 *slot) | |
5655 | { | |
5656 | jsval_layout l; | |
5657 | ((void) 0); | |
5658 | uint32 isI32 = (uint32)(type < JSVAL_TYPE_MAGIC); | |
5659 | uint32 shift = isI32 * 32; | |
5660 | uint64 mask = ((uint64)-1) >> shift; | |
5661 | uint64 payload = *slot & mask; | |
5662 | ((void) 0) | |
5663 | ; | |
5664 | l.asBits = payload | (((uint64)((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type & 0xF)))) << 47); | |
5665 | return l; | |
5666 | } | |
5667 | static __attribute__((always_inline)) inline void | |
5668 | UNBOX_NON_DOUBLE_JSVAL(jsval_layout l, uint64 *out) | |
5669 | { | |
5670 | ((void) 0); | |
5671 | *out = (l.asBits & 0x00007FFFFFFFFFFFLL); | |
5672 | } | |
5673 | namespace js { | |
5674 | class Value | |
5675 | { | |
5676 | public: | |
5677 | __attribute__((always_inline)) inline | |
5678 | void setNull() { | |
5679 | data.asBits = (((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0))); | |
5680 | } | |
5681 | __attribute__((always_inline)) inline | |
5682 | void setUndefined() { | |
5683 | data.asBits = (((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0))); | |
5684 | } | |
5685 | __attribute__((always_inline)) inline | |
5686 | void setInt32(int32 i) { | |
5687 | data = INT32_TO_JSVAL_IMPL(i); | |
5688 | } | |
5689 | __attribute__((always_inline)) inline | |
5690 | int32 &getInt32Ref() { | |
5691 | ((void) 0); | |
5692 | return data.s.payload.i32; | |
5693 | } | |
5694 | __attribute__((always_inline)) inline | |
5695 | void setDouble(double d) { | |
5696 | data = DOUBLE_TO_JSVAL_IMPL(d); | |
5697 | } | |
5698 | __attribute__((always_inline)) inline | |
5699 | double &getDoubleRef() { | |
5700 | ((void) 0); | |
5701 | return data.asDouble; | |
5702 | } | |
5703 | __attribute__((always_inline)) inline | |
5704 | void setString(JSString *str) { | |
5705 | data = STRING_TO_JSVAL_IMPL(str); | |
5706 | } | |
5707 | __attribute__((always_inline)) inline | |
5708 | void setObject(JSObject &obj) { | |
5709 | data = OBJECT_TO_JSVAL_IMPL(&obj); | |
5710 | } | |
5711 | __attribute__((always_inline)) inline | |
5712 | void setBoolean(bool b) { | |
5713 | data = BOOLEAN_TO_JSVAL_IMPL(b); | |
5714 | } | |
5715 | __attribute__((always_inline)) inline | |
5716 | void setMagic(JSWhyMagic why) { | |
5717 | data = MAGIC_TO_JSVAL_IMPL(why); | |
5718 | } | |
5719 | __attribute__((always_inline)) inline | |
5720 | void setMagicWithObjectOrNullPayload(JSObject *obj) { | |
5721 | data = MAGIC_TO_JSVAL_IMPL(obj); | |
5722 | } | |
5723 | __attribute__((always_inline)) inline | |
5724 | JSObject *getMagicObjectOrNullPayload() const { | |
5725 | return MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(data); | |
5726 | } | |
5727 | __attribute__((always_inline)) inline | |
5728 | void setNumber(uint32 ui) { | |
5729 | if (ui > ((jsint)0x7fffffff)) | |
5730 | setDouble((double)ui); | |
5731 | else | |
5732 | setInt32((int32)ui); | |
5733 | } | |
5734 | __attribute__((always_inline)) inline | |
5735 | void setNumber(double d) { | |
5736 | int32_t i; | |
5737 | if (JSDOUBLE_IS_INT32(d, &i)) | |
5738 | setInt32(i); | |
5739 | else | |
5740 | setDouble(d); | |
5741 | } | |
5742 | __attribute__((always_inline)) inline | |
5743 | void setObjectOrNull(JSObject *arg) { | |
5744 | if (arg) | |
5745 | setObject(*arg); | |
5746 | else | |
5747 | setNull(); | |
5748 | } | |
5749 | __attribute__((always_inline)) inline | |
5750 | void setObjectOrUndefined(JSObject *arg) { | |
5751 | if (arg) | |
5752 | setObject(*arg); | |
5753 | else | |
5754 | setUndefined(); | |
5755 | } | |
5756 | __attribute__((always_inline)) inline | |
5757 | void swap(Value &rhs) { | |
5758 | uint64 tmp = rhs.data.asBits; | |
5759 | rhs.data.asBits = data.asBits; | |
5760 | data.asBits = tmp; | |
5761 | } | |
5762 | __attribute__((always_inline)) inline | |
5763 | bool isUndefined() const { | |
5764 | return JSVAL_IS_UNDEFINED_IMPL(data); | |
5765 | } | |
5766 | __attribute__((always_inline)) inline | |
5767 | bool isNull() const { | |
5768 | return JSVAL_IS_NULL_IMPL(data); | |
5769 | } | |
5770 | __attribute__((always_inline)) inline | |
5771 | bool isNullOrUndefined() const { | |
5772 | return isNull() || isUndefined(); | |
5773 | } | |
5774 | __attribute__((always_inline)) inline | |
5775 | bool isInt32() const { | |
5776 | return JSVAL_IS_INT32_IMPL(data); | |
5777 | } | |
5778 | __attribute__((always_inline)) inline | |
5779 | bool isInt32(int32 i32) const { | |
5780 | return JSVAL_IS_SPECIFIC_INT32_IMPL(data, i32); | |
5781 | } | |
5782 | __attribute__((always_inline)) inline | |
5783 | bool isDouble() const { | |
5784 | return JSVAL_IS_DOUBLE_IMPL(data); | |
5785 | } | |
5786 | __attribute__((always_inline)) inline | |
5787 | bool isNumber() const { | |
5788 | return JSVAL_IS_NUMBER_IMPL(data); | |
5789 | } | |
5790 | __attribute__((always_inline)) inline | |
5791 | bool isString() const { | |
5792 | return JSVAL_IS_STRING_IMPL(data); | |
5793 | } | |
5794 | __attribute__((always_inline)) inline | |
5795 | bool isObject() const { | |
5796 | return JSVAL_IS_OBJECT_IMPL(data); | |
5797 | } | |
5798 | __attribute__((always_inline)) inline | |
5799 | bool isPrimitive() const { | |
5800 | return JSVAL_IS_PRIMITIVE_IMPL(data); | |
5801 | } | |
5802 | __attribute__((always_inline)) inline | |
5803 | bool isObjectOrNull() const { | |
5804 | return JSVAL_IS_OBJECT_OR_NULL_IMPL(data); | |
5805 | } | |
5806 | __attribute__((always_inline)) inline | |
5807 | bool isGCThing() const { | |
5808 | return JSVAL_IS_GCTHING_IMPL(data); | |
5809 | } | |
5810 | __attribute__((always_inline)) inline | |
5811 | bool isBoolean() const { | |
5812 | return JSVAL_IS_BOOLEAN_IMPL(data); | |
5813 | } | |
5814 | __attribute__((always_inline)) inline | |
5815 | bool isTrue() const { | |
5816 | return JSVAL_IS_SPECIFIC_BOOLEAN(data, true); | |
5817 | } | |
5818 | __attribute__((always_inline)) inline | |
5819 | bool isFalse() const { | |
5820 | return JSVAL_IS_SPECIFIC_BOOLEAN(data, false); | |
5821 | } | |
5822 | __attribute__((always_inline)) inline | |
5823 | bool isMagic() const { | |
5824 | return JSVAL_IS_MAGIC_IMPL(data); | |
5825 | } | |
5826 | __attribute__((always_inline)) inline | |
5827 | bool isMagic(JSWhyMagic why) const { | |
5828 | ((void) 0); | |
5829 | return JSVAL_IS_MAGIC_IMPL(data); | |
5830 | } | |
5831 | __attribute__((always_inline)) inline | |
5832 | bool hasPtrPayload() const { | |
5833 | return data.asBits >= JSVAL_SHIFTED_TAG_MAGIC; | |
5834 | } | |
5835 | __attribute__((always_inline)) inline | |
5836 | bool isMarkable() const { | |
5837 | return JSVAL_IS_TRACEABLE_IMPL(data); | |
5838 | } | |
5839 | __attribute__((always_inline)) inline | |
5840 | int32 gcKind() const { | |
5841 | ((void) 0); | |
5842 | return JSVAL_TRACE_KIND_IMPL(data); | |
5843 | } | |
5844 | __attribute__((always_inline)) inline | |
5845 | bool operator==(const Value &rhs) const { | |
5846 | return data.asBits == rhs.data.asBits; | |
5847 | } | |
5848 | __attribute__((always_inline)) inline | |
5849 | bool operator!=(const Value &rhs) const { | |
5850 | return data.asBits != rhs.data.asBits; | |
5851 | } | |
5852 | friend bool SameType(const Value &lhs, const Value &rhs); | |
5853 | __attribute__((always_inline)) inline | |
5854 | int32 toInt32() const { | |
5855 | ((void) 0); | |
5856 | return JSVAL_TO_INT32_IMPL(data); | |
5857 | } | |
5858 | __attribute__((always_inline)) inline | |
5859 | double toDouble() const { | |
5860 | ((void) 0); | |
5861 | return data.asDouble; | |
5862 | } | |
5863 | __attribute__((always_inline)) inline | |
5864 | double toNumber() const { | |
5865 | ((void) 0); | |
5866 | return isDouble() ? toDouble() : double(toInt32()); | |
5867 | } | |
5868 | __attribute__((always_inline)) inline | |
5869 | JSString *toString() const { | |
5870 | ((void) 0); | |
5871 | return JSVAL_TO_STRING_IMPL(data); | |
5872 | } | |
5873 | __attribute__((always_inline)) inline | |
5874 | JSObject &toObject() const { | |
5875 | ((void) 0); | |
5876 | return *JSVAL_TO_OBJECT_IMPL(data); | |
5877 | } | |
5878 | __attribute__((always_inline)) inline | |
5879 | JSObject *toObjectOrNull() const { | |
5880 | ((void) 0); | |
5881 | return JSVAL_TO_OBJECT_IMPL(data); | |
5882 | } | |
5883 | __attribute__((always_inline)) inline | |
5884 | void *toGCThing() const { | |
5885 | ((void) 0); | |
5886 | return JSVAL_TO_GCTHING_IMPL(data); | |
5887 | } | |
5888 | __attribute__((always_inline)) inline | |
5889 | bool toBoolean() const { | |
5890 | ((void) 0); | |
5891 | return JSVAL_TO_BOOLEAN_IMPL(data); | |
5892 | } | |
5893 | __attribute__((always_inline)) inline | |
5894 | uint32 payloadAsRawUint32() const { | |
5895 | ((void) 0); | |
5896 | return data.s.payload.u32; | |
5897 | } | |
5898 | __attribute__((always_inline)) inline | |
5899 | uint64 asRawBits() const { | |
5900 | return data.asBits; | |
5901 | } | |
5902 | __attribute__((always_inline)) inline | |
5903 | JSValueType extractNonDoubleType() const { | |
5904 | return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); | |
5905 | } | |
5906 | __attribute__((always_inline)) inline | |
5907 | JSValueTag extractNonDoubleTag() const { | |
5908 | return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); | |
5909 | } | |
5910 | __attribute__((always_inline)) inline | |
5911 | void unboxNonDoubleTo(uint64 *out) const { | |
5912 | UNBOX_NON_DOUBLE_JSVAL(data, out); | |
5913 | } | |
5914 | __attribute__((always_inline)) inline | |
5915 | void boxNonDoubleFrom(JSValueType type, uint64 *out) { | |
5916 | data = BOX_NON_DOUBLE_JSVAL(type, out); | |
5917 | } | |
5918 | __attribute__((always_inline)) inline | |
5919 | JSValueType extractNonDoubleObjectTraceType() const { | |
5920 | ((void) 0); | |
5921 | return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); | |
5922 | } | |
5923 | __attribute__((always_inline)) inline | |
5924 | JSValueTag extractNonDoubleObjectTraceTag() const { | |
5925 | ((void) 0); | |
5926 | return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); | |
5927 | } | |
5928 | __attribute__((always_inline)) inline | |
5929 | void setPrivate(void *ptr) { | |
5930 | data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr); | |
5931 | } | |
5932 | __attribute__((always_inline)) inline | |
5933 | void *toPrivate() const { | |
5934 | ((void) 0); | |
5935 | return JSVAL_TO_PRIVATE_PTR_IMPL(data); | |
5936 | } | |
5937 | __attribute__((always_inline)) inline | |
5938 | void setPrivateUint32(uint32 ui) { | |
5939 | data = PRIVATE_UINT32_TO_JSVAL_IMPL(ui); | |
5940 | } | |
5941 | __attribute__((always_inline)) inline | |
5942 | uint32 toPrivateUint32() const { | |
5943 | ((void) 0); | |
5944 | return JSVAL_TO_PRIVATE_UINT32_IMPL(data); | |
5945 | } | |
5946 | __attribute__((always_inline)) inline | |
5947 | uint32 &getPrivateUint32Ref() { | |
5948 | ((void) 0); | |
5949 | return data.s.payload.u32; | |
5950 | } | |
5951 | __attribute__((always_inline)) inline | |
5952 | void setUnmarkedPtr(void *ptr) { | |
5953 | data.asPtr = ptr; | |
5954 | } | |
5955 | __attribute__((always_inline)) inline | |
5956 | void *toUnmarkedPtr() const { | |
5957 | return data.asPtr; | |
5958 | } | |
5959 | const jsuword *payloadWord() const { | |
5960 | return &data.s.payload.word; | |
5961 | } | |
5962 | private: | |
5963 | void staticAssertions() { | |
5964 | typedef int js_static_assert6[(sizeof(JSValueType) == 1) ? 1 : -1]; | |
5965 | typedef int js_static_assert7[(sizeof(JSValueTag) == 4) ? 1 : -1]; | |
5966 | typedef int js_static_assert8[(sizeof(JSBool) == 4) ? 1 : -1]; | |
5967 | typedef int js_static_assert9[(sizeof(JSWhyMagic) <= 4) ? 1 : -1]; | |
5968 | typedef int js_static_assert10[(sizeof(jsval) == 8) ? 1 : -1]; | |
5969 | } | |
5970 | jsval_layout data; | |
5971 | } __attribute__((aligned (8))); | |
5972 | __attribute__((always_inline)) inline | |
5973 | bool | |
5974 | SameType(const Value &lhs, const Value &rhs) | |
5975 | { | |
5976 | return JSVAL_SAME_TYPE_IMPL(lhs.data, rhs.data); | |
5977 | } | |
5978 | static __attribute__((always_inline)) inline Value | |
5979 | NullValue() | |
5980 | { | |
5981 | Value v; | |
5982 | v.setNull(); | |
5983 | return v; | |
5984 | } | |
5985 | static __attribute__((always_inline)) inline Value | |
5986 | UndefinedValue() | |
5987 | { | |
5988 | Value v; | |
5989 | v.setUndefined(); | |
5990 | return v; | |
5991 | } | |
5992 | static __attribute__((always_inline)) inline Value | |
5993 | Int32Value(int32 i32) | |
5994 | { | |
5995 | Value v; | |
5996 | v.setInt32(i32); | |
5997 | return v; | |
5998 | } | |
5999 | static __attribute__((always_inline)) inline Value | |
6000 | DoubleValue(double dbl) | |
6001 | { | |
6002 | Value v; | |
6003 | v.setDouble(dbl); | |
6004 | return v; | |
6005 | } | |
6006 | static __attribute__((always_inline)) inline Value | |
6007 | StringValue(JSString *str) | |
6008 | { | |
6009 | Value v; | |
6010 | v.setString(str); | |
6011 | return v; | |
6012 | } | |
6013 | static __attribute__((always_inline)) inline Value | |
6014 | BooleanValue(bool boo) | |
6015 | { | |
6016 | Value v; | |
6017 | v.setBoolean(boo); | |
6018 | return v; | |
6019 | } | |
6020 | static __attribute__((always_inline)) inline Value | |
6021 | ObjectValue(JSObject &obj) | |
6022 | { | |
6023 | Value v; | |
6024 | v.setObject(obj); | |
6025 | return v; | |
6026 | } | |
6027 | static __attribute__((always_inline)) inline Value | |
6028 | MagicValue(JSWhyMagic why) | |
6029 | { | |
6030 | Value v; | |
6031 | v.setMagic(why); | |
6032 | return v; | |
6033 | } | |
6034 | static __attribute__((always_inline)) inline Value | |
6035 | NumberValue(double dbl) | |
6036 | { | |
6037 | Value v; | |
6038 | v.setNumber(dbl); | |
6039 | return v; | |
6040 | } | |
6041 | static __attribute__((always_inline)) inline Value | |
6042 | ObjectOrNullValue(JSObject *obj) | |
6043 | { | |
6044 | Value v; | |
6045 | v.setObjectOrNull(obj); | |
6046 | return v; | |
6047 | } | |
6048 | static __attribute__((always_inline)) inline Value | |
6049 | PrivateValue(void *ptr) | |
6050 | { | |
6051 | Value v; | |
6052 | v.setPrivate(ptr); | |
6053 | return v; | |
6054 | } | |
6055 | static __attribute__((always_inline)) inline void | |
6056 | ClearValueRange(Value *vec, uintN len, bool useHoles) | |
6057 | { | |
6058 | if (useHoles) { | |
6059 | for (uintN i = 0; i < len; i++) | |
6060 | vec[i].setMagic(JS_ARRAY_HOLE); | |
6061 | } else { | |
6062 | for (uintN i = 0; i < len; i++) | |
6063 | vec[i].setUndefined(); | |
6064 | } | |
6065 | } | |
6066 | static inline jsval * Jsvalify(Value *v) { return (jsval *)v; } | |
6067 | static inline const jsval * Jsvalify(const Value *v) { return (const jsval *)v; } | |
6068 | static inline jsval & Jsvalify(Value &v) { return (jsval &)v; } | |
6069 | static inline const jsval & Jsvalify(const Value &v) { return (const jsval &)v; } | |
6070 | static inline Value * Valueify(jsval *v) { return (Value *)v; } | |
6071 | static inline const Value * Valueify(const jsval *v) { return (const Value *)v; } | |
6072 | static inline Value ** Valueify(jsval **v) { return (Value **)v; } | |
6073 | static inline Value & Valueify(jsval &v) { return (Value &)v; } | |
6074 | static inline const Value & Valueify(const jsval &v) { return (const Value &)v; } | |
6075 | struct Class; | |
6076 | typedef JSBool | |
6077 | (* Native)(JSContext *cx, uintN argc, Value *vp); | |
6078 | typedef JSBool | |
6079 | (* PropertyOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp); | |
6080 | typedef JSBool | |
6081 | (* StrictPropertyOp)(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp); | |
6082 | typedef JSBool | |
6083 | (* ConvertOp)(JSContext *cx, JSObject *obj, JSType type, Value *vp); | |
6084 | typedef JSBool | |
6085 | (* NewEnumerateOp)(JSContext *cx, JSObject *obj, JSIterateOp enum_op, | |
6086 | Value *statep, jsid *idp); | |
6087 | typedef JSBool | |
6088 | (* HasInstanceOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp); | |
6089 | typedef JSBool | |
6090 | (* CheckAccessOp)(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | |
6091 | Value *vp); | |
6092 | typedef JSBool | |
6093 | (* EqualityOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp); | |
6094 | typedef JSBool | |
6095 | (* DefinePropOp)(JSContext *cx, JSObject *obj, jsid id, const Value *value, | |
6096 | PropertyOp getter, StrictPropertyOp setter, uintN attrs); | |
6097 | typedef JSBool | |
6098 | (* PropertyIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp); | |
6099 | typedef JSBool | |
6100 | (* StrictPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict); | |
6101 | typedef JSBool | |
6102 | (* DeleteIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict); | |
6103 | typedef JSBool | |
6104 | (* CallOp)(JSContext *cx, uintN argc, Value *vp); | |
6105 | typedef JSBool | |
6106 | (* LookupPropOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |
6107 | JSProperty **propp); | |
6108 | typedef JSBool | |
6109 | (* AttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); | |
6110 | typedef JSType | |
6111 | (* TypeOfOp)(JSContext *cx, JSObject *obj); | |
6112 | typedef void | |
6113 | (* TraceOp)(JSTracer *trc, JSObject *obj); | |
6114 | typedef JSObject * | |
6115 | (* ObjectOp)(JSContext *cx, JSObject *obj); | |
6116 | typedef void | |
6117 | (* FinalizeOp)(JSContext *cx, JSObject *obj); | |
6118 | class AutoIdVector; | |
6119 | typedef JSBool | |
6120 | (* FixOp)(JSContext *cx, JSObject *obj, bool *fixed, AutoIdVector *props); | |
6121 | static inline Native Valueify(JSNative f) { return (Native)f; } | |
6122 | static inline JSNative Jsvalify(Native f) { return (JSNative)f; } | |
6123 | static inline PropertyOp Valueify(JSPropertyOp f) { return (PropertyOp)f; } | |
6124 | static inline JSPropertyOp Jsvalify(PropertyOp f) { return (JSPropertyOp)f; } | |
6125 | static inline StrictPropertyOp Valueify(JSStrictPropertyOp f) { return (StrictPropertyOp)f; } | |
6126 | static inline JSStrictPropertyOp Jsvalify(StrictPropertyOp f) { return (JSStrictPropertyOp)f; } | |
6127 | static inline ConvertOp Valueify(JSConvertOp f) { return (ConvertOp)f; } | |
6128 | static inline JSConvertOp Jsvalify(ConvertOp f) { return (JSConvertOp)f; } | |
6129 | static inline NewEnumerateOp Valueify(JSNewEnumerateOp f) { return (NewEnumerateOp)f; } | |
6130 | static inline JSNewEnumerateOp Jsvalify(NewEnumerateOp f) { return (JSNewEnumerateOp)f; } | |
6131 | static inline HasInstanceOp Valueify(JSHasInstanceOp f) { return (HasInstanceOp)f; } | |
6132 | static inline JSHasInstanceOp Jsvalify(HasInstanceOp f) { return (JSHasInstanceOp)f; } | |
6133 | static inline CheckAccessOp Valueify(JSCheckAccessOp f) { return (CheckAccessOp)f; } | |
6134 | static inline JSCheckAccessOp Jsvalify(CheckAccessOp f) { return (JSCheckAccessOp)f; } | |
6135 | static inline EqualityOp Valueify(JSEqualityOp f); | |
6136 | static inline JSEqualityOp Jsvalify(EqualityOp f); | |
6137 | static const PropertyOp PropertyStub = (PropertyOp)JS_PropertyStub; | |
6138 | static const StrictPropertyOp StrictPropertyStub = (StrictPropertyOp)JS_StrictPropertyStub; | |
6139 | static const JSEnumerateOp EnumerateStub = JS_EnumerateStub; | |
6140 | static const JSResolveOp ResolveStub = JS_ResolveStub; | |
6141 | static const ConvertOp ConvertStub = (ConvertOp)JS_ConvertStub; | |
6142 | static const JSFinalizeOp FinalizeStub = JS_FinalizeStub; | |
6143 | struct ClassSizeMeasurement { | |
6144 | const char *name; uint32 flags; PropertyOp addProperty; PropertyOp delProperty; PropertyOp getProperty; StrictPropertyOp setProperty; JSEnumerateOp enumerate; JSResolveOp resolve; ConvertOp convert; JSFinalizeOp finalize; JSClassInternal reserved0; CheckAccessOp checkAccess; Native call; Native construct; JSXDRObjectOp xdrObject; HasInstanceOp hasInstance; JSMarkOp mark; | |
6145 | }; | |
6146 | struct ClassExtension { | |
6147 | EqualityOp equality; | |
6148 | JSObjectOp outerObject; | |
6149 | JSObjectOp innerObject; | |
6150 | JSIteratorOp iteratorObject; | |
6151 | void *unused; | |
6152 | }; | |
6153 | struct ObjectOps { | |
6154 | js::LookupPropOp lookupProperty; | |
6155 | js::DefinePropOp defineProperty; | |
6156 | js::PropertyIdOp getProperty; | |
6157 | js::StrictPropertyIdOp setProperty; | |
6158 | js::AttributesOp getAttributes; | |
6159 | js::AttributesOp setAttributes; | |
6160 | js::DeleteIdOp deleteProperty; | |
6161 | js::NewEnumerateOp enumerate; | |
6162 | js::TypeOfOp typeOf; | |
6163 | js::TraceOp trace; | |
6164 | js::FixOp fix; | |
6165 | js::ObjectOp thisObject; | |
6166 | js::FinalizeOp clear; | |
6167 | }; | |
6168 | struct Class { | |
6169 | const char *name; uint32 flags; PropertyOp addProperty; PropertyOp delProperty; PropertyOp getProperty; StrictPropertyOp setProperty; JSEnumerateOp enumerate; JSResolveOp resolve; ConvertOp convert; JSFinalizeOp finalize; JSClassInternal reserved0; CheckAccessOp checkAccess; Native call; Native construct; JSXDRObjectOp xdrObject; HasInstanceOp hasInstance; JSMarkOp mark; | |
6170 | ClassExtension ext; | |
6171 | ObjectOps ops; | |
6172 | uint8 pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) - | |
6173 | sizeof(ClassExtension) - sizeof(ObjectOps)]; | |
6174 | static const uint32 NON_NATIVE = (1<<((8 + 8)+4)); | |
6175 | bool isNative() const { | |
6176 | return !(flags & NON_NATIVE); | |
6177 | } | |
6178 | }; | |
6179 | typedef int js_static_assert11[(__builtin_offsetof (JSClass, name) == __builtin_offsetof (Class, name)) ? 1 : -1]; | |
6180 | typedef int js_static_assert12[(__builtin_offsetof (JSClass, flags) == __builtin_offsetof (Class, flags)) ? 1 : -1]; | |
6181 | typedef int js_static_assert13[(__builtin_offsetof (JSClass, addProperty) == __builtin_offsetof (Class, addProperty)) ? 1 : -1]; | |
6182 | typedef int js_static_assert14[(__builtin_offsetof (JSClass, delProperty) == __builtin_offsetof (Class, delProperty)) ? 1 : -1]; | |
6183 | typedef int js_static_assert15[(__builtin_offsetof (JSClass, getProperty) == __builtin_offsetof (Class, getProperty)) ? 1 : -1]; | |
6184 | typedef int js_static_assert16[(__builtin_offsetof (JSClass, setProperty) == __builtin_offsetof (Class, setProperty)) ? 1 : -1]; | |
6185 | typedef int js_static_assert17[(__builtin_offsetof (JSClass, enumerate) == __builtin_offsetof (Class, enumerate)) ? 1 : -1]; | |
6186 | typedef int js_static_assert18[(__builtin_offsetof (JSClass, resolve) == __builtin_offsetof (Class, resolve)) ? 1 : -1]; | |
6187 | typedef int js_static_assert19[(__builtin_offsetof (JSClass, convert) == __builtin_offsetof (Class, convert)) ? 1 : -1]; | |
6188 | typedef int js_static_assert20[(__builtin_offsetof (JSClass, finalize) == __builtin_offsetof (Class, finalize)) ? 1 : -1]; | |
6189 | typedef int js_static_assert21[(__builtin_offsetof (JSClass, reserved0) == __builtin_offsetof (Class, reserved0)) ? 1 : -1]; | |
6190 | typedef int js_static_assert22[(__builtin_offsetof (JSClass, checkAccess) == __builtin_offsetof (Class, checkAccess)) ? 1 : -1]; | |
6191 | typedef int js_static_assert23[(__builtin_offsetof (JSClass, call) == __builtin_offsetof (Class, call)) ? 1 : -1]; | |
6192 | typedef int js_static_assert24[(__builtin_offsetof (JSClass, construct) == __builtin_offsetof (Class, construct)) ? 1 : -1]; | |
6193 | typedef int js_static_assert25[(__builtin_offsetof (JSClass, xdrObject) == __builtin_offsetof (Class, xdrObject)) ? 1 : -1]; | |
6194 | typedef int js_static_assert26[(__builtin_offsetof (JSClass, hasInstance) == __builtin_offsetof (Class, hasInstance)) ? 1 : -1]; | |
6195 | typedef int js_static_assert27[(__builtin_offsetof (JSClass, mark) == __builtin_offsetof (Class, mark)) ? 1 : -1]; | |
6196 | typedef int js_static_assert28[(sizeof(JSClass) == sizeof(Class)) ? 1 : -1]; | |
6197 | struct PropertyDescriptor { | |
6198 | JSObject *obj; | |
6199 | uintN attrs; | |
6200 | PropertyOp getter; | |
6201 | StrictPropertyOp setter; | |
6202 | Value value; | |
6203 | uintN shortid; | |
6204 | }; | |
6205 | typedef int js_static_assert29[(__builtin_offsetof (JSPropertyDescriptor, obj) == __builtin_offsetof (PropertyDescriptor, obj)) ? 1 : -1]; | |
6206 | typedef int js_static_assert30[(__builtin_offsetof (JSPropertyDescriptor, attrs) == __builtin_offsetof (PropertyDescriptor, attrs)) ? 1 : -1]; | |
6207 | typedef int js_static_assert31[(__builtin_offsetof (JSPropertyDescriptor, getter) == __builtin_offsetof (PropertyDescriptor, getter)) ? 1 : -1]; | |
6208 | typedef int js_static_assert32[(__builtin_offsetof (JSPropertyDescriptor, setter) == __builtin_offsetof (PropertyDescriptor, setter)) ? 1 : -1]; | |
6209 | typedef int js_static_assert33[(__builtin_offsetof (JSPropertyDescriptor, value) == __builtin_offsetof (PropertyDescriptor, value)) ? 1 : -1]; | |
6210 | typedef int js_static_assert34[(__builtin_offsetof (JSPropertyDescriptor, shortid) == __builtin_offsetof (PropertyDescriptor, shortid)) ? 1 : -1]; | |
6211 | typedef int js_static_assert35[(sizeof(JSPropertyDescriptor) == sizeof(PropertyDescriptor)) ? 1 : -1]; | |
6212 | static __attribute__((always_inline)) inline JSClass * Jsvalify(Class *c) { return (JSClass *)c; } | |
6213 | static __attribute__((always_inline)) inline Class * Valueify(JSClass *c) { return (Class *)c; } | |
6214 | static __attribute__((always_inline)) inline JSPropertyDescriptor * Jsvalify(PropertyDescriptor *p) { return (JSPropertyDescriptor *) p; } | |
6215 | static __attribute__((always_inline)) inline PropertyDescriptor * Valueify(JSPropertyDescriptor *p) { return (PropertyDescriptor *) p; } | |
6216 | typedef js::Value ValueArgType; | |
6217 | static __attribute__((always_inline)) inline const Value & | |
6218 | ValueArgToConstRef(const Value &v) | |
6219 | { | |
6220 | return v; | |
6221 | } | |
6222 | static __attribute__((always_inline)) inline void | |
6223 | MakeRangeGCSafe(Value *vec, size_t len) | |
6224 | { | |
6225 | PodZero(vec, len); | |
6226 | } | |
6227 | static __attribute__((always_inline)) inline void | |
6228 | MakeRangeGCSafe(Value *beg, Value *end) | |
6229 | { | |
6230 | PodZero(beg, end - beg); | |
6231 | } | |
6232 | static __attribute__((always_inline)) inline void | |
6233 | MakeRangeGCSafe(jsid *beg, jsid *end) | |
6234 | { | |
6235 | for (jsid *id = beg; id != end; ++id) | |
6236 | *id = INT_TO_JSID(0); | |
6237 | } | |
6238 | static __attribute__((always_inline)) inline void | |
6239 | MakeRangeGCSafe(jsid *vec, size_t len) | |
6240 | { | |
6241 | MakeRangeGCSafe(vec, vec + len); | |
6242 | } | |
6243 | static __attribute__((always_inline)) inline void | |
6244 | MakeRangeGCSafe(const Shape **beg, const Shape **end) | |
6245 | { | |
6246 | PodZero(beg, end - beg); | |
6247 | } | |
6248 | static __attribute__((always_inline)) inline void | |
6249 | MakeRangeGCSafe(const Shape **vec, size_t len) | |
6250 | { | |
6251 | PodZero(vec, len); | |
6252 | } | |
6253 | static __attribute__((always_inline)) inline void | |
6254 | SetValueRangeToUndefined(Value *beg, Value *end) | |
6255 | { | |
6256 | for (Value *v = beg; v != end; ++v) | |
6257 | v->setUndefined(); | |
6258 | } | |
6259 | static __attribute__((always_inline)) inline void | |
6260 | SetValueRangeToUndefined(Value *vec, size_t len) | |
6261 | { | |
6262 | SetValueRangeToUndefined(vec, vec + len); | |
6263 | } | |
6264 | static __attribute__((always_inline)) inline void | |
6265 | SetValueRangeToNull(Value *beg, Value *end) | |
6266 | { | |
6267 | for (Value *v = beg; v != end; ++v) | |
6268 | v->setNull(); | |
6269 | } | |
6270 | static __attribute__((always_inline)) inline void | |
6271 | SetValueRangeToNull(Value *vec, size_t len) | |
6272 | { | |
6273 | SetValueRangeToNull(vec, vec + len); | |
6274 | } | |
6275 | static __attribute__((always_inline)) inline void | |
6276 | Debug_SetValueRangeToCrashOnTouch(Value *beg, Value *end) | |
6277 | { | |
6278 | } | |
6279 | static __attribute__((always_inline)) inline void | |
6280 | Debug_SetValueRangeToCrashOnTouch(Value *vec, size_t len) | |
6281 | { | |
6282 | } | |
6283 | } | |
6284 | namespace js { | |
6285 | template <class T, size_t N, class AP, bool IsPod> | |
6286 | struct VectorImpl | |
6287 | { | |
6288 | static inline void destroy(T *begin, T *end) { | |
6289 | for (T *p = begin; p != end; ++p) | |
6290 | p->~T(); | |
6291 | } | |
6292 | static inline void initialize(T *begin, T *end) { | |
6293 | for (T *p = begin; p != end; ++p) | |
6294 | new(p) T(); | |
6295 | } | |
6296 | template <class U> | |
6297 | static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { | |
6298 | for (const U *p = srcbeg; p != srcend; ++p, ++dst) | |
6299 | new(dst) T(*p); | |
6300 | } | |
6301 | template <class U> | |
6302 | static inline void copyConstructN(T *dst, size_t n, const U &u) { | |
6303 | for (T *end = dst + n; dst != end; ++dst) | |
6304 | new(dst) T(u); | |
6305 | } | |
6306 | static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) { | |
6307 | ((void) 0); | |
6308 | T *newbuf = reinterpret_cast<T *>(v.malloc(newcap * sizeof(T))); | |
6309 | if (!newbuf) | |
6310 | return false; | |
6311 | for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) | |
6312 | new(dst) T(*src); | |
6313 | VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); | |
6314 | v.free(v.mBegin); | |
6315 | v.mBegin = newbuf; | |
6316 | v.mCapacity = newcap; | |
6317 | return true; | |
6318 | } | |
6319 | }; | |
6320 | template <class T, size_t N, class AP> | |
6321 | struct VectorImpl<T, N, AP, true> | |
6322 | { | |
6323 | static inline void destroy(T *, T *) {} | |
6324 | static inline void initialize(T *begin, T *end) { | |
6325 | for (T *p = begin; p != end; ++p) | |
6326 | new(p) T(); | |
6327 | } | |
6328 | template <class U> | |
6329 | static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { | |
6330 | for (const U *p = srcbeg; p != srcend; ++p, ++dst) | |
6331 | *dst = *p; | |
6332 | } | |
6333 | static inline void copyConstructN(T *dst, size_t n, const T &t) { | |
6334 | for (T *p = dst, *end = dst + n; p != end; ++p) | |
6335 | *p = t; | |
6336 | } | |
6337 | static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) { | |
6338 | ((void) 0); | |
6339 | size_t bytes = sizeof(T) * newcap; | |
6340 | T *newbuf = reinterpret_cast<T *>(v.realloc(v.mBegin, bytes)); | |
6341 | if (!newbuf) | |
6342 | return false; | |
6343 | v.mBegin = newbuf; | |
6344 | v.mCapacity = newcap; | |
6345 | return true; | |
6346 | } | |
6347 | }; | |
6348 | template <class T, size_t N, class AllocPolicy> | |
6349 | class Vector : AllocPolicy | |
6350 | { | |
6351 | static const bool sElemIsPod = tl::IsPodType<T>::result; | |
6352 | typedef VectorImpl<T, N, AllocPolicy, sElemIsPod> Impl; | |
6353 | friend struct VectorImpl<T, N, AllocPolicy, sElemIsPod>; | |
6354 | bool calculateNewCapacity(size_t curLength, size_t lengthInc, size_t &newCap); | |
6355 | bool growStorageBy(size_t lengthInc); | |
6356 | bool growHeapStorageBy(size_t lengthInc); | |
6357 | bool convertToHeapStorage(size_t lengthInc); | |
6358 | template <bool InitNewElems> inline bool growByImpl(size_t inc); | |
6359 | static const int sMaxInlineBytes = 1024; | |
6360 | static const size_t sInlineCapacity = | |
6361 | tl::Min<N, sMaxInlineBytes / sizeof(T)>::result; | |
6362 | static const size_t sInlineBytes = | |
6363 | tl::Max<1, sInlineCapacity * sizeof(T)>::result; | |
6364 | T *mBegin; | |
6365 | size_t mLength; | |
6366 | size_t mCapacity; | |
6367 | AlignedStorage<sInlineBytes> storage; | |
6368 | Vector(const Vector &); | |
6369 | Vector &operator=(const Vector &); | |
6370 | bool usingInlineStorage() const { | |
6371 | return mBegin == (T *)storage.addr(); | |
6372 | } | |
6373 | T *beginNoCheck() const { | |
6374 | return mBegin; | |
6375 | } | |
6376 | T *endNoCheck() { | |
6377 | return mBegin + mLength; | |
6378 | } | |
6379 | const T *endNoCheck() const { | |
6380 | return mBegin + mLength; | |
6381 | } | |
6382 | public: | |
6383 | typedef T ElementType; | |
6384 | Vector(AllocPolicy = AllocPolicy()); | |
6385 | ~Vector(); | |
6386 | const AllocPolicy &allocPolicy() const { | |
6387 | return *this; | |
6388 | } | |
6389 | enum { InlineLength = N }; | |
6390 | size_t length() const { | |
6391 | return mLength; | |
6392 | } | |
6393 | bool empty() const { | |
6394 | return mLength == 0; | |
6395 | } | |
6396 | size_t capacity() const { | |
6397 | return mCapacity; | |
6398 | } | |
6399 | T *begin() const { | |
6400 | ((void) 0); | |
6401 | return mBegin; | |
6402 | } | |
6403 | T *end() { | |
6404 | ((void) 0); | |
6405 | return mBegin + mLength; | |
6406 | } | |
6407 | const T *end() const { | |
6408 | ((void) 0); | |
6409 | return mBegin + mLength; | |
6410 | } | |
6411 | T &operator[](size_t i) { | |
6412 | ((void) 0); | |
6413 | return begin()[i]; | |
6414 | } | |
6415 | const T &operator[](size_t i) const { | |
6416 | ((void) 0); | |
6417 | return begin()[i]; | |
6418 | } | |
6419 | T &back() { | |
6420 | ((void) 0); | |
6421 | return *(end() - 1); | |
6422 | } | |
6423 | const T &back() const { | |
6424 | ((void) 0); | |
6425 | return *(end() - 1); | |
6426 | } | |
6427 | bool reserve(size_t capacity); | |
6428 | void shrinkBy(size_t incr); | |
6429 | bool growBy(size_t incr); | |
6430 | bool resize(size_t newLength); | |
6431 | bool growByUninitialized(size_t incr); | |
6432 | bool resizeUninitialized(size_t newLength); | |
6433 | void clear(); | |
6434 | bool append(const T &t); | |
6435 | bool appendN(const T &t, size_t n); | |
6436 | template <class U> bool append(const U *begin, const U *end); | |
6437 | template <class U> bool append(const U *begin, size_t length); | |
6438 | template <class U, size_t O, class BP> bool append(const Vector<U,O,BP> &other); | |
6439 | void popBack(); | |
6440 | T popCopy(); | |
6441 | T *extractRawBuffer(); | |
6442 | void replaceRawBuffer(T *p, size_t length); | |
6443 | bool insert(T *p, const T &val); | |
6444 | void erase(T *t); | |
6445 | }; | |
6446 | template <class T, size_t N, class AllocPolicy> | |
6447 | __attribute__((always_inline)) inline | |
6448 | Vector<T,N,AllocPolicy>::Vector(AllocPolicy ap) | |
6449 | : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), | |
6450 | mCapacity(sInlineCapacity) | |
6451 | {} | |
6452 | template <class T, size_t N, class AP> | |
6453 | __attribute__((always_inline)) inline | |
6454 | Vector<T,N,AP>::~Vector() | |
6455 | { | |
6456 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6457 | Impl::destroy(beginNoCheck(), endNoCheck()); | |
6458 | if (!usingInlineStorage()) | |
6459 | this->free(beginNoCheck()); | |
6460 | } | |
6461 | template <class T, size_t N, class AP> | |
6462 | inline | |
6463 | bool | |
6464 | Vector<T,N,AP>::calculateNewCapacity(size_t curLength, size_t lengthInc, | |
6465 | size_t &newCap) | |
6466 | { | |
6467 | size_t newMinCap = curLength + lengthInc; | |
6468 | if (newMinCap < curLength || | |
6469 | newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) { | |
6470 | this->reportAllocOverflow(); | |
6471 | return false; | |
6472 | } | |
6473 | newCap = RoundUpPow2(newMinCap); | |
6474 | if (newCap & tl::UnsafeRangeSizeMask<T>::result) { | |
6475 | this->reportAllocOverflow(); | |
6476 | return false; | |
6477 | } | |
6478 | return true; | |
6479 | } | |
6480 | template <class T, size_t N, class AP> | |
6481 | __attribute__((always_inline)) inline | |
6482 | bool | |
6483 | Vector<T,N,AP>::growHeapStorageBy(size_t lengthInc) | |
6484 | { | |
6485 | ((void) 0); | |
6486 | size_t newCap; | |
6487 | return calculateNewCapacity(mLength, lengthInc, newCap) && | |
6488 | Impl::growTo(*this, newCap); | |
6489 | } | |
6490 | template <class T, size_t N, class AP> | |
6491 | inline | |
6492 | bool | |
6493 | Vector<T,N,AP>::convertToHeapStorage(size_t lengthInc) | |
6494 | { | |
6495 | ((void) 0); | |
6496 | size_t newCap; | |
6497 | if (!calculateNewCapacity(mLength, lengthInc, newCap)) | |
6498 | return false; | |
6499 | T *newBuf = reinterpret_cast<T *>(this->malloc(newCap * sizeof(T))); | |
6500 | if (!newBuf) | |
6501 | return false; | |
6502 | Impl::copyConstruct(newBuf, beginNoCheck(), endNoCheck()); | |
6503 | Impl::destroy(beginNoCheck(), endNoCheck()); | |
6504 | mBegin = newBuf; | |
6505 | mCapacity = newCap; | |
6506 | return true; | |
6507 | } | |
6508 | template <class T, size_t N, class AP> | |
6509 | __attribute__((noinline)) | |
6510 | bool | |
6511 | Vector<T,N,AP>::growStorageBy(size_t incr) | |
6512 | { | |
6513 | ((void) 0); | |
6514 | return usingInlineStorage() | |
6515 | ? convertToHeapStorage(incr) | |
6516 | : growHeapStorageBy(incr); | |
6517 | } | |
6518 | template <class T, size_t N, class AP> | |
6519 | inline | |
6520 | bool | |
6521 | Vector<T,N,AP>::reserve(size_t request) | |
6522 | { | |
6523 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6524 | if (request > mCapacity) | |
6525 | return growStorageBy(request - mLength); | |
6526 | return true; | |
6527 | } | |
6528 | template <class T, size_t N, class AP> | |
6529 | inline void | |
6530 | Vector<T,N,AP>::shrinkBy(size_t incr) | |
6531 | { | |
6532 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6533 | ((void) 0); | |
6534 | Impl::destroy(endNoCheck() - incr, endNoCheck()); | |
6535 | mLength -= incr; | |
6536 | } | |
6537 | template <class T, size_t N, class AP> | |
6538 | template <bool InitNewElems> | |
6539 | __attribute__((always_inline)) inline | |
6540 | bool | |
6541 | Vector<T,N,AP>::growByImpl(size_t incr) | |
6542 | { | |
6543 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6544 | if (incr > mCapacity - mLength && !growStorageBy(incr)) | |
6545 | return false; | |
6546 | ((void) 0); | |
6547 | T *newend = endNoCheck() + incr; | |
6548 | if (InitNewElems) | |
6549 | Impl::initialize(endNoCheck(), newend); | |
6550 | mLength += incr; | |
6551 | return true; | |
6552 | } | |
6553 | template <class T, size_t N, class AP> | |
6554 | __attribute__((always_inline)) inline | |
6555 | bool | |
6556 | Vector<T,N,AP>::growBy(size_t incr) | |
6557 | { | |
6558 | return growByImpl<true>(incr); | |
6559 | } | |
6560 | template <class T, size_t N, class AP> | |
6561 | __attribute__((always_inline)) inline | |
6562 | bool | |
6563 | Vector<T,N,AP>::growByUninitialized(size_t incr) | |
6564 | { | |
6565 | return growByImpl<false>(incr); | |
6566 | } | |
6567 | template <class T, size_t N, class AP> | |
6568 | inline | |
6569 | bool | |
6570 | Vector<T,N,AP>::resize(size_t newLength) | |
6571 | { | |
6572 | size_t curLength = mLength; | |
6573 | if (newLength > curLength) | |
6574 | return growBy(newLength - curLength); | |
6575 | shrinkBy(curLength - newLength); | |
6576 | return true; | |
6577 | } | |
6578 | template <class T, size_t N, class AP> | |
6579 | __attribute__((always_inline)) inline | |
6580 | bool | |
6581 | Vector<T,N,AP>::resizeUninitialized(size_t newLength) | |
6582 | { | |
6583 | size_t curLength = mLength; | |
6584 | if (newLength > curLength) | |
6585 | return growByUninitialized(newLength - curLength); | |
6586 | shrinkBy(curLength - newLength); | |
6587 | return true; | |
6588 | } | |
6589 | template <class T, size_t N, class AP> | |
6590 | inline void | |
6591 | Vector<T,N,AP>::clear() | |
6592 | { | |
6593 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6594 | Impl::destroy(beginNoCheck(), endNoCheck()); | |
6595 | mLength = 0; | |
6596 | } | |
6597 | template <class T, size_t N, class AP> | |
6598 | __attribute__((always_inline)) inline | |
6599 | bool | |
6600 | Vector<T,N,AP>::append(const T &t) | |
6601 | { | |
6602 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6603 | if (mLength == mCapacity && !growStorageBy(1)) | |
6604 | return false; | |
6605 | ((void) 0); | |
6606 | new(endNoCheck()) T(t); | |
6607 | ++mLength; | |
6608 | return true; | |
6609 | } | |
6610 | template <class T, size_t N, class AP> | |
6611 | __attribute__((always_inline)) inline | |
6612 | bool | |
6613 | Vector<T,N,AP>::appendN(const T &t, size_t needed) | |
6614 | { | |
6615 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6616 | if (mLength + needed > mCapacity && !growStorageBy(needed)) | |
6617 | return false; | |
6618 | ((void) 0); | |
6619 | Impl::copyConstructN(endNoCheck(), needed, t); | |
6620 | mLength += needed; | |
6621 | return true; | |
6622 | } | |
6623 | template <class T, size_t N, class AP> | |
6624 | inline | |
6625 | bool | |
6626 | Vector<T,N,AP>::insert(T *p, const T &val) | |
6627 | { | |
6628 | ((void) 0); | |
6629 | size_t pos = p - begin(); | |
6630 | ((void) 0); | |
6631 | size_t oldLength = mLength; | |
6632 | if (pos == oldLength) | |
6633 | return append(val); | |
6634 | { | |
6635 | T oldBack = back(); | |
6636 | if (!append(oldBack)) | |
6637 | return false; | |
6638 | } | |
6639 | for (size_t i = oldLength; i > pos; --i) | |
6640 | (*this)[i] = (*this)[i - 1]; | |
6641 | (*this)[pos] = val; | |
6642 | return true; | |
6643 | } | |
6644 | template<typename T, size_t N, class AP> | |
6645 | inline void | |
6646 | Vector<T,N,AP>::erase(T *it) | |
6647 | { | |
6648 | ((void) 0); | |
6649 | while (it + 1 != end()) { | |
6650 | *it = *(it + 1); | |
6651 | ++it; | |
6652 | } | |
6653 | popBack(); | |
6654 | } | |
6655 | template <class T, size_t N, class AP> | |
6656 | template <class U> | |
6657 | __attribute__((always_inline)) inline | |
6658 | bool | |
6659 | Vector<T,N,AP>::append(const U *insBegin, const U *insEnd) | |
6660 | { | |
6661 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6662 | size_t needed = PointerRangeSize(insBegin, insEnd); | |
6663 | if (mLength + needed > mCapacity && !growStorageBy(needed)) | |
6664 | return false; | |
6665 | ((void) 0); | |
6666 | Impl::copyConstruct(endNoCheck(), insBegin, insEnd); | |
6667 | mLength += needed; | |
6668 | return true; | |
6669 | } | |
6670 | template <class T, size_t N, class AP> | |
6671 | template <class U, size_t O, class BP> | |
6672 | inline | |
6673 | bool | |
6674 | Vector<T,N,AP>::append(const Vector<U,O,BP> &other) | |
6675 | { | |
6676 | return append(other.begin(), other.end()); | |
6677 | } | |
6678 | template <class T, size_t N, class AP> | |
6679 | template <class U> | |
6680 | __attribute__((always_inline)) inline | |
6681 | bool | |
6682 | Vector<T,N,AP>::append(const U *insBegin, size_t length) | |
6683 | { | |
6684 | return this->append(insBegin, insBegin + length); | |
6685 | } | |
6686 | template <class T, size_t N, class AP> | |
6687 | __attribute__((always_inline)) inline void | |
6688 | Vector<T,N,AP>::popBack() | |
6689 | { | |
6690 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6691 | ((void) 0); | |
6692 | --mLength; | |
6693 | endNoCheck()->~T(); | |
6694 | } | |
6695 | template <class T, size_t N, class AP> | |
6696 | __attribute__((always_inline)) inline T | |
6697 | Vector<T,N,AP>::popCopy() | |
6698 | { | |
6699 | T ret = back(); | |
6700 | popBack(); | |
6701 | return ret; | |
6702 | } | |
6703 | template <class T, size_t N, class AP> | |
6704 | inline T * | |
6705 | Vector<T,N,AP>::extractRawBuffer() | |
6706 | { | |
6707 | T *ret; | |
6708 | if (usingInlineStorage()) { | |
6709 | ret = reinterpret_cast<T *>(this->malloc(mLength * sizeof(T))); | |
6710 | if (!ret) | |
6711 | return __null; | |
6712 | Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); | |
6713 | Impl::destroy(beginNoCheck(), endNoCheck()); | |
6714 | mLength = 0; | |
6715 | } else { | |
6716 | ret = mBegin; | |
6717 | mBegin = (T *)storage.addr(); | |
6718 | mLength = 0; | |
6719 | mCapacity = sInlineCapacity; | |
6720 | } | |
6721 | return ret; | |
6722 | } | |
6723 | template <class T, size_t N, class AP> | |
6724 | inline void | |
6725 | Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length) | |
6726 | { | |
6727 | ReentrancyGuard g(*this); ((void) 0); ((void) 0); | |
6728 | Impl::destroy(beginNoCheck(), endNoCheck()); | |
6729 | if (!usingInlineStorage()) | |
6730 | this->free(beginNoCheck()); | |
6731 | if (length <= sInlineCapacity) { | |
6732 | mBegin = (T *)storage.addr(); | |
6733 | mLength = length; | |
6734 | mCapacity = sInlineCapacity; | |
6735 | Impl::copyConstruct(mBegin, p, p + length); | |
6736 | Impl::destroy(p, p + length); | |
6737 | this->free(p); | |
6738 | } else { | |
6739 | mBegin = p; | |
6740 | mLength = length; | |
6741 | mCapacity = length; | |
6742 | } | |
6743 | } | |
6744 | } | |
6745 | struct JSCompartment; | |
6746 | namespace js { | |
6747 | namespace gc { | |
6748 | template <typename T> struct Arena; | |
6749 | struct ArenaBitmap; | |
6750 | struct MarkingDelay; | |
6751 | struct Chunk; | |
6752 | struct FreeCell; | |
6753 | struct Cell { | |
6754 | static const size_t CellShift = 3; | |
6755 | static const size_t CellSize = size_t(1) << CellShift; | |
6756 | static const size_t CellMask = CellSize - 1; | |
6757 | inline Arena<Cell> *arena() const; | |
6758 | inline Chunk *chunk() const; | |
6759 | inline ArenaBitmap *bitmap() const; | |
6760 | __attribute__((always_inline)) inline size_t cellIndex() const; | |
6761 | __attribute__((always_inline)) inline bool isMarked(uint32 color) const; | |
6762 | __attribute__((always_inline)) inline bool markIfUnmarked(uint32 color) const; | |
6763 | __attribute__((always_inline)) inline void unmark(uint32 color) const; | |
6764 | inline JSCompartment *compartment() const; | |
6765 | __attribute__((always_inline)) inline js::gc::Cell *asCell() { return this; } | |
6766 | __attribute__((always_inline)) inline js::gc::FreeCell *asFreeCell() { | |
6767 | return reinterpret_cast<FreeCell *>(this); | |
6768 | } | |
6769 | }; | |
6770 | struct FreeCell : Cell { | |
6771 | union { | |
6772 | FreeCell *link; | |
6773 | double data; | |
6774 | }; | |
6775 | }; | |
6776 | typedef int js_static_assert36[(sizeof(FreeCell) == 8) ? 1 : -1]; | |
6777 | } | |
6778 | } | |
6779 | namespace js { | |
6780 | class JSProxyHandler; | |
6781 | class AutoPropDescArrayRooter; | |
6782 | namespace mjit { | |
6783 | class Compiler; | |
6784 | } | |
6785 | static inline PropertyOp | |
6786 | CastAsPropertyOp(JSObject *object) | |
6787 | { | |
6788 | return (__extension__ (PropertyOp) (size_t) (object)); | |
6789 | } | |
6790 | static inline StrictPropertyOp | |
6791 | CastAsStrictPropertyOp(JSObject *object) | |
6792 | { | |
6793 | return (__extension__ (StrictPropertyOp) (size_t) (object)); | |
6794 | } | |
6795 | static inline JSPropertyOp | |
6796 | CastAsJSPropertyOp(JSObject *object) | |
6797 | { | |
6798 | return (__extension__ (JSPropertyOp) (size_t) (object)); | |
6799 | } | |
6800 | static inline JSStrictPropertyOp | |
6801 | CastAsJSStrictPropertyOp(JSObject *object) | |
6802 | { | |
6803 | return (__extension__ (JSStrictPropertyOp) (size_t) (object)); | |
6804 | } | |
6805 | inline JSObject * | |
6806 | CastAsObject(PropertyOp op) | |
6807 | { | |
6808 | return (__extension__ (JSObject *) (size_t) (op)); | |
6809 | } | |
6810 | inline JSObject * | |
6811 | CastAsObject(StrictPropertyOp op) | |
6812 | { | |
6813 | return (__extension__ (JSObject *) (size_t) (op)); | |
6814 | } | |
6815 | inline Value | |
6816 | CastAsObjectJsval(PropertyOp op) | |
6817 | { | |
6818 | return ObjectOrNullValue(CastAsObject(op)); | |
6819 | } | |
6820 | inline Value | |
6821 | CastAsObjectJsval(StrictPropertyOp op) | |
6822 | { | |
6823 | return ObjectOrNullValue(CastAsObject(op)); | |
6824 | } | |
6825 | } | |
6826 | struct PropDesc { | |
6827 | friend class js::AutoPropDescArrayRooter; | |
6828 | PropDesc(); | |
6829 | public: | |
6830 | bool initialize(JSContext* cx, jsid id, const js::Value &v); | |
6831 | bool isAccessorDescriptor() const { | |
6832 | return hasGet || hasSet; | |
6833 | } | |
6834 | bool isDataDescriptor() const { | |
6835 | return hasValue || hasWritable; | |
6836 | } | |
6837 | bool isGenericDescriptor() const { | |
6838 | return !isAccessorDescriptor() && !isDataDescriptor(); | |
6839 | } | |
6840 | bool configurable() const { | |
6841 | return (attrs & 0x04) == 0; | |
6842 | } | |
6843 | bool enumerable() const { | |
6844 | return (attrs & 0x01) != 0; | |
6845 | } | |
6846 | bool writable() const { | |
6847 | return (attrs & 0x02) == 0; | |
6848 | } | |
6849 | JSObject* getterObject() const { | |
6850 | return get.isUndefined() ? __null : &get.toObject(); | |
6851 | } | |
6852 | JSObject* setterObject() const { | |
6853 | return set.isUndefined() ? __null : &set.toObject(); | |
6854 | } | |
6855 | const js::Value &getterValue() const { | |
6856 | return get; | |
6857 | } | |
6858 | const js::Value &setterValue() const { | |
6859 | return set; | |
6860 | } | |
6861 | js::PropertyOp getter() const { | |
6862 | return js::CastAsPropertyOp(getterObject()); | |
6863 | } | |
6864 | js::StrictPropertyOp setter() const { | |
6865 | return js::CastAsStrictPropertyOp(setterObject()); | |
6866 | } | |
6867 | js::Value pd; | |
6868 | jsid id; | |
6869 | js::Value value, get, set; | |
6870 | uint8 attrs; | |
6871 | bool hasGet : 1; | |
6872 | bool hasSet : 1; | |
6873 | bool hasValue : 1; | |
6874 | bool hasWritable : 1; | |
6875 | bool hasEnumerable : 1; | |
6876 | bool hasConfigurable : 1; | |
6877 | }; | |
6878 | namespace js { | |
6879 | typedef Vector<PropDesc, 1> PropDescArray; | |
6880 | } | |
6881 | struct JSObjectMap { | |
6882 | uint32 shape; | |
6883 | uint32 slotSpan; | |
6884 | static __attribute__((visibility ("default"))) const JSObjectMap sharedNonNative; | |
6885 | explicit JSObjectMap(uint32 shape) : shape(shape), slotSpan(0) {} | |
6886 | JSObjectMap(uint32 shape, uint32 slotSpan) : shape(shape), slotSpan(slotSpan) {} | |
6887 | enum { INVALID_SHAPE = 0x8fffffff, SHAPELESS = 0xffffffff }; | |
6888 | bool isNative() const { return this != &sharedNonNative; } | |
6889 | private: | |
6890 | JSObjectMap(JSObjectMap &); | |
6891 | void operator=(JSObjectMap &); | |
6892 | }; | |
6893 | extern __attribute__((visibility ("default"))) JSBool | |
6894 | js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |
6895 | JSProperty **propp); | |
6896 | extern JSBool | |
6897 | js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value, | |
6898 | js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs); | |
6899 | extern JSBool | |
6900 | js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp); | |
6901 | inline JSBool | |
6902 | js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp) | |
6903 | { | |
6904 | return js_GetProperty(cx, obj, obj, id, vp); | |
6905 | } | |
6906 | namespace js { | |
6907 | extern JSBool | |
6908 | GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp); | |
6909 | } | |
6910 | extern JSBool | |
6911 | js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp, JSBool strict); | |
6912 | extern JSBool | |
6913 | js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); | |
6914 | extern JSBool | |
6915 | js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); | |
6916 | extern JSBool | |
6917 | js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict); | |
6918 | extern __attribute__((visibility ("default"))) JSBool | |
6919 | js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, | |
6920 | js::Value *statep, jsid *idp); | |
6921 | extern JSType | |
6922 | js_TypeOf(JSContext *cx, JSObject *obj); | |
6923 | namespace js { | |
6924 | struct NativeIterator; | |
6925 | } | |
6926 | struct JSFunction; | |
6927 | namespace nanojit { | |
6928 | class ValidateWriter; | |
6929 | } | |
6930 | struct JSObject : js::gc::Cell { | |
6931 | friend class js::TraceRecorder; | |
6932 | friend class nanojit::ValidateWriter; | |
6933 | friend class GetPropCompiler; | |
6934 | union { | |
6935 | js::Shape *lastProp; | |
6936 | JSObjectMap *map; | |
6937 | }; | |
6938 | js::Class *clasp; | |
6939 | private: | |
6940 | inline void setLastProperty(const js::Shape *shape); | |
6941 | inline void removeLastProperty(); | |
6942 | public: | |
6943 | inline const js::Shape *lastProperty() const; | |
6944 | inline js::Shape **nativeSearch(jsid id, bool adding = false); | |
6945 | inline const js::Shape *nativeLookup(jsid id); | |
6946 | inline bool nativeContains(jsid id); | |
6947 | inline bool nativeContains(const js::Shape &shape); | |
6948 | enum { | |
6949 | DELEGATE = 0x01, | |
6950 | SYSTEM = 0x02, | |
6951 | NOT_EXTENSIBLE = 0x04, | |
6952 | BRANDED = 0x08, | |
6953 | GENERIC = 0x10, | |
6954 | METHOD_BARRIER = 0x20, | |
6955 | INDEXED = 0x40, | |
6956 | OWN_SHAPE = 0x80, | |
6957 | BOUND_FUNCTION = 0x100, | |
6958 | HAS_EQUALITY = 0x200, | |
6959 | METHOD_THRASH_COUNT_MASK = 0xc00, | |
6960 | METHOD_THRASH_COUNT_SHIFT = 10, | |
6961 | METHOD_THRASH_COUNT_MAX = METHOD_THRASH_COUNT_MASK >> METHOD_THRASH_COUNT_SHIFT | |
6962 | }; | |
6963 | enum { | |
6964 | NSLOTS_BITS = 29, | |
6965 | NSLOTS_LIMIT = ((JSUint32)1 << (NSLOTS_BITS)) | |
6966 | }; | |
6967 | uint32 flags; | |
6968 | uint32 objShape; | |
6969 | js::EmptyShape **emptyShapes; | |
6970 | JSObject *proto; | |
6971 | JSObject *parent; | |
6972 | void *privateData; | |
6973 | jsuword capacity; | |
6974 | js::Value *slots; | |
6975 | inline bool canProvideEmptyShape(js::Class *clasp); | |
6976 | inline js::EmptyShape *getEmptyShape(JSContext *cx, js::Class *aclasp, | |
6977 | unsigned kind); | |
6978 | bool isNative() const { return map->isNative(); } | |
6979 | js::Class *getClass() const { return clasp; } | |
6980 | JSClass *getJSClass() const { return Jsvalify(clasp); } | |
6981 | bool hasClass(const js::Class *c) const { | |
6982 | return c == clasp; | |
6983 | } | |
6984 | const js::ObjectOps *getOps() const { | |
6985 | return &getClass()->ops; | |
6986 | } | |
6987 | inline void trace(JSTracer *trc); | |
6988 | uint32 shape() const { | |
6989 | ((void) 0); | |
6990 | return objShape; | |
6991 | } | |
6992 | bool isDelegate() const { return !!(flags & DELEGATE); } | |
6993 | void setDelegate() { flags |= DELEGATE; } | |
6994 | void clearDelegate() { flags &= ~DELEGATE; } | |
6995 | bool isBoundFunction() const { return !!(flags & BOUND_FUNCTION); } | |
6996 | static void setDelegateNullSafe(JSObject *obj) { | |
6997 | if (obj) | |
6998 | obj->setDelegate(); | |
6999 | } | |
7000 | bool isSystem() const { return !!(flags & SYSTEM); } | |
7001 | void setSystem() { flags |= SYSTEM; } | |
7002 | bool branded() { return !!(flags & BRANDED); } | |
7003 | bool brand(JSContext *cx); | |
7004 | bool unbrand(JSContext *cx); | |
7005 | bool generic() { return !!(flags & GENERIC); } | |
7006 | void setGeneric() { flags |= GENERIC; } | |
7007 | uintN getMethodThrashCount() const { | |
7008 | return (flags & METHOD_THRASH_COUNT_MASK) >> METHOD_THRASH_COUNT_SHIFT; | |
7009 | } | |
7010 | void setMethodThrashCount(uintN count) { | |
7011 | ((void) 0); | |
7012 | flags = (flags & ~METHOD_THRASH_COUNT_MASK) | (count << METHOD_THRASH_COUNT_SHIFT); | |
7013 | } | |
7014 | bool hasSpecialEquality() const { return !!(flags & HAS_EQUALITY); } | |
7015 | void assertSpecialEqualitySynced() const { | |
7016 | ((void) 0); | |
7017 | } | |
7018 | inline void syncSpecialEquality(); | |
7019 | private: | |
7020 | void generateOwnShape(JSContext *cx); | |
7021 | void setOwnShape(uint32 s) { flags |= OWN_SHAPE; objShape = s; } | |
7022 | void clearOwnShape() { flags &= ~OWN_SHAPE; objShape = map->shape; } | |
7023 | public: | |
7024 | inline bool nativeEmpty() const; | |
7025 | bool hasOwnShape() const { return !!(flags & OWN_SHAPE); } | |
7026 | void setMap(const JSObjectMap *amap) { | |
7027 | ((void) 0); | |
7028 | map = const_cast<JSObjectMap *>(amap); | |
7029 | objShape = map->shape; | |
7030 | } | |
7031 | void setSharedNonNativeMap() { | |
7032 | setMap(&JSObjectMap::sharedNonNative); | |
7033 | } | |
7034 | void deletingShapeChange(JSContext *cx, const js::Shape &shape); | |
7035 | const js::Shape *methodShapeChange(JSContext *cx, const js::Shape &shape); | |
7036 | bool methodShapeChange(JSContext *cx, uint32 slot); | |
7037 | void protoShapeChange(JSContext *cx); | |
7038 | void shadowingShapeChange(JSContext *cx, const js::Shape &shape); | |
7039 | bool globalObjectOwnShapeChange(JSContext *cx); | |
7040 | void watchpointOwnShapeChange(JSContext *cx) { generateOwnShape(cx); } | |
7041 | void extensibleShapeChange(JSContext *cx) { | |
7042 | generateOwnShape(cx); | |
7043 | } | |
7044 | bool hasMethodBarrier() { return !!(flags & METHOD_BARRIER); } | |
7045 | void setMethodBarrier() { flags |= METHOD_BARRIER; } | |
7046 | bool brandedOrHasMethodBarrier() { return !!(flags & (BRANDED | METHOD_BARRIER)); } | |
7047 | const js::Shape *methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp); | |
7048 | const js::Shape *methodWriteBarrier(JSContext *cx, const js::Shape &shape, const js::Value &v); | |
7049 | bool methodWriteBarrier(JSContext *cx, uint32 slot, const js::Value &v); | |
7050 | bool isIndexed() const { return !!(flags & INDEXED); } | |
7051 | void setIndexed() { flags |= INDEXED; } | |
7052 | inline bool inDictionaryMode() const; | |
7053 | inline uint32 propertyCount() const; | |
7054 | inline bool hasPropertyTable() const; | |
7055 | unsigned finalizeKind() const; | |
7056 | uint32 numSlots() const { return capacity; } | |
7057 | size_t slotsAndStructSize(uint32 nslots) const; | |
7058 | size_t slotsAndStructSize() const { return slotsAndStructSize(numSlots()); } | |
7059 | inline js::Value* fixedSlots() const; | |
7060 | inline size_t numFixedSlots() const; | |
7061 | static inline size_t getFixedSlotOffset(size_t slot); | |
7062 | public: | |
7063 | static const uint32 SLOT_CAPACITY_MIN = 8; | |
7064 | bool allocSlots(JSContext *cx, size_t nslots); | |
7065 | bool growSlots(JSContext *cx, size_t nslots); | |
7066 | void shrinkSlots(JSContext *cx, size_t nslots); | |
7067 | bool ensureSlots(JSContext *cx, size_t nslots) { | |
7068 | if (numSlots() < nslots) | |
7069 | return growSlots(cx, nslots); | |
7070 | return true; | |
7071 | } | |
7072 | bool ensureInstanceReservedSlots(JSContext *cx, size_t nreserved); | |
7073 | js::Value *getSlots() const { | |
7074 | return slots; | |
7075 | } | |
7076 | bool ensureClassReservedSlotsForEmptyObject(JSContext *cx); | |
7077 | inline bool ensureClassReservedSlots(JSContext *cx); | |
7078 | uint32 slotSpan() const { return map->slotSpan; } | |
7079 | bool containsSlot(uint32 slot) const { return slot < slotSpan(); } | |
7080 | js::Value& getSlotRef(uintN slot) { | |
7081 | ((void) 0); | |
7082 | return slots[slot]; | |
7083 | } | |
7084 | js::Value &nativeGetSlotRef(uintN slot) { | |
7085 | ((void) 0); | |
7086 | ((void) 0); | |
7087 | return getSlotRef(slot); | |
7088 | } | |
7089 | const js::Value &getSlot(uintN slot) const { | |
7090 | ((void) 0); | |
7091 | return slots[slot]; | |
7092 | } | |
7093 | const js::Value &nativeGetSlot(uintN slot) const { | |
7094 | ((void) 0); | |
7095 | ((void) 0); | |
7096 | return getSlot(slot); | |
7097 | } | |
7098 | void setSlot(uintN slot, const js::Value &value) { | |
7099 | ((void) 0); | |
7100 | slots[slot] = value; | |
7101 | } | |
7102 | void nativeSetSlot(uintN slot, const js::Value &value) { | |
7103 | ((void) 0); | |
7104 | ((void) 0); | |
7105 | return setSlot(slot, value); | |
7106 | } | |
7107 | inline js::Value getReservedSlot(uintN index) const; | |
7108 | inline void updateShape(JSContext *cx); | |
7109 | inline void updateFlags(const js::Shape *shape, bool isDefinitelyAtom = false); | |
7110 | inline void extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom = false); | |
7111 | JSObject *getProto() const { return proto; } | |
7112 | void clearProto() { proto = __null; } | |
7113 | void setProto(JSObject *newProto) { | |
7114 | setDelegateNullSafe(newProto); | |
7115 | proto = newProto; | |
7116 | } | |
7117 | JSObject *getParent() const { | |
7118 | return parent; | |
7119 | } | |
7120 | void clearParent() { | |
7121 | parent = __null; | |
7122 | } | |
7123 | void setParent(JSObject *newParent) { | |
7124 | setDelegateNullSafe(newParent); | |
7125 | parent = newParent; | |
7126 | } | |
7127 | __attribute__((visibility ("default"))) JSObject * getGlobal() const; | |
7128 | bool isGlobal() const { | |
7129 | return !!(getClass()->flags & (1<<((8 + 8)+2))); | |
7130 | } | |
7131 | void *getPrivate() const { | |
7132 | ((void) 0); | |
7133 | return privateData; | |
7134 | } | |
7135 | void setPrivate(void *data) { | |
7136 | ((void) 0); | |
7137 | privateData = data; | |
7138 | } | |
7139 | private: | |
7140 | enum ImmutabilityType { SEAL, FREEZE }; | |
7141 | bool sealOrFreeze(JSContext *cx, ImmutabilityType it); | |
7142 | public: | |
7143 | bool isExtensible() const { return !(flags & NOT_EXTENSIBLE); } | |
7144 | bool preventExtensions(JSContext *cx, js::AutoIdVector *props); | |
7145 | inline bool seal(JSContext *cx) { return sealOrFreeze(cx, SEAL); } | |
7146 | bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); } | |
7147 | private: | |
7148 | static const uint32 JSSLOT_PRIMITIVE_THIS = 0; | |
7149 | public: | |
7150 | inline const js::Value &getPrimitiveThis() const; | |
7151 | inline void setPrimitiveThis(const js::Value &pthis); | |
7152 | inline uint32 getArrayLength() const; | |
7153 | inline void setArrayLength(uint32 length); | |
7154 | inline uint32 getDenseArrayCapacity(); | |
7155 | inline js::Value* getDenseArrayElements(); | |
7156 | inline const js::Value &getDenseArrayElement(uintN idx); | |
7157 | inline js::Value* addressOfDenseArrayElement(uintN idx); | |
7158 | inline void setDenseArrayElement(uintN idx, const js::Value &val); | |
7159 | inline void shrinkDenseArrayElements(JSContext *cx, uintN cap); | |
7160 | enum EnsureDenseResult { ED_OK, ED_FAILED, ED_SPARSE }; | |
7161 | inline EnsureDenseResult ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra); | |
7162 | bool willBeSparseDenseArray(uintN requiredCapacity, uintN newElementsHint); | |
7163 | JSBool makeDenseArraySlow(JSContext *cx); | |
7164 | private: | |
7165 | static const uint32 JSSLOT_ARGS_DATA = 1; | |
7166 | public: | |
7167 | static const uint32 JSSLOT_ARGS_LENGTH = 0; | |
7168 | static const uint32 ARGS_CLASS_RESERVED_SLOTS = 2; | |
7169 | static const uint32 ARGS_FIRST_FREE_SLOT = ARGS_CLASS_RESERVED_SLOTS + 1; | |
7170 | static const uint32 ARGS_LENGTH_OVERRIDDEN_BIT = 0x1; | |
7171 | static const uint32 ARGS_PACKED_BITS_COUNT = 1; | |
7172 | inline void setArgsLength(uint32 argc); | |
7173 | inline uint32 getArgsInitialLength() const; | |
7174 | inline void setArgsLengthOverridden(); | |
7175 | inline bool isArgsLengthOverridden() const; | |
7176 | inline js::ArgumentsData *getArgsData() const; | |
7177 | inline void setArgsData(js::ArgumentsData *data); | |
7178 | inline const js::Value &getArgsCallee() const; | |
7179 | inline void setArgsCallee(const js::Value &callee); | |
7180 | inline const js::Value &getArgsElement(uint32 i) const; | |
7181 | inline js::Value *getArgsElements() const; | |
7182 | inline js::Value *addressOfArgsElement(uint32 i); | |
7183 | inline void setArgsElement(uint32 i, const js::Value &v); | |
7184 | private: | |
7185 | static const uint32 JSSLOT_CALL_CALLEE = 0; | |
7186 | static const uint32 JSSLOT_CALL_ARGUMENTS = 1; | |
7187 | public: | |
7188 | static const uint32 CALL_RESERVED_SLOTS = 2; | |
7189 | inline bool callIsForEval() const; | |
7190 | inline JSStackFrame *maybeCallObjStackFrame() const; | |
7191 | inline JSObject *getCallObjCallee() const; | |
7192 | inline JSFunction *getCallObjCalleeFunction() const; | |
7193 | inline void setCallObjCallee(JSObject *callee); | |
7194 | inline const js::Value &getCallObjArguments() const; | |
7195 | inline void setCallObjArguments(const js::Value &v); | |
7196 | inline const js::Value &callObjArg(uintN i) const; | |
7197 | inline js::Value &callObjArg(uintN i); | |
7198 | inline const js::Value &callObjVar(uintN i) const; | |
7199 | inline js::Value &callObjVar(uintN i); | |
7200 | static const uint32 JSSLOT_DATE_UTC_TIME = 0; | |
7201 | static const uint32 JSSLOT_DATE_COMPONENTS_START = 1; | |
7202 | static const uint32 JSSLOT_DATE_LOCAL_TIME = 1; | |
7203 | static const uint32 JSSLOT_DATE_LOCAL_YEAR = 2; | |
7204 | static const uint32 JSSLOT_DATE_LOCAL_MONTH = 3; | |
7205 | static const uint32 JSSLOT_DATE_LOCAL_DATE = 4; | |
7206 | static const uint32 JSSLOT_DATE_LOCAL_DAY = 5; | |
7207 | static const uint32 JSSLOT_DATE_LOCAL_HOURS = 6; | |
7208 | static const uint32 JSSLOT_DATE_LOCAL_MINUTES = 7; | |
7209 | static const uint32 JSSLOT_DATE_LOCAL_SECONDS = 8; | |
7210 | static const uint32 DATE_CLASS_RESERVED_SLOTS = 9; | |
7211 | inline const js::Value &getDateUTCTime() const; | |
7212 | inline void setDateUTCTime(const js::Value &pthis); | |
7213 | private: | |
7214 | friend struct JSFunction; | |
7215 | friend class js::mjit::Compiler; | |
7216 | static const uint32 JSSLOT_FLAT_CLOSURE_UPVARS = 0; | |
7217 | static const uint32 JSSLOT_FUN_METHOD_ATOM = 0; | |
7218 | static const uint32 JSSLOT_FUN_METHOD_OBJ = 1; | |
7219 | static const uint32 JSSLOT_BOUND_FUNCTION_THIS = 0; | |
7220 | static const uint32 JSSLOT_BOUND_FUNCTION_ARGS_COUNT = 1; | |
7221 | public: | |
7222 | static const uint32 FUN_CLASS_RESERVED_SLOTS = 2; | |
7223 | inline JSFunction *getFunctionPrivate() const; | |
7224 | inline js::Value *getFlatClosureUpvars() const; | |
7225 | inline js::Value getFlatClosureUpvar(uint32 i) const; | |
7226 | inline js::Value &getFlatClosureUpvar(uint32 i); | |
7227 | inline void setFlatClosureUpvars(js::Value *upvars); | |
7228 | inline bool hasMethodObj(const JSObject& obj) const; | |
7229 | inline void setMethodObj(JSObject& obj); | |
7230 | inline bool initBoundFunction(JSContext *cx, const js::Value &thisArg, | |
7231 | const js::Value *args, uintN argslen); | |
7232 | inline JSObject *getBoundFunctionTarget() const; | |
7233 | inline const js::Value &getBoundFunctionThis() const; | |
7234 | inline const js::Value *getBoundFunctionArguments(uintN &argslen) const; | |
7235 | private: | |
7236 | static const uint32 JSSLOT_REGEXP_LAST_INDEX = 0; | |
7237 | public: | |
7238 | static const uint32 REGEXP_CLASS_RESERVED_SLOTS = 1; | |
7239 | inline const js::Value &getRegExpLastIndex() const; | |
7240 | inline void setRegExpLastIndex(const js::Value &v); | |
7241 | inline void setRegExpLastIndex(jsdouble d); | |
7242 | inline void zeroRegExpLastIndex(); | |
7243 | inline js::NativeIterator *getNativeIterator() const; | |
7244 | inline void setNativeIterator(js::NativeIterator *); | |
7245 | inline JSScript *getScript() const; | |
7246 | private: | |
7247 | static const uint32 JSSLOT_NAME_PREFIX = 0; | |
7248 | static const uint32 JSSLOT_NAME_URI = 1; | |
7249 | static const uint32 JSSLOT_NAMESPACE_DECLARED = 2; | |
7250 | static const uint32 JSSLOT_QNAME_LOCAL_NAME = 2; | |
7251 | public: | |
7252 | static const uint32 NAMESPACE_CLASS_RESERVED_SLOTS = 3; | |
7253 | static const uint32 QNAME_CLASS_RESERVED_SLOTS = 3; | |
7254 | inline JSLinearString *getNamePrefix() const; | |
7255 | inline jsval getNamePrefixVal() const; | |
7256 | inline void setNamePrefix(JSLinearString *prefix); | |
7257 | inline void clearNamePrefix(); | |
7258 | inline JSLinearString *getNameURI() const; | |
7259 | inline jsval getNameURIVal() const; | |
7260 | inline void setNameURI(JSLinearString *uri); | |
7261 | inline jsval getNamespaceDeclared() const; | |
7262 | inline void setNamespaceDeclared(jsval decl); | |
7263 | inline JSLinearString *getQNameLocalName() const; | |
7264 | inline jsval getQNameLocalNameVal() const; | |
7265 | inline void setQNameLocalName(JSLinearString *name); | |
7266 | inline js::JSProxyHandler *getProxyHandler() const; | |
7267 | inline const js::Value &getProxyPrivate() const; | |
7268 | inline void setProxyPrivate(const js::Value &priv); | |
7269 | inline const js::Value &getProxyExtra() const; | |
7270 | inline void setProxyExtra(const js::Value &extra); | |
7271 | inline JSObject *getWithThis() const; | |
7272 | inline void setWithThis(JSObject *thisp); | |
7273 | inline bool isCallable(); | |
7274 | void init(JSContext *cx, js::Class *aclasp, JSObject *proto, JSObject *parent, | |
7275 | void *priv, bool useHoles); | |
7276 | inline void finish(JSContext *cx); | |
7277 | __attribute__((always_inline)) inline void finalize(JSContext *cx); | |
7278 | inline bool initSharingEmptyShape(JSContext *cx, | |
7279 | js::Class *clasp, | |
7280 | JSObject *proto, | |
7281 | JSObject *parent, | |
7282 | void *priv, | |
7283 | unsigned kind); | |
7284 | inline bool hasSlotsArray() const; | |
7285 | inline void freeSlotsArray(JSContext *cx); | |
7286 | inline void revertToFixedSlots(JSContext *cx); | |
7287 | inline bool hasProperty(JSContext *cx, jsid id, bool *foundp, uintN flags = 0); | |
7288 | bool allocSlot(JSContext *cx, uint32 *slotp); | |
7289 | bool freeSlot(JSContext *cx, uint32 slot); | |
7290 | public: | |
7291 | bool reportReadOnly(JSContext* cx, jsid id, uintN report = 0x0); | |
7292 | bool reportNotConfigurable(JSContext* cx, jsid id, uintN report = 0x0); | |
7293 | bool reportNotExtensible(JSContext *cx, uintN report = 0x0); | |
7294 | private: | |
7295 | js::Shape *getChildProperty(JSContext *cx, js::Shape *parent, js::Shape &child); | |
7296 | const js::Shape *addPropertyInternal(JSContext *cx, jsid id, | |
7297 | js::PropertyOp getter, js::StrictPropertyOp setter, | |
7298 | uint32 slot, uintN attrs, | |
7299 | uintN flags, intN shortid, | |
7300 | js::Shape **spp); | |
7301 | bool toDictionaryMode(JSContext *cx); | |
7302 | public: | |
7303 | const js::Shape *addProperty(JSContext *cx, jsid id, | |
7304 | js::PropertyOp getter, js::StrictPropertyOp setter, | |
7305 | uint32 slot, uintN attrs, | |
7306 | uintN flags, intN shortid); | |
7307 | const js::Shape *addDataProperty(JSContext *cx, jsid id, uint32 slot, uintN attrs) { | |
7308 | ((void) 0); | |
7309 | return addProperty(cx, id, __null, __null, slot, attrs, 0, 0); | |
7310 | } | |
7311 | const js::Shape *putProperty(JSContext *cx, jsid id, | |
7312 | js::PropertyOp getter, js::StrictPropertyOp setter, | |
7313 | uint32 slot, uintN attrs, | |
7314 | uintN flags, intN shortid); | |
7315 | const js::Shape *changeProperty(JSContext *cx, const js::Shape *shape, uintN attrs, uintN mask, | |
7316 | js::PropertyOp getter, js::StrictPropertyOp setter); | |
7317 | bool removeProperty(JSContext *cx, jsid id); | |
7318 | void clear(JSContext *cx); | |
7319 | JSBool lookupProperty(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp) { | |
7320 | js::LookupPropOp op = getOps()->lookupProperty; | |
7321 | return (op ? op : js_LookupProperty)(cx, this, id, objp, propp); | |
7322 | } | |
7323 | JSBool defineProperty(JSContext *cx, jsid id, const js::Value &value, | |
7324 | js::PropertyOp getter = js::PropertyStub, | |
7325 | js::StrictPropertyOp setter = js::StrictPropertyStub, | |
7326 | uintN attrs = 0x01) { | |
7327 | js::DefinePropOp op = getOps()->defineProperty; | |
7328 | return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs); | |
7329 | } | |
7330 | JSBool getProperty(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp) { | |
7331 | js::PropertyIdOp op = getOps()->getProperty; | |
7332 | return (op ? op : (js::PropertyIdOp)js_GetProperty)(cx, this, receiver, id, vp); | |
7333 | } | |
7334 | JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) { | |
7335 | return getProperty(cx, this, id, vp); | |
7336 | } | |
7337 | JSBool setProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict) { | |
7338 | js::StrictPropertyIdOp op = getOps()->setProperty; | |
7339 | return (op ? op : js_SetProperty)(cx, this, id, vp, strict); | |
7340 | } | |
7341 | JSBool getAttributes(JSContext *cx, jsid id, uintN *attrsp) { | |
7342 | js::AttributesOp op = getOps()->getAttributes; | |
7343 | return (op ? op : js_GetAttributes)(cx, this, id, attrsp); | |
7344 | } | |
7345 | JSBool setAttributes(JSContext *cx, jsid id, uintN *attrsp) { | |
7346 | js::AttributesOp op = getOps()->setAttributes; | |
7347 | return (op ? op : js_SetAttributes)(cx, this, id, attrsp); | |
7348 | } | |
7349 | JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval, JSBool strict) { | |
7350 | js::DeleteIdOp op = getOps()->deleteProperty; | |
7351 | return (op ? op : js_DeleteProperty)(cx, this, id, rval, strict); | |
7352 | } | |
7353 | JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) { | |
7354 | js::NewEnumerateOp op = getOps()->enumerate; | |
7355 | return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp); | |
7356 | } | |
7357 | JSType typeOf(JSContext *cx) { | |
7358 | js::TypeOfOp op = getOps()->typeOf; | |
7359 | return (op ? op : js_TypeOf)(cx, this); | |
7360 | } | |
7361 | JSObject *thisObject(JSContext *cx) { | |
7362 | JSObjectOp op = getOps()->thisObject; | |
7363 | return op ? op(cx, this) : this; | |
7364 | } | |
7365 | static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp); | |
7366 | inline JSCompartment *getCompartment() const; | |
7367 | inline JSObject *getThrowTypeError() const; | |
7368 | __attribute__((visibility ("default"))) JSObject * clone(JSContext *cx, JSObject *proto, JSObject *parent); | |
7369 | __attribute__((visibility ("default"))) bool copyPropertiesFrom(JSContext *cx, JSObject *obj); | |
7370 | bool swap(JSContext *cx, JSObject *other); | |
7371 | const js::Shape *defineBlockVariable(JSContext *cx, jsid id, intN index); | |
7372 | inline bool canHaveMethodBarrier() const; | |
7373 | inline bool isArguments() const; | |
7374 | inline bool isNormalArguments() const; | |
7375 | inline bool isStrictArguments() const; | |
7376 | inline bool isArray() const; | |
7377 | inline bool isDenseArray() const; | |
7378 | inline bool isSlowArray() const; | |
7379 | inline bool isNumber() const; | |
7380 | inline bool isBoolean() const; | |
7381 | inline bool isString() const; | |
7382 | inline bool isPrimitive() const; | |
7383 | inline bool isDate() const; | |
7384 | inline bool isFunction() const; | |
7385 | inline bool isObject() const; | |
7386 | inline bool isWith() const; | |
7387 | inline bool isBlock() const; | |
7388 | inline bool isStaticBlock() const; | |
7389 | inline bool isClonedBlock() const; | |
7390 | inline bool isCall() const; | |
7391 | inline bool isRegExp() const; | |
7392 | inline bool isScript() const; | |
7393 | inline bool isXML() const; | |
7394 | inline bool isXMLId() const; | |
7395 | inline bool isNamespace() const; | |
7396 | inline bool isQName() const; | |
7397 | inline bool isProxy() const; | |
7398 | inline bool isObjectProxy() const; | |
7399 | inline bool isFunctionProxy() const; | |
7400 | __attribute__((visibility ("default"))) bool isWrapper() const; | |
7401 | __attribute__((visibility ("default"))) JSObject * unwrap(uintN *flagsp = __null); | |
7402 | inline void initArrayClass(); | |
7403 | }; | |
7404 | typedef int js_static_assert37[(sizeof(JSObject) % sizeof(js::Value) == 0) ? 1 : -1]; | |
7405 | inline js::Value* | |
7406 | JSObject::fixedSlots() const { | |
7407 | return (js::Value*) (jsuword(this) + sizeof(JSObject)); | |
7408 | } | |
7409 | inline | |
7410 | bool | |
7411 | JSObject::hasSlotsArray() const { return this->slots != fixedSlots(); } | |
7412 | inline size_t | |
7413 | JSObject::getFixedSlotOffset(size_t slot) { | |
7414 | return sizeof(JSObject) + (slot * sizeof(js::Value)); | |
7415 | } | |
7416 | struct JSObject_Slots2 : JSObject { js::Value fslots[2]; }; | |
7417 | struct JSObject_Slots4 : JSObject { js::Value fslots[4]; }; | |
7418 | struct JSObject_Slots8 : JSObject { js::Value fslots[8]; }; | |
7419 | struct JSObject_Slots12 : JSObject { js::Value fslots[12]; }; | |
7420 | struct JSObject_Slots16 : JSObject { js::Value fslots[16]; }; | |
7421 | inline void | |
7422 | OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj) | |
7423 | { | |
7424 | if (JSObjectOp op = obj->getClass()->ext.innerObject) | |
7425 | obj = op(cx, obj); | |
7426 | } | |
7427 | inline void | |
7428 | OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj) | |
7429 | { | |
7430 | if (JSObjectOp op = obj->getClass()->ext.outerObject) | |
7431 | obj = op(cx, obj); | |
7432 | } | |
7433 | class JSValueArray { | |
7434 | public: | |
7435 | jsval *array; | |
7436 | size_t length; | |
7437 | JSValueArray(jsval *v, size_t c) : array(v), length(c) {} | |
7438 | }; | |
7439 | class ValueArray { | |
7440 | public: | |
7441 | js::Value *array; | |
7442 | size_t length; | |
7443 | ValueArray(js::Value *v, size_t c) : array(v), length(c) {} | |
7444 | }; | |
7445 | extern js::Class js_ObjectClass; | |
7446 | extern js::Class js_WithClass; | |
7447 | extern js::Class js_BlockClass; | |
7448 | inline bool JSObject::isObject() const { return getClass() == &js_ObjectClass; } | |
7449 | inline bool JSObject::isWith() const { return getClass() == &js_WithClass; } | |
7450 | inline bool JSObject::isBlock() const { return getClass() == &js_BlockClass; } | |
7451 | static const uint32 JSSLOT_BLOCK_DEPTH = 0; | |
7452 | static const uint32 JSSLOT_BLOCK_FIRST_FREE_SLOT = JSSLOT_BLOCK_DEPTH + 1; | |
7453 | inline | |
7454 | bool | |
7455 | JSObject::isStaticBlock() const | |
7456 | { | |
7457 | return isBlock() && !getProto(); | |
7458 | } | |
7459 | inline | |
7460 | bool | |
7461 | JSObject::isClonedBlock() const | |
7462 | { | |
7463 | return isBlock() && !!getProto(); | |
7464 | } | |
7465 | static const uint32 JSSLOT_WITH_THIS = 1; | |
7466 | extern JSObject * | |
7467 | js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth); | |
7468 | inline JSObject * | |
7469 | js_UnwrapWithObject(JSContext *cx, JSObject *withobj) | |
7470 | { | |
7471 | ((void) 0); | |
7472 | return withobj->getProto(); | |
7473 | } | |
7474 | extern JSObject * | |
7475 | js_NewBlockObject(JSContext *cx); | |
7476 | extern JSObject * | |
7477 | js_CloneBlockObject(JSContext *cx, JSObject *proto, JSStackFrame *fp); | |
7478 | extern JSBool | |
7479 | js_PutBlockObject(JSContext *cx, JSBool normalUnwind); | |
7480 | JSBool | |
7481 | js_XDRBlockObject(JSXDRState *xdr, JSObject **objp); | |
7482 | struct JSSharpObjectMap { | |
7483 | jsrefcount depth; | |
7484 | jsatomid sharpgen; | |
7485 | JSHashTable *table; | |
7486 | }; | |
7487 | extern JSHashEntry * | |
7488 | js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, | |
7489 | jschar **sp); | |
7490 | extern void | |
7491 | js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); | |
7492 | extern void | |
7493 | js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map); | |
7494 | extern JSBool | |
7495 | js_HasOwnPropertyHelper(JSContext *cx, js::LookupPropOp lookup, uintN argc, | |
7496 | js::Value *vp); | |
7497 | extern JSBool | |
7498 | js_HasOwnProperty(JSContext *cx, js::LookupPropOp lookup, JSObject *obj, jsid id, | |
7499 | JSObject **objp, JSProperty **propp); | |
7500 | extern JSBool | |
7501 | js_NewPropertyDescriptorObject(JSContext *cx, jsid id, uintN attrs, | |
7502 | const js::Value &getter, const js::Value &setter, | |
7503 | const js::Value &value, js::Value *vp); | |
7504 | extern JSBool | |
7505 | js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
7506 | __attribute__((visibility ("default"))) JSBool js_obj_defineGetter(JSContext *cx, uintN argc, js::Value *vp); | |
7507 | __attribute__((visibility ("default"))) JSBool js_obj_defineSetter(JSContext *cx, uintN argc, js::Value *vp); | |
7508 | extern JSObject * | |
7509 | js_InitObjectClass(JSContext *cx, JSObject *obj); | |
7510 | namespace js { | |
7511 | JSObject * | |
7512 | DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom, | |
7513 | JSObject *protoProto, Class *clasp, | |
7514 | Native constructor, uintN nargs, | |
7515 | JSPropertySpec *ps, JSFunctionSpec *fs, | |
7516 | JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | |
7517 | } | |
7518 | extern JSObject * | |
7519 | js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, | |
7520 | js::Class *clasp, js::Native constructor, uintN nargs, | |
7521 | JSPropertySpec *ps, JSFunctionSpec *fs, | |
7522 | JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | |
7523 | extern const char js_watch_str[]; | |
7524 | extern const char js_unwatch_str[]; | |
7525 | extern const char js_hasOwnProperty_str[]; | |
7526 | extern const char js_isPrototypeOf_str[]; | |
7527 | extern const char js_propertyIsEnumerable_str[]; | |
7528 | extern const char js_defineGetter_str[]; | |
7529 | extern const char js_defineSetter_str[]; | |
7530 | extern const char js_lookupGetter_str[]; | |
7531 | extern const char js_lookupSetter_str[]; | |
7532 | extern JSBool | |
7533 | js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props); | |
7534 | extern JSBool | |
7535 | js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | |
7536 | JSObject **objp); | |
7537 | extern JSBool | |
7538 | js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | |
7539 | JSObject *cobj, JSObject *prototype); | |
7540 | extern JSBool | |
7541 | js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key, | |
7542 | js::Value *vp, js::Class *clasp = __null); | |
7543 | extern JSObject * | |
7544 | js_ConstructObject(JSContext *cx, js::Class *clasp, JSObject *proto, | |
7545 | JSObject *parent, uintN argc, js::Value *argv); | |
7546 | extern JSObject * | |
7547 | js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *proto); | |
7548 | extern JSObject * | |
7549 | js_CreateThisForFunction(JSContext *cx, JSObject *callee); | |
7550 | extern JSObject * | |
7551 | js_CreateThis(JSContext *cx, JSObject *callee); | |
7552 | extern jsid | |
7553 | js_CheckForStringIndex(jsid id); | |
7554 | extern void | |
7555 | js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id); | |
7556 | inline void | |
7557 | js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id) | |
7558 | { | |
7559 | if (obj->isDelegate()) | |
7560 | js_PurgeScopeChainHelper(cx, obj, id); | |
7561 | } | |
7562 | extern const js::Shape * | |
7563 | js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, | |
7564 | js::PropertyOp getter, js::StrictPropertyOp setter, uint32 slot, | |
7565 | uintN attrs, uintN flags, intN shortid); | |
7566 | extern const js::Shape * | |
7567 | js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, | |
7568 | const js::Shape *shape, uintN attrs, uintN mask, | |
7569 | js::PropertyOp getter, js::StrictPropertyOp setter); | |
7570 | extern JSBool | |
7571 | js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, | |
7572 | const js::Value &descriptor, JSBool *bp); | |
7573 | const uintN JSDNP_CACHE_RESULT = 1; | |
7574 | const uintN JSDNP_DONT_PURGE = 2; | |
7575 | const uintN JSDNP_SET_METHOD = 4; | |
7576 | const uintN JSDNP_UNQUALIFIED = 8; | |
7577 | extern JSBool | |
7578 | js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value, | |
7579 | js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs, | |
7580 | uintN flags, intN shortid, JSProperty **propp, | |
7581 | uintN defineHow = 0); | |
7582 | extern int | |
7583 | js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags, | |
7584 | JSObject **objp, JSProperty **propp); | |
7585 | extern __attribute__((visibility ("default"))) js::Class js_CallClass; | |
7586 | extern __attribute__((visibility ("default"))) js::Class js_DeclEnvClass; | |
7587 | namespace js { | |
7588 | static inline | |
7589 | bool | |
7590 | IsCacheableNonGlobalScope(JSObject *obj) | |
7591 | { | |
7592 | ((void) 0); | |
7593 | js::Class *clasp = obj->getClass(); | |
7594 | bool cacheable = (clasp == &js_CallClass || | |
7595 | clasp == &js_BlockClass || | |
7596 | clasp == &js_DeclEnvClass); | |
7597 | ((void) 0); | |
7598 | return cacheable; | |
7599 | } | |
7600 | } | |
7601 | extern js::PropertyCacheEntry * | |
7602 | js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult, | |
7603 | JSObject **objp, JSObject **pobjp, JSProperty **propp); | |
7604 | extern __attribute__((visibility ("default"))) JSBool | |
7605 | js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, | |
7606 | JSProperty **propp); | |
7607 | extern JSObject * | |
7608 | js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id); | |
7609 | extern JSObject * | |
7610 | js_FindVariableScope(JSContext *cx, JSFunction **funp); | |
7611 | const uintN JSGET_CACHE_RESULT = 1; | |
7612 | const uintN JSGET_METHOD_BARRIER = 0; | |
7613 | const uintN JSGET_NO_METHOD_BARRIER = 2; | |
7614 | extern JSBool | |
7615 | js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const js::Shape *shape, uintN getHow, | |
7616 | js::Value *vp); | |
7617 | extern JSBool | |
7618 | js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added, | |
7619 | bool strict, js::Value *vp); | |
7620 | extern JSBool | |
7621 | js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, js::Value *vp); | |
7622 | extern | |
7623 | bool | |
7624 | js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, | |
7625 | uint32 getHow, js::Value *vp, | |
7626 | const js::Shape **shapeOut, JSObject **holderOut); | |
7627 | extern JSBool | |
7628 | js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
7629 | extern JSBool | |
7630 | js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp); | |
7631 | extern __attribute__((visibility ("default"))) bool | |
7632 | js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname); | |
7633 | extern JSBool | |
7634 | js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, | |
7635 | js::Value *vp, JSBool strict); | |
7636 | extern JSBool | |
7637 | js_SetNativeAttributes(JSContext *cx, JSObject *obj, js::Shape *shape, | |
7638 | uintN attrs); | |
7639 | namespace js { | |
7640 | extern JSObject * | |
7641 | HasNativeMethod(JSObject *obj, jsid methodid, Native native); | |
7642 | extern | |
7643 | bool | |
7644 | DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp); | |
7645 | extern JSBool | |
7646 | CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | |
7647 | js::Value *vp, uintN *attrsp); | |
7648 | } | |
7649 | extern | |
7650 | bool | |
7651 | js_IsDelegate(JSContext *cx, JSObject *obj, const js::Value &v); | |
7652 | extern __attribute__((visibility ("default"))) JSBool | |
7653 | js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, | |
7654 | JSObject **protop, js::Class *clasp = __null); | |
7655 | extern JSBool | |
7656 | js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, | |
7657 | uintN attrs); | |
7658 | extern JSBool | |
7659 | js_PrimitiveToObject(JSContext *cx, js::Value *vp); | |
7660 | extern JSBool | |
7661 | js_ValueToObjectOrNull(JSContext *cx, const js::Value &v, JSObject **objp); | |
7662 | namespace js { | |
7663 | extern JSObject * | |
7664 | ToObjectSlow(JSContext *cx, js::Value *vp); | |
7665 | __attribute__((always_inline)) inline JSObject * | |
7666 | ToObject(JSContext *cx, js::Value *vp) | |
7667 | { | |
7668 | if (vp->isObject()) | |
7669 | return &vp->toObject(); | |
7670 | return ToObjectSlow(cx, vp); | |
7671 | } | |
7672 | } | |
7673 | extern JSObject * | |
7674 | js_ValueToNonNullObject(JSContext *cx, const js::Value &v); | |
7675 | extern JSBool | |
7676 | js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, js::Value *rval); | |
7677 | extern JSBool | |
7678 | js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, | |
7679 | uintN argc, js::Value *argv, js::Value *rval); | |
7680 | extern JSBool | |
7681 | js_XDRObject(JSXDRState *xdr, JSObject **objp); | |
7682 | extern void | |
7683 | js_TraceObject(JSTracer *trc, JSObject *obj); | |
7684 | extern void | |
7685 | js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize); | |
7686 | extern void | |
7687 | js_ClearNative(JSContext *cx, JSObject *obj); | |
7688 | extern | |
7689 | bool | |
7690 | js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp); | |
7691 | extern | |
7692 | bool | |
7693 | js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const js::Value &v); | |
7694 | extern JSBool | |
7695 | js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, | |
7696 | JSPrincipals *principals, JSAtom *caller); | |
7697 | extern JSBool | |
7698 | js_CheckContentSecurityPolicy(JSContext *cx, JSObject *scopeObj); | |
7699 | extern const char * | |
7700 | js_ComputeFilename(JSContext *cx, JSStackFrame *caller, | |
7701 | JSPrincipals *principals, uintN *linenop); | |
7702 | extern JSBool | |
7703 | js_ReportGetterOnlyAssignment(JSContext *cx); | |
7704 | extern __attribute__((visibility ("default"))) JSBool | |
7705 | js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); | |
7706 | extern uintN | |
7707 | js_InferFlags(JSContext *cx, uintN defaultFlags); | |
7708 | JSBool | |
7709 | js_Object(JSContext *cx, uintN argc, js::Value *vp); | |
7710 | namespace js { | |
7711 | extern | |
7712 | bool | |
7713 | SetProto(JSContext *cx, JSObject *obj, JSObject *proto, bool checkForCycles); | |
7714 | extern JSString * | |
7715 | obj_toStringHelper(JSContext *cx, JSObject *obj); | |
7716 | enum EvalType { INDIRECT_EVAL, DIRECT_EVAL }; | |
7717 | extern | |
7718 | bool | |
7719 | EvalKernel(JSContext *cx, uintN argc, js::Value *vp, EvalType evalType, JSStackFrame *caller, | |
7720 | JSObject *scopeobj); | |
7721 | extern __attribute__((visibility ("default"))) bool | |
7722 | IsBuiltinEvalFunction(JSFunction *fun); | |
7723 | } | |
7724 | enum { | |
7725 | UNIT_STRING_LIMIT = 256U, | |
7726 | SMALL_CHAR_LIMIT = 128U, | |
7727 | NUM_SMALL_CHARS = 64U, | |
7728 | INT_STRING_LIMIT = 256U, | |
7729 | NUM_HUNDRED_STRINGS = 156U | |
7730 | }; | |
7731 | extern jschar * | |
7732 | js_GetDependentStringChars(JSString *str); | |
7733 | extern JSString * | |
7734 | js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); | |
7735 | typedef int js_static_assert38[((8 * 8) >= 32) ? 1 : -1]; | |
7736 | struct JSRopeBufferInfo { | |
7737 | size_t capacity; | |
7738 | }; | |
7739 | namespace js { namespace mjit { | |
7740 | class Compiler; | |
7741 | }} | |
7742 | struct JSLinearString; | |
7743 | struct JSString | |
7744 | { | |
7745 | friend class js::TraceRecorder; | |
7746 | friend class js::mjit::Compiler; | |
7747 | friend JSAtom *js_AtomizeString(JSContext *cx, JSString *str, uintN flags); | |
7748 | size_t lengthAndFlags; | |
7749 | union { | |
7750 | const jschar *chars; | |
7751 | JSString *left; | |
7752 | } u; | |
7753 | union { | |
7754 | jschar inlineStorage[4]; | |
7755 | struct { | |
7756 | union { | |
7757 | JSString *right; | |
7758 | JSString *base; | |
7759 | size_t capacity; | |
7760 | }; | |
7761 | union { | |
7762 | JSString *parent; | |
7763 | size_t reserved; | |
7764 | }; | |
7765 | } s; | |
7766 | size_t externalStringType; | |
7767 | }; | |
7768 | static const size_t TYPE_FLAGS_MASK = (((JSUint32)1 << (4)) - 1); | |
7769 | static const size_t LENGTH_SHIFT = 4; | |
7770 | static const size_t TYPE_MASK = (((JSUint32)1 << (2)) - 1); | |
7771 | static const size_t FLAT = 0x0; | |
7772 | static const size_t DEPENDENT = 0x1; | |
7773 | static const size_t ROPE = 0x2; | |
7774 | static const size_t DEPENDENT_BIT = ((JSUint32)1 << (0)); | |
7775 | static const size_t ROPE_BIT = ((JSUint32)1 << (1)); | |
7776 | static const size_t ATOMIZED = ((JSUint32)1 << (2)); | |
7777 | static const size_t EXTENSIBLE = ((JSUint32)1 << (3)); | |
7778 | size_t buildLengthAndFlags(size_t length, size_t flags) { | |
7779 | return (length << LENGTH_SHIFT) | flags; | |
7780 | } | |
7781 | inline js::gc::Cell *asCell() { | |
7782 | return reinterpret_cast<js::gc::Cell *>(this); | |
7783 | } | |
7784 | inline js::gc::FreeCell *asFreeCell() { | |
7785 | return reinterpret_cast<js::gc::FreeCell *>(this); | |
7786 | } | |
7787 | static const size_t MAX_LENGTH = (1 << 28) - 1; | |
7788 | __attribute__((always_inline)) inline bool isDependent() const { | |
7789 | return lengthAndFlags & DEPENDENT_BIT; | |
7790 | } | |
7791 | __attribute__((always_inline)) inline bool isFlat() const { | |
7792 | return (lengthAndFlags & TYPE_MASK) == FLAT; | |
7793 | } | |
7794 | __attribute__((always_inline)) inline bool isExtensible() const { | |
7795 | ((void) 0); | |
7796 | return lengthAndFlags & EXTENSIBLE; | |
7797 | } | |
7798 | __attribute__((always_inline)) inline bool isAtomized() const { | |
7799 | ((void) 0); | |
7800 | return lengthAndFlags & ATOMIZED; | |
7801 | } | |
7802 | __attribute__((always_inline)) inline bool isRope() const { | |
7803 | return lengthAndFlags & ROPE_BIT; | |
7804 | } | |
7805 | __attribute__((always_inline)) inline size_t length() const { | |
7806 | return lengthAndFlags >> LENGTH_SHIFT; | |
7807 | } | |
7808 | __attribute__((always_inline)) inline bool empty() const { | |
7809 | return lengthAndFlags <= TYPE_FLAGS_MASK; | |
7810 | } | |
7811 | __attribute__((always_inline)) inline const jschar *getChars(JSContext *cx) { | |
7812 | if (isRope()) | |
7813 | return flatten(cx); | |
7814 | return nonRopeChars(); | |
7815 | } | |
7816 | __attribute__((always_inline)) inline const jschar *getCharsZ(JSContext *cx) { | |
7817 | if (!isFlat()) | |
7818 | return undepend(cx); | |
7819 | return flatChars(); | |
7820 | } | |
7821 | __attribute__((always_inline)) inline void initFlatNotTerminated(jschar *chars, size_t length) { | |
7822 | ((void) 0); | |
7823 | ((void) 0); | |
7824 | lengthAndFlags = buildLengthAndFlags(length, FLAT); | |
7825 | u.chars = chars; | |
7826 | } | |
7827 | __attribute__((always_inline)) inline void initFlat(jschar *chars, size_t length) { | |
7828 | initFlatNotTerminated(chars, length); | |
7829 | ((void) 0); | |
7830 | } | |
7831 | __attribute__((always_inline)) inline void initShortString(const jschar *chars, size_t length) { | |
7832 | ((void) 0); | |
7833 | ((void) 0); | |
7834 | ((void) 0); | |
7835 | lengthAndFlags = buildLengthAndFlags(length, FLAT); | |
7836 | u.chars = chars; | |
7837 | } | |
7838 | __attribute__((always_inline)) inline void initFlatExtensible(jschar *chars, size_t length, size_t cap) { | |
7839 | ((void) 0); | |
7840 | ((void) 0); | |
7841 | ((void) 0); | |
7842 | lengthAndFlags = buildLengthAndFlags(length, FLAT | EXTENSIBLE); | |
7843 | u.chars = chars; | |
7844 | s.capacity = cap; | |
7845 | } | |
7846 | __attribute__((always_inline)) inline JSFlatString *assertIsFlat() { | |
7847 | ((void) 0); | |
7848 | return reinterpret_cast<JSFlatString *>(this); | |
7849 | } | |
7850 | __attribute__((always_inline)) inline const jschar *flatChars() const { | |
7851 | ((void) 0); | |
7852 | return u.chars; | |
7853 | } | |
7854 | __attribute__((always_inline)) inline size_t flatLength() const { | |
7855 | ((void) 0); | |
7856 | return length(); | |
7857 | } | |
7858 | inline void flatSetAtomized() { | |
7859 | ((void) 0); | |
7860 | ((void) 0); | |
7861 | lengthAndFlags |= ATOMIZED; | |
7862 | } | |
7863 | inline void flatClearExtensible() { | |
7864 | ((void) 0); | |
7865 | if (lengthAndFlags & EXTENSIBLE) | |
7866 | lengthAndFlags &= ~EXTENSIBLE; | |
7867 | } | |
7868 | inline void initDependent(JSString *base, const jschar *chars, size_t length) { | |
7869 | ((void) 0); | |
7870 | ((void) 0); | |
7871 | ((void) 0); | |
7872 | ((void) 0); | |
7873 | lengthAndFlags = buildLengthAndFlags(length, DEPENDENT); | |
7874 | u.chars = chars; | |
7875 | s.base = base; | |
7876 | } | |
7877 | inline JSLinearString *dependentBase() const { | |
7878 | ((void) 0); | |
7879 | return s.base->assertIsLinear(); | |
7880 | } | |
7881 | __attribute__((always_inline)) inline const jschar *dependentChars() { | |
7882 | ((void) 0); | |
7883 | return u.chars; | |
7884 | } | |
7885 | inline size_t dependentLength() const { | |
7886 | ((void) 0); | |
7887 | return length(); | |
7888 | } | |
7889 | const jschar *undepend(JSContext *cx); | |
7890 | const jschar *nonRopeChars() const { | |
7891 | ((void) 0); | |
7892 | return u.chars; | |
7893 | } | |
7894 | inline void initRopeNode(JSString *left, JSString *right, size_t length) { | |
7895 | ((void) 0); | |
7896 | lengthAndFlags = buildLengthAndFlags(length, ROPE); | |
7897 | u.left = left; | |
7898 | s.right = right; | |
7899 | } | |
7900 | inline JSString *ropeLeft() const { | |
7901 | ((void) 0); | |
7902 | return u.left; | |
7903 | } | |
7904 | inline JSString *ropeRight() const { | |
7905 | ((void) 0); | |
7906 | return s.right; | |
7907 | } | |
7908 | inline void finishTraversalConversion(JSString *base, const jschar *baseBegin, const jschar *end) { | |
7909 | ((void) 0); | |
7910 | lengthAndFlags = buildLengthAndFlags(end - u.chars, DEPENDENT); | |
7911 | s.base = base; | |
7912 | } | |
7913 | const jschar *flatten(JSContext *maybecx); | |
7914 | JSLinearString *ensureLinear(JSContext *cx) { | |
7915 | if (isRope() && !flatten(cx)) | |
7916 | return __null; | |
7917 | return reinterpret_cast<JSLinearString *>(this); | |
7918 | } | |
7919 | bool isLinear() const { | |
7920 | return !isRope(); | |
7921 | } | |
7922 | JSLinearString *assertIsLinear() { | |
7923 | ((void) 0); | |
7924 | return reinterpret_cast<JSLinearString *>(this); | |
7925 | } | |
7926 | typedef uint8 SmallChar; | |
7927 | static inline bool fitsInSmallChar(jschar c) { | |
7928 | return c < SMALL_CHAR_LIMIT && toSmallChar[c] != INVALID_SMALL_CHAR; | |
7929 | } | |
7930 | static inline bool isUnitString(void *ptr) { | |
7931 | jsuword delta = reinterpret_cast<jsuword>(ptr) - | |
7932 | reinterpret_cast<jsuword>(unitStringTable); | |
7933 | if (delta >= UNIT_STRING_LIMIT * sizeof(JSString)) | |
7934 | return false; | |
7935 | ((void) 0); | |
7936 | return true; | |
7937 | } | |
7938 | static inline bool isLength2String(void *ptr) { | |
7939 | jsuword delta = reinterpret_cast<jsuword>(ptr) - | |
7940 | reinterpret_cast<jsuword>(length2StringTable); | |
7941 | if (delta >= NUM_SMALL_CHARS * NUM_SMALL_CHARS * sizeof(JSString)) | |
7942 | return false; | |
7943 | ((void) 0); | |
7944 | return true; | |
7945 | } | |
7946 | static inline bool isHundredString(void *ptr) { | |
7947 | jsuword delta = reinterpret_cast<jsuword>(ptr) - | |
7948 | reinterpret_cast<jsuword>(hundredStringTable); | |
7949 | if (delta >= NUM_HUNDRED_STRINGS * sizeof(JSString)) | |
7950 | return false; | |
7951 | ((void) 0); | |
7952 | return true; | |
7953 | } | |
7954 | static inline bool isStatic(void *ptr) { | |
7955 | return isUnitString(ptr) || isLength2String(ptr) || isHundredString(ptr); | |
7956 | } | |
7957 | static const SmallChar INVALID_SMALL_CHAR = -1; | |
7958 | static const jschar fromSmallChar[]; | |
7959 | static const SmallChar toSmallChar[]; | |
7960 | static const JSString unitStringTable[]; | |
7961 | static const JSString length2StringTable[]; | |
7962 | static const JSString hundredStringTable[]; | |
7963 | static const JSString *const intStringTable[]; | |
7964 | static JSFlatString *unitString(jschar c); | |
7965 | static JSLinearString *getUnitString(JSContext *cx, JSString *str, size_t index); | |
7966 | static JSFlatString *length2String(jschar c1, jschar c2); | |
7967 | static JSFlatString *length2String(uint32 i); | |
7968 | static JSFlatString *intString(jsint i); | |
7969 | static JSFlatString *lookupStaticString(const jschar *chars, size_t length); | |
7970 | __attribute__((always_inline)) inline void finalize(JSContext *cx); | |
7971 | static size_t offsetOfLengthAndFlags() { | |
7972 | return __builtin_offsetof (JSString, lengthAndFlags); | |
7973 | } | |
7974 | static size_t offsetOfChars() { | |
7975 | return __builtin_offsetof (JSString, u.chars); | |
7976 | } | |
7977 | static void staticAsserts() { | |
7978 | typedef int js_static_assert39[(((JSString::MAX_LENGTH << JSString::LENGTH_SHIFT) >> JSString::LENGTH_SHIFT) == JSString::MAX_LENGTH) ? 1 : -1] | |
7979 | ; | |
7980 | } | |
7981 | }; | |
7982 | struct JSLinearString : JSString | |
7983 | { | |
7984 | const jschar *chars() const { return JSString::nonRopeChars(); } | |
7985 | }; | |
7986 | typedef int js_static_assert40[(sizeof(JSLinearString) == sizeof(JSString)) ? 1 : -1]; | |
7987 | struct JSFlatString : JSLinearString | |
7988 | { | |
7989 | const jschar *charsZ() const { return chars(); } | |
7990 | }; | |
7991 | typedef int js_static_assert41[(sizeof(JSFlatString) == sizeof(JSString)) ? 1 : -1]; | |
7992 | struct JSAtom : JSFlatString | |
7993 | { | |
7994 | }; | |
7995 | struct JSExternalString : JSString | |
7996 | { | |
7997 | static const uintN TYPE_LIMIT = 8; | |
7998 | static JSStringFinalizeOp str_finalizers[TYPE_LIMIT]; | |
7999 | static intN changeFinalizer(JSStringFinalizeOp oldop, | |
8000 | JSStringFinalizeOp newop) { | |
8001 | for (uintN i = 0; i != (sizeof (str_finalizers) / sizeof (str_finalizers)[0]); i++) { | |
8002 | if (str_finalizers[i] == oldop) { | |
8003 | str_finalizers[i] = newop; | |
8004 | return intN(i); | |
8005 | } | |
8006 | } | |
8007 | return -1; | |
8008 | } | |
8009 | void finalize(JSContext *cx); | |
8010 | void finalize(); | |
8011 | }; | |
8012 | typedef int js_static_assert42[(sizeof(JSString) == sizeof(JSExternalString)) ? 1 : -1]; | |
8013 | class JSShortString : public js::gc::Cell | |
8014 | { | |
8015 | JSString mHeader; | |
8016 | JSString mDummy; | |
8017 | public: | |
8018 | inline jschar *init(size_t length) { | |
8019 | ((void) 0); | |
8020 | mHeader.initShortString(mHeader.inlineStorage, length); | |
8021 | return mHeader.inlineStorage; | |
8022 | } | |
8023 | inline jschar *getInlineStorageBeforeInit() { | |
8024 | return mHeader.inlineStorage; | |
8025 | } | |
8026 | inline void initAtOffsetInBuffer(jschar *p, size_t length) { | |
8027 | ((void) 0); | |
8028 | mHeader.initShortString(p, length); | |
8029 | } | |
8030 | inline void resetLength(size_t length) { | |
8031 | mHeader.initShortString(mHeader.flatChars(), length); | |
8032 | } | |
8033 | inline JSString *header() { | |
8034 | return &mHeader; | |
8035 | } | |
8036 | static const size_t FREE_STRING_WORDS = 2; | |
8037 | static const size_t MAX_SHORT_STRING_LENGTH = | |
8038 | ((sizeof(JSString) + FREE_STRING_WORDS * sizeof(size_t)) / sizeof(jschar)) - 1; | |
8039 | static inline bool fitsIntoShortString(size_t length) { | |
8040 | return length <= MAX_SHORT_STRING_LENGTH; | |
8041 | } | |
8042 | __attribute__((always_inline)) inline void finalize(JSContext *cx); | |
8043 | static void staticAsserts() { | |
8044 | typedef int js_static_assert43[(__builtin_offsetof (JSString, inlineStorage) == sizeof(JSString) - JSShortString::FREE_STRING_WORDS * sizeof(void *)) ? 1 : -1] | |
8045 | ; | |
8046 | typedef int js_static_assert44[(__builtin_offsetof (JSShortString, mDummy) == sizeof(JSString)) ? 1 : -1]; | |
8047 | typedef int js_static_assert45[(__builtin_offsetof (JSString, inlineStorage) + sizeof(jschar) * (JSShortString::MAX_SHORT_STRING_LENGTH + 1) == sizeof(JSShortString)) ? 1 : -1] | |
8048 | ; | |
8049 | } | |
8050 | }; | |
8051 | namespace js { | |
8052 | class StringBuffer; | |
8053 | class StringSegmentRange; | |
8054 | class MutatingRopeSegmentRange; | |
8055 | class RopeBuilder; | |
8056 | } | |
8057 | extern const jschar * | |
8058 | js_GetStringChars(JSContext *cx, JSString *str); | |
8059 | extern const jschar * | |
8060 | js_UndependString(JSContext *cx, JSString *str); | |
8061 | extern JSBool | |
8062 | js_MakeStringImmutable(JSContext *cx, JSString *str); | |
8063 | extern JSString * | |
8064 | js_toLowerCase(JSContext *cx, JSString *str); | |
8065 | extern JSString * | |
8066 | js_toUpperCase(JSContext *cx, JSString *str); | |
8067 | struct JSSubString { | |
8068 | size_t length; | |
8069 | const jschar *chars; | |
8070 | }; | |
8071 | extern jschar js_empty_ucstr[]; | |
8072 | extern JSSubString js_EmptySubString; | |
8073 | extern const uint8 js_X[]; | |
8074 | extern const uint8 js_Y[]; | |
8075 | extern const uint32 js_A[]; | |
8076 | typedef enum JSCharType { | |
8077 | JSCT_UNASSIGNED = 0, | |
8078 | JSCT_UPPERCASE_LETTER = 1, | |
8079 | JSCT_LOWERCASE_LETTER = 2, | |
8080 | JSCT_TITLECASE_LETTER = 3, | |
8081 | JSCT_MODIFIER_LETTER = 4, | |
8082 | JSCT_OTHER_LETTER = 5, | |
8083 | JSCT_NON_SPACING_MARK = 6, | |
8084 | JSCT_ENCLOSING_MARK = 7, | |
8085 | JSCT_COMBINING_SPACING_MARK = 8, | |
8086 | JSCT_DECIMAL_DIGIT_NUMBER = 9, | |
8087 | JSCT_LETTER_NUMBER = 10, | |
8088 | JSCT_OTHER_NUMBER = 11, | |
8089 | JSCT_SPACE_SEPARATOR = 12, | |
8090 | JSCT_LINE_SEPARATOR = 13, | |
8091 | JSCT_PARAGRAPH_SEPARATOR = 14, | |
8092 | JSCT_CONTROL = 15, | |
8093 | JSCT_FORMAT = 16, | |
8094 | JSCT_PRIVATE_USE = 18, | |
8095 | JSCT_SURROGATE = 19, | |
8096 | JSCT_DASH_PUNCTUATION = 20, | |
8097 | JSCT_START_PUNCTUATION = 21, | |
8098 | JSCT_END_PUNCTUATION = 22, | |
8099 | JSCT_CONNECTOR_PUNCTUATION = 23, | |
8100 | JSCT_OTHER_PUNCTUATION = 24, | |
8101 | JSCT_MATH_SYMBOL = 25, | |
8102 | JSCT_CURRENCY_SYMBOL = 26, | |
8103 | JSCT_MODIFIER_SYMBOL = 27, | |
8104 | JSCT_OTHER_SYMBOL = 28 | |
8105 | } JSCharType; | |
8106 | extern const bool js_alnum[]; | |
8107 | const jschar BYTE_ORDER_MARK = 0xFEFF; | |
8108 | const jschar NO_BREAK_SPACE = 0x00A0; | |
8109 | static inline | |
8110 | bool | |
8111 | JS_ISSPACE(jschar c) | |
8112 | { | |
8113 | unsigned w = c; | |
8114 | if (w < 256) | |
8115 | return (w <= ' ' && (w == ' ' || (9 <= w && w <= 0xD))) || w == NO_BREAK_SPACE; | |
8116 | return w == BYTE_ORDER_MARK || ((js_A[js_Y[(js_X[(uint16)(w)>>6]<<6)|((w)&0x3F)]]) & 0x00070000) == 0x00040000; | |
8117 | } | |
8118 | extern js::Class js_StringClass; | |
8119 | inline | |
8120 | bool | |
8121 | JSObject::isString() const | |
8122 | { | |
8123 | return getClass() == &js_StringClass; | |
8124 | } | |
8125 | extern JSObject * | |
8126 | js_InitStringClass(JSContext *cx, JSObject *obj); | |
8127 | extern const char js_escape_str[]; | |
8128 | extern const char js_unescape_str[]; | |
8129 | extern const char js_uneval_str[]; | |
8130 | extern const char js_decodeURI_str[]; | |
8131 | extern const char js_encodeURI_str[]; | |
8132 | extern const char js_decodeURIComponent_str[]; | |
8133 | extern const char js_encodeURIComponent_str[]; | |
8134 | extern JSFlatString * | |
8135 | js_NewString(JSContext *cx, jschar *chars, size_t length); | |
8136 | extern JSLinearString * | |
8137 | js_NewDependentString(JSContext *cx, JSString *base, size_t start, | |
8138 | size_t length); | |
8139 | extern JSFlatString * | |
8140 | js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n); | |
8141 | extern JSFlatString * | |
8142 | js_NewStringCopyN(JSContext *cx, const char *s, size_t n); | |
8143 | extern JSFlatString * | |
8144 | js_NewStringCopyZ(JSContext *cx, const jschar *s); | |
8145 | extern JSFlatString * | |
8146 | js_NewStringCopyZ(JSContext *cx, const char *s); | |
8147 | extern const char * | |
8148 | js_ValueToPrintable(JSContext *cx, const js::Value &, | |
8149 | JSAutoByteString *bytes, bool asSource = false); | |
8150 | extern JSString * | |
8151 | js_ValueToString(JSContext *cx, const js::Value &v); | |
8152 | namespace js { | |
8153 | static __attribute__((always_inline)) inline JSString * | |
8154 | ValueToString_TestForStringInline(JSContext *cx, const Value &v) | |
8155 | { | |
8156 | if (v.isString()) | |
8157 | return v.toString(); | |
8158 | return js_ValueToString(cx, v); | |
8159 | } | |
8160 | extern | |
8161 | bool | |
8162 | ValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb); | |
8163 | } | |
8164 | extern __attribute__((visibility ("default"))) JSString * | |
8165 | js_ValueToSource(JSContext *cx, const js::Value &v); | |
8166 | inline uint32 | |
8167 | js_HashString(JSLinearString *str) | |
8168 | { | |
8169 | const jschar *s = str->chars(); | |
8170 | size_t n = str->length(); | |
8171 | uint32 h; | |
8172 | for (h = 0; n; s++, n--) | |
8173 | h = (((h) << (4)) | ((h) >> (32 - (4)))) ^ *s; | |
8174 | return h; | |
8175 | } | |
8176 | namespace js { | |
8177 | extern | |
8178 | bool | |
8179 | EqualStrings(JSContext *cx, JSString *str1, JSString *str2, JSBool *result); | |
8180 | extern | |
8181 | bool | |
8182 | EqualStrings(JSLinearString *str1, JSLinearString *str2); | |
8183 | extern | |
8184 | bool | |
8185 | CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result); | |
8186 | extern | |
8187 | bool | |
8188 | StringEqualsAscii(JSLinearString *str, const char *asciiBytes); | |
8189 | } | |
8190 | static const jsuint sBMHCharSetSize = 256; | |
8191 | static const jsuint sBMHPatLenMax = 255; | |
8192 | static const jsint sBMHBadPattern = -2; | |
8193 | extern jsint | |
8194 | js_BoyerMooreHorspool(const jschar *text, jsuint textlen, | |
8195 | const jschar *pat, jsuint patlen); | |
8196 | extern size_t | |
8197 | js_strlen(const jschar *s); | |
8198 | extern jschar * | |
8199 | js_strchr(const jschar *s, jschar c); | |
8200 | extern jschar * | |
8201 | js_strchr_limit(const jschar *s, jschar c, const jschar *limit); | |
8202 | inline void | |
8203 | js_short_strncpy(jschar *dest, const jschar *src, size_t num) | |
8204 | { | |
8205 | ((void) 0); | |
8206 | for (size_t i = 0; i < num; i++) | |
8207 | dest[i] = src[i]; | |
8208 | } | |
8209 | static inline const jschar * | |
8210 | js_SkipWhiteSpace(const jschar *s, const jschar *end) | |
8211 | { | |
8212 | ((void) 0); | |
8213 | while (s != end && JS_ISSPACE(*s)) | |
8214 | s++; | |
8215 | return s; | |
8216 | } | |
8217 | extern jschar * | |
8218 | js_InflateString(JSContext *cx, const char *bytes, size_t *length); | |
8219 | extern char * | |
8220 | js_DeflateString(JSContext *cx, const jschar *chars, size_t length); | |
8221 | extern JSBool | |
8222 | js_InflateStringToBuffer(JSContext *cx, const char *bytes, size_t length, | |
8223 | jschar *chars, size_t *charsLength); | |
8224 | extern JSBool | |
8225 | js_InflateUTF8StringToBuffer(JSContext *cx, const char *bytes, size_t length, | |
8226 | jschar *chars, size_t *charsLength); | |
8227 | extern size_t | |
8228 | js_GetDeflatedStringLength(JSContext *cx, const jschar *chars, | |
8229 | size_t charsLength); | |
8230 | extern size_t | |
8231 | js_GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars, | |
8232 | size_t charsLength); | |
8233 | extern JSBool | |
8234 | js_DeflateStringToBuffer(JSContext *cx, const jschar *chars, | |
8235 | size_t charsLength, char *bytes, size_t *length); | |
8236 | extern JSBool | |
8237 | js_DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars, | |
8238 | size_t charsLength, char *bytes, size_t *length); | |
8239 | extern JSBool | |
8240 | js_str_escape(JSContext *cx, uintN argc, js::Value *argv, js::Value *rval); | |
8241 | namespace js { | |
8242 | extern JSBool | |
8243 | str_replace(JSContext *cx, uintN argc, js::Value *vp); | |
8244 | } | |
8245 | extern JSBool | |
8246 | js_str_toString(JSContext *cx, uintN argc, js::Value *vp); | |
8247 | extern JSBool | |
8248 | js_str_charAt(JSContext *cx, uintN argc, js::Value *vp); | |
8249 | extern JSBool | |
8250 | js_str_charCodeAt(JSContext *cx, uintN argc, js::Value *vp); | |
8251 | extern int | |
8252 | js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); | |
8253 | namespace js { | |
8254 | extern size_t | |
8255 | PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32 quote); | |
8256 | inline size_t | |
8257 | PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32 quote) | |
8258 | { | |
8259 | size_t n = PutEscapedStringImpl(buffer, size, __null, str, quote); | |
8260 | ((void) 0); | |
8261 | return n; | |
8262 | } | |
8263 | inline | |
8264 | bool | |
8265 | FileEscapedString(FILE *fp, JSLinearString *str, uint32 quote) | |
8266 | { | |
8267 | return PutEscapedStringImpl(__null, 0, fp, str, quote) != size_t(-1); | |
8268 | } | |
8269 | } | |
8270 | extern JSBool | |
8271 | js_String(JSContext *cx, uintN argc, js::Value *vp); | |
8272 | static __attribute__((always_inline)) inline jsid | |
8273 | JSID_FROM_BITS(size_t bits) | |
8274 | { | |
8275 | jsid id; | |
8276 | (id) = bits; | |
8277 | return id; | |
8278 | } | |
8279 | static __attribute__((always_inline)) inline jsid | |
8280 | ATOM_TO_JSID(JSAtom *atom) | |
8281 | { | |
8282 | ((void) 0); | |
8283 | return JSID_FROM_BITS((size_t)atom); | |
8284 | } | |
8285 | static __attribute__((always_inline)) inline JSBool | |
8286 | JSID_IS_ATOM(jsid id) | |
8287 | { | |
8288 | return JSID_IS_STRING(id); | |
8289 | } | |
8290 | static __attribute__((always_inline)) inline JSBool | |
8291 | JSID_IS_ATOM(jsid id, JSAtom *atom) | |
8292 | { | |
8293 | return (id) == (ATOM_TO_JSID(atom)); | |
8294 | } | |
8295 | static __attribute__((always_inline)) inline JSAtom * | |
8296 | JSID_TO_ATOM(jsid id) | |
8297 | { | |
8298 | return (JSAtom *)JSID_TO_STRING(id); | |
8299 | } | |
8300 | namespace js { | |
8301 | static __attribute__((always_inline)) inline Value | |
8302 | IdToValue(jsid id) | |
8303 | { | |
8304 | if (JSID_IS_STRING(id)) | |
8305 | return StringValue(JSID_TO_STRING(id)); | |
8306 | if ((__builtin_expect((JSID_IS_INT(id)), 1))) | |
8307 | return Int32Value(JSID_TO_INT(id)); | |
8308 | if ((__builtin_expect((JSID_IS_OBJECT(id)), 1))) | |
8309 | return ObjectValue(*JSID_TO_OBJECT(id)); | |
8310 | ((void) 0); | |
8311 | return UndefinedValue(); | |
8312 | } | |
8313 | static __attribute__((always_inline)) inline jsval | |
8314 | IdToJsval(jsid id) | |
8315 | { | |
8316 | return Jsvalify(IdToValue(id)); | |
8317 | } | |
8318 | } | |
8319 | extern const char * | |
8320 | js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes); | |
8321 | struct JSAtomListElement { | |
8322 | JSHashEntry entry; | |
8323 | }; | |
8324 | struct JSAtomSet { | |
8325 | JSHashEntry *list; | |
8326 | JSHashTable *table; | |
8327 | jsuint count; | |
8328 | }; | |
8329 | struct JSAtomList : public JSAtomSet | |
8330 | { | |
8331 | JSAtomList() { | |
8332 | list = __null; table = __null; count = 0; | |
8333 | } | |
8334 | JSAtomList(const JSAtomSet& as) { | |
8335 | list = as.list; table = as.table; count = as.count; | |
8336 | } | |
8337 | void clear() { ((void) 0); list = __null; table = __null; count = 0; } | |
8338 | JSAtomListElement *lookup(JSAtom *atom) { | |
8339 | JSHashEntry **hep; | |
8340 | return rawLookup(atom, hep); | |
8341 | } | |
8342 | JSAtomListElement *rawLookup(JSAtom *atom, JSHashEntry **&hep); | |
8343 | enum AddHow { UNIQUE, SHADOW, HOIST }; | |
8344 | JSAtomListElement *add(js::Parser *parser, JSAtom *atom, AddHow how = UNIQUE); | |
8345 | void remove(js::Parser *parser, JSAtom *atom) { | |
8346 | JSHashEntry **hep; | |
8347 | JSAtomListElement *ale = rawLookup(atom, hep); | |
8348 | if (ale) | |
8349 | rawRemove(parser, ale, hep); | |
8350 | } | |
8351 | void rawRemove(js::Parser *parser, JSAtomListElement *ale, JSHashEntry **hep); | |
8352 | }; | |
8353 | struct JSAutoAtomList: public JSAtomList | |
8354 | { | |
8355 | JSAutoAtomList(js::Parser *p): parser(p) {} | |
8356 | ~JSAutoAtomList(); | |
8357 | private: | |
8358 | js::Parser *parser; | |
8359 | }; | |
8360 | class JSAtomListIterator { | |
8361 | JSAtomList* list; | |
8362 | JSAtomListElement* next; | |
8363 | uint32 index; | |
8364 | public: | |
8365 | JSAtomListIterator(JSAtomList* al) : list(al) { reset(); } | |
8366 | void reset() { | |
8367 | next = (JSAtomListElement *) list->list; | |
8368 | index = 0; | |
8369 | } | |
8370 | JSAtomListElement* operator ()(); | |
8371 | }; | |
8372 | struct JSAtomMap { | |
8373 | JSAtom **vector; | |
8374 | jsatomid length; | |
8375 | }; | |
8376 | namespace js { | |
8377 | typedef int js_static_assert46[(((size_t)(0x1 | 0x2)) < JS_GCTHING_ALIGN) ? 1 : -1]; | |
8378 | typedef uintptr_t AtomEntryType; | |
8379 | static __attribute__((always_inline)) inline JSAtom * | |
8380 | AtomEntryToKey(AtomEntryType entry) | |
8381 | { | |
8382 | ((void) 0); | |
8383 | return (JSAtom *)(entry & ~((size_t)(0x1 | 0x2))); | |
8384 | } | |
8385 | struct AtomHasher | |
8386 | { | |
8387 | typedef JSLinearString *Lookup; | |
8388 | static HashNumber hash(JSLinearString *str) { | |
8389 | return js_HashString(str); | |
8390 | } | |
8391 | static bool match(AtomEntryType entry, JSLinearString *lookup) { | |
8392 | return entry ? EqualStrings(AtomEntryToKey(entry), lookup) : false; | |
8393 | } | |
8394 | }; | |
8395 | typedef HashSet<AtomEntryType, AtomHasher, SystemAllocPolicy> AtomSet; | |
8396 | } | |
8397 | struct JSAtomState | |
8398 | { | |
8399 | js::AtomSet atoms; | |
8400 | JSThinLock lock; | |
8401 | JSAtom *emptyAtom; | |
8402 | JSAtom *booleanAtoms[2]; | |
8403 | JSAtom *typeAtoms[JSTYPE_LIMIT]; | |
8404 | JSAtom *nullAtom; | |
8405 | JSAtom *classAtoms[JSProto_LIMIT]; | |
8406 | JSAtom *anonymousAtom; | |
8407 | JSAtom *applyAtom; | |
8408 | JSAtom *argumentsAtom; | |
8409 | JSAtom *arityAtom; | |
8410 | JSAtom *callAtom; | |
8411 | JSAtom *calleeAtom; | |
8412 | JSAtom *callerAtom; | |
8413 | JSAtom *classPrototypeAtom; | |
8414 | JSAtom *constructorAtom; | |
8415 | JSAtom *eachAtom; | |
8416 | JSAtom *evalAtom; | |
8417 | JSAtom *fileNameAtom; | |
8418 | JSAtom *getAtom; | |
8419 | JSAtom *globalAtom; | |
8420 | JSAtom *ignoreCaseAtom; | |
8421 | JSAtom *indexAtom; | |
8422 | JSAtom *inputAtom; | |
8423 | JSAtom *toISOStringAtom; | |
8424 | JSAtom *iteratorAtom; | |
8425 | JSAtom *joinAtom; | |
8426 | JSAtom *lastIndexAtom; | |
8427 | JSAtom *lengthAtom; | |
8428 | JSAtom *lineNumberAtom; | |
8429 | JSAtom *messageAtom; | |
8430 | JSAtom *multilineAtom; | |
8431 | JSAtom *nameAtom; | |
8432 | JSAtom *nextAtom; | |
8433 | JSAtom *noSuchMethodAtom; | |
8434 | JSAtom *objectNullAtom; | |
8435 | JSAtom *objectUndefinedAtom; | |
8436 | JSAtom *protoAtom; | |
8437 | JSAtom *setAtom; | |
8438 | JSAtom *sourceAtom; | |
8439 | JSAtom *stackAtom; | |
8440 | JSAtom *stickyAtom; | |
8441 | JSAtom *toGMTStringAtom; | |
8442 | JSAtom *toLocaleStringAtom; | |
8443 | JSAtom *toSourceAtom; | |
8444 | JSAtom *toStringAtom; | |
8445 | JSAtom *toUTCStringAtom; | |
8446 | JSAtom *valueOfAtom; | |
8447 | JSAtom *toJSONAtom; | |
8448 | JSAtom *void0Atom; | |
8449 | JSAtom *enumerableAtom; | |
8450 | JSAtom *configurableAtom; | |
8451 | JSAtom *writableAtom; | |
8452 | JSAtom *valueAtom; | |
8453 | JSAtom *testAtom; | |
8454 | JSAtom *useStrictAtom; | |
8455 | JSAtom *locAtom; | |
8456 | JSAtom *lineAtom; | |
8457 | JSAtom *InfinityAtom; | |
8458 | JSAtom *NaNAtom; | |
8459 | JSAtom *builderAtom; | |
8460 | JSAtom *etagoAtom; | |
8461 | JSAtom *namespaceAtom; | |
8462 | JSAtom *ptagcAtom; | |
8463 | JSAtom *qualifierAtom; | |
8464 | JSAtom *spaceAtom; | |
8465 | JSAtom *stagoAtom; | |
8466 | JSAtom *starAtom; | |
8467 | JSAtom *starQualifierAtom; | |
8468 | JSAtom *tagcAtom; | |
8469 | JSAtom *xmlAtom; | |
8470 | JSAtom *functionNamespaceURIAtom; | |
8471 | JSAtom *ProxyAtom; | |
8472 | JSAtom *getOwnPropertyDescriptorAtom; | |
8473 | JSAtom *getPropertyDescriptorAtom; | |
8474 | JSAtom *definePropertyAtom; | |
8475 | JSAtom *deleteAtom; | |
8476 | JSAtom *getOwnPropertyNamesAtom; | |
8477 | JSAtom *enumerateAtom; | |
8478 | JSAtom *fixAtom; | |
8479 | JSAtom *hasAtom; | |
8480 | JSAtom *hasOwnAtom; | |
8481 | JSAtom *keysAtom; | |
8482 | JSAtom *iterateAtom; | |
8483 | struct { | |
8484 | JSAtom *XMLListAtom; | |
8485 | JSAtom *decodeURIAtom; | |
8486 | JSAtom *decodeURIComponentAtom; | |
8487 | JSAtom *defineGetterAtom; | |
8488 | JSAtom *defineSetterAtom; | |
8489 | JSAtom *encodeURIAtom; | |
8490 | JSAtom *encodeURIComponentAtom; | |
8491 | JSAtom *escapeAtom; | |
8492 | JSAtom *hasOwnPropertyAtom; | |
8493 | JSAtom *isFiniteAtom; | |
8494 | JSAtom *isNaNAtom; | |
8495 | JSAtom *isPrototypeOfAtom; | |
8496 | JSAtom *isXMLNameAtom; | |
8497 | JSAtom *lookupGetterAtom; | |
8498 | JSAtom *lookupSetterAtom; | |
8499 | JSAtom *parseFloatAtom; | |
8500 | JSAtom *parseIntAtom; | |
8501 | JSAtom *propertyIsEnumerableAtom; | |
8502 | JSAtom *unescapeAtom; | |
8503 | JSAtom *unevalAtom; | |
8504 | JSAtom *unwatchAtom; | |
8505 | JSAtom *watchAtom; | |
8506 | } lazy; | |
8507 | }; | |
8508 | extern const char *const js_common_atom_names[]; | |
8509 | extern const size_t js_common_atom_count; | |
8510 | extern const char js_Null_str[]; | |
8511 | extern const char js_Object_str[]; | |
8512 | extern const char js_Function_str[]; | |
8513 | extern const char js_Array_str[]; | |
8514 | extern const char js_Boolean_str[]; | |
8515 | extern const char js_JSON_str[]; | |
8516 | extern const char js_Date_str[]; | |
8517 | extern const char js_Math_str[]; | |
8518 | extern const char js_Number_str[]; | |
8519 | extern const char js_String_str[]; | |
8520 | extern const char js_RegExp_str[]; | |
8521 | extern const char js_XML_str[]; | |
8522 | extern const char js_Namespace_str[]; | |
8523 | extern const char js_QName_str[]; | |
8524 | extern const char js_Reflect_str[]; | |
8525 | extern const char js_ASTNode_str[]; | |
8526 | extern const char js_Error_str[]; | |
8527 | extern const char js_InternalError_str[]; | |
8528 | extern const char js_EvalError_str[]; | |
8529 | extern const char js_RangeError_str[]; | |
8530 | extern const char js_ReferenceError_str[]; | |
8531 | extern const char js_SyntaxError_str[]; | |
8532 | extern const char js_TypeError_str[]; | |
8533 | extern const char js_URIError_str[]; | |
8534 | extern const char js_Generator_str[]; | |
8535 | extern const char js_Iterator_str[]; | |
8536 | extern const char js_StopIteration_str[]; | |
8537 | extern const char js_ArrayBuffer_str[]; | |
8538 | extern const char js_Int8Array_str[]; | |
8539 | extern const char js_Uint8Array_str[]; | |
8540 | extern const char js_Int16Array_str[]; | |
8541 | extern const char js_Uint16Array_str[]; | |
8542 | extern const char js_Int32Array_str[]; | |
8543 | extern const char js_Uint32Array_str[]; | |
8544 | extern const char js_Float32Array_str[]; | |
8545 | extern const char js_Float64Array_str[]; | |
8546 | extern const char js_Uint8ClampedArray_str[]; | |
8547 | extern const char js_Proxy_str[]; | |
8548 | extern const char js_AnyName_str[]; | |
8549 | extern const char js_anonymous_str[]; | |
8550 | extern const char js_apply_str[]; | |
8551 | extern const char js_arguments_str[]; | |
8552 | extern const char js_arity_str[]; | |
8553 | extern const char js_call_str[]; | |
8554 | extern const char js_callee_str[]; | |
8555 | extern const char js_caller_str[]; | |
8556 | extern const char js_class_prototype_str[]; | |
8557 | extern const char js_close_str[]; | |
8558 | extern const char js_constructor_str[]; | |
8559 | extern const char js_count_str[]; | |
8560 | extern const char js_etago_str[]; | |
8561 | extern const char js_each_str[]; | |
8562 | extern const char js_eval_str[]; | |
8563 | extern const char js_fileName_str[]; | |
8564 | extern const char js_get_str[]; | |
8565 | extern const char js_getter_str[]; | |
8566 | extern const char js_global_str[]; | |
8567 | extern const char js_ignoreCase_str[]; | |
8568 | extern const char js_index_str[]; | |
8569 | extern const char js_input_str[]; | |
8570 | extern const char js_iterator_str[]; | |
8571 | extern const char js_join_str[]; | |
8572 | extern const char js_lastIndex_str[]; | |
8573 | extern const char js_length_str[]; | |
8574 | extern const char js_lineNumber_str[]; | |
8575 | extern const char js_message_str[]; | |
8576 | extern const char js_multiline_str[]; | |
8577 | extern const char js_name_str[]; | |
8578 | extern const char js_namespace_str[]; | |
8579 | extern const char js_next_str[]; | |
8580 | extern const char js_noSuchMethod_str[]; | |
8581 | extern const char js_object_str[]; | |
8582 | extern const char js_proto_str[]; | |
8583 | extern const char js_ptagc_str[]; | |
8584 | extern const char js_qualifier_str[]; | |
8585 | extern const char js_send_str[]; | |
8586 | extern const char js_setter_str[]; | |
8587 | extern const char js_set_str[]; | |
8588 | extern const char js_source_str[]; | |
8589 | extern const char js_space_str[]; | |
8590 | extern const char js_stack_str[]; | |
8591 | extern const char js_sticky_str[]; | |
8592 | extern const char js_stago_str[]; | |
8593 | extern const char js_star_str[]; | |
8594 | extern const char js_starQualifier_str[]; | |
8595 | extern const char js_tagc_str[]; | |
8596 | extern const char js_toGMTString_str[]; | |
8597 | extern const char js_toLocaleString_str[]; | |
8598 | extern const char js_toSource_str[]; | |
8599 | extern const char js_toString_str[]; | |
8600 | extern const char js_toUTCString_str[]; | |
8601 | extern const char js_undefined_str[]; | |
8602 | extern const char js_valueOf_str[]; | |
8603 | extern const char js_toJSON_str[]; | |
8604 | extern const char js_xml_str[]; | |
8605 | extern const char js_enumerable_str[]; | |
8606 | extern const char js_configurable_str[]; | |
8607 | extern const char js_writable_str[]; | |
8608 | extern const char js_value_str[]; | |
8609 | extern const char js_test_str[]; | |
8610 | extern JSBool | |
8611 | js_InitAtomState(JSRuntime *rt); | |
8612 | extern void | |
8613 | js_FinishAtomState(JSRuntime *rt); | |
8614 | extern void | |
8615 | js_TraceAtomState(JSTracer *trc); | |
8616 | extern void | |
8617 | js_SweepAtomState(JSContext *cx); | |
8618 | extern JSBool | |
8619 | js_InitCommonAtoms(JSContext *cx); | |
8620 | extern void | |
8621 | js_FinishCommonAtoms(JSContext *cx); | |
8622 | extern JSAtom * | |
8623 | js_AtomizeString(JSContext *cx, JSString *str, uintN flags); | |
8624 | extern JSAtom * | |
8625 | js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); | |
8626 | extern JSAtom * | |
8627 | js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags); | |
8628 | extern JSAtom * | |
8629 | js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length); | |
8630 | inline | |
8631 | bool | |
8632 | js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp); | |
8633 | inline | |
8634 | bool | |
8635 | js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp); | |
8636 | inline | |
8637 | bool | |
8638 | js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, | |
8639 | jsid *idp); | |
8640 | inline | |
8641 | bool | |
8642 | js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, | |
8643 | jsid *idp, js::Value *vp); | |
8644 | extern void | |
8645 | js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); | |
8646 | const uintN MIN_SPARSE_INDEX = 256; | |
8647 | inline JSObject::EnsureDenseResult | |
8648 | JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra) | |
8649 | { | |
8650 | ((void) 0); | |
8651 | uintN currentCapacity = numSlots(); | |
8652 | uintN requiredCapacity; | |
8653 | if (extra == 1) { | |
8654 | if (index < currentCapacity) | |
8655 | return ED_OK; | |
8656 | requiredCapacity = index + 1; | |
8657 | if (requiredCapacity == 0) { | |
8658 | return ED_SPARSE; | |
8659 | } | |
8660 | } else { | |
8661 | requiredCapacity = index + extra; | |
8662 | if (requiredCapacity < index) { | |
8663 | return ED_SPARSE; | |
8664 | } | |
8665 | if (requiredCapacity <= currentCapacity) | |
8666 | return ED_OK; | |
8667 | } | |
8668 | if (requiredCapacity > MIN_SPARSE_INDEX && | |
8669 | willBeSparseDenseArray(requiredCapacity, extra)) { | |
8670 | return ED_SPARSE; | |
8671 | } | |
8672 | return growSlots(cx, requiredCapacity) ? ED_OK : ED_FAILED; | |
8673 | } | |
8674 | extern | |
8675 | bool | |
8676 | js_StringIsIndex(JSLinearString *str, jsuint *indexp); | |
8677 | inline JSBool | |
8678 | js_IdIsIndex(jsid id, jsuint *indexp) | |
8679 | { | |
8680 | if (JSID_IS_INT(id)) { | |
8681 | jsint i; | |
8682 | i = JSID_TO_INT(id); | |
8683 | if (i < 0) | |
8684 | return (JSIntn)0; | |
8685 | *indexp = (jsuint)i; | |
8686 | return (JSIntn)1; | |
8687 | } | |
8688 | if ((__builtin_expect((!JSID_IS_STRING(id)), 0))) | |
8689 | return (JSIntn)0; | |
8690 | return js_StringIsIndex(JSID_TO_ATOM(id), indexp); | |
8691 | } | |
8692 | inline | |
8693 | bool | |
8694 | js_IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex) | |
8695 | { | |
8696 | if (JSVAL_IS_INT(id)) { | |
8697 | jsint i; | |
8698 | i = JSVAL_TO_INT(id); | |
8699 | if (i < 0) { | |
8700 | *isIndex = false; | |
8701 | return true; | |
8702 | } | |
8703 | *indexp = (jsuint)i; | |
8704 | *isIndex = true; | |
8705 | return true; | |
8706 | } | |
8707 | if (!JSVAL_IS_STRING(id)) { | |
8708 | *isIndex = false; | |
8709 | return true; | |
8710 | } | |
8711 | JSLinearString *str = JSVAL_TO_STRING(id)->ensureLinear(cx); | |
8712 | if (!str) | |
8713 | return false; | |
8714 | *isIndex = js_StringIsIndex(str, indexp); | |
8715 | return true; | |
8716 | } | |
8717 | extern js::Class js_ArrayClass, js_SlowArrayClass; | |
8718 | inline | |
8719 | bool | |
8720 | JSObject::isDenseArray() const | |
8721 | { | |
8722 | return getClass() == &js_ArrayClass; | |
8723 | } | |
8724 | inline | |
8725 | bool | |
8726 | JSObject::isSlowArray() const | |
8727 | { | |
8728 | return getClass() == &js_SlowArrayClass; | |
8729 | } | |
8730 | inline | |
8731 | bool | |
8732 | JSObject::isArray() const | |
8733 | { | |
8734 | return isDenseArray() || isSlowArray(); | |
8735 | } | |
8736 | static inline JSObject * | |
8737 | js_GetProtoIfDenseArray(JSObject *obj) | |
8738 | { | |
8739 | return obj->isDenseArray() ? obj->getProto() : obj; | |
8740 | } | |
8741 | extern JSObject * | |
8742 | js_InitArrayClass(JSContext *cx, JSObject *obj); | |
8743 | extern | |
8744 | bool | |
8745 | js_InitContextBusyArrayTable(JSContext *cx); | |
8746 | namespace js | |
8747 | { | |
8748 | extern JSObject * | |
8749 | NewDenseEmptyArray(JSContext *cx, JSObject *proto=__null); | |
8750 | extern JSObject * | |
8751 | NewDenseAllocatedArray(JSContext *cx, uint length, JSObject *proto=__null); | |
8752 | extern JSObject * | |
8753 | NewDenseUnallocatedArray(JSContext *cx, uint length, JSObject *proto=__null); | |
8754 | extern JSObject * | |
8755 | NewDenseCopiedArray(JSContext *cx, uint length, Value *vp, JSObject *proto=__null); | |
8756 | extern JSObject * | |
8757 | NewSlowEmptyArray(JSContext *cx); | |
8758 | } | |
8759 | extern JSBool | |
8760 | js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | |
8761 | extern JSBool | |
8762 | js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length); | |
8763 | extern JSBool | |
8764 | js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | |
8765 | extern JSBool | |
8766 | js_IndexToId(JSContext *cx, jsuint index, jsid *idp); | |
8767 | namespace js { | |
8768 | extern | |
8769 | bool | |
8770 | GetElements(JSContext *cx, JSObject *aobj, jsuint length, js::Value *vp); | |
8771 | } | |
8772 | typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b, | |
8773 | int *result); | |
8774 | enum JSMergeSortElemType { | |
8775 | JS_SORTING_VALUES, | |
8776 | JS_SORTING_GENERIC | |
8777 | }; | |
8778 | extern | |
8779 | bool | |
8780 | js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, | |
8781 | void *arg, void *tmp, JSMergeSortElemType elemType); | |
8782 | namespace js { | |
8783 | extern JSBool | |
8784 | array_sort(JSContext *cx, uintN argc, js::Value *vp); | |
8785 | } | |
8786 | extern JSBool | |
8787 | js_ArrayCompPush(JSContext *cx, JSObject *obj, const js::Value &vp); | |
8788 | __attribute__((visibility ("default"))) JSBool | |
8789 | js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count, | |
8790 | JSUint8 *dest); | |
8791 | JSBool | |
8792 | js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj); | |
8793 | JSBool | |
8794 | js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id, | |
8795 | js::Value *vp); | |
8796 | JSBool | |
8797 | js_Array(JSContext *cx, uintN argc, js::Value *vp); | |
8798 | __attribute__((visibility ("default"))) JSBool | |
8799 | js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone); | |
8800 | __attribute__((visibility ("default"))) JSBool | |
8801 | js_IsDensePrimitiveArray(JSObject *obj); | |
8802 | extern JSBool | |
8803 | js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i); | |
8804 | extern js::Class js_BooleanClass; | |
8805 | inline | |
8806 | bool | |
8807 | JSObject::isBoolean() const | |
8808 | { | |
8809 | return getClass() == &js_BooleanClass; | |
8810 | } | |
8811 | extern JSObject * | |
8812 | js_InitBooleanClass(JSContext *cx, JSObject *obj); | |
8813 | extern JSString * | |
8814 | js_BooleanToString(JSContext *cx, JSBool b); | |
8815 | namespace js { | |
8816 | extern | |
8817 | bool | |
8818 | BooleanToStringBuffer(JSContext *cx, JSBool b, StringBuffer &sb); | |
8819 | } | |
8820 | extern JSBool | |
8821 | js_ValueToBoolean(const js::Value &v); | |
8822 | extern "C" { | |
8823 | typedef struct JSArena JSArena; | |
8824 | typedef struct JSArenaPool JSArenaPool; | |
8825 | struct JSArena { | |
8826 | JSArena *next; | |
8827 | jsuword base; | |
8828 | jsuword limit; | |
8829 | jsuword avail; | |
8830 | }; | |
8831 | struct JSArenaPool { | |
8832 | JSArena first; | |
8833 | JSArena *current; | |
8834 | size_t arenasize; | |
8835 | jsuword mask; | |
8836 | size_t *quotap; | |
8837 | }; | |
8838 | extern __attribute__((visibility ("default"))) void | |
8839 | JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, | |
8840 | size_t align, size_t *quotap); | |
8841 | extern __attribute__((visibility ("default"))) void | |
8842 | JS_FreeArenaPool(JSArenaPool *pool); | |
8843 | extern __attribute__((visibility ("default"))) void | |
8844 | JS_FinishArenaPool(JSArenaPool *pool); | |
8845 | extern __attribute__((visibility ("default"))) void | |
8846 | JS_ArenaFinish(void); | |
8847 | extern __attribute__((visibility ("default"))) void | |
8848 | JS_ArenaShutDown(void); | |
8849 | extern __attribute__((visibility ("default"))) void * | |
8850 | JS_ArenaAllocate(JSArenaPool *pool, size_t nb); | |
8851 | extern __attribute__((visibility ("default"))) void * | |
8852 | JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); | |
8853 | extern __attribute__((visibility ("default"))) void * | |
8854 | JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); | |
8855 | extern __attribute__((visibility ("default"))) void | |
8856 | JS_ArenaRelease(JSArenaPool *pool, char *mark); | |
8857 | } | |
8858 | typedef struct JSCListStr { | |
8859 | struct JSCListStr *next; | |
8860 | struct JSCListStr *prev; | |
8861 | } JSCList; | |
8862 | extern "C" { | |
8863 | typedef uint32 JSDHashNumber; | |
8864 | typedef struct JSDHashEntryHdr JSDHashEntryHdr; | |
8865 | typedef struct JSDHashEntryStub JSDHashEntryStub; | |
8866 | typedef struct JSDHashTable JSDHashTable; | |
8867 | typedef struct JSDHashTableOps JSDHashTableOps; | |
8868 | struct JSDHashEntryHdr { | |
8869 | JSDHashNumber keyHash; | |
8870 | }; | |
8871 | struct JSDHashTable { | |
8872 | const JSDHashTableOps *ops; | |
8873 | void *data; | |
8874 | int16 hashShift; | |
8875 | uint8 maxAlphaFrac; | |
8876 | uint8 minAlphaFrac; | |
8877 | uint32 entrySize; | |
8878 | uint32 entryCount; | |
8879 | uint32 removedCount; | |
8880 | uint32 generation; | |
8881 | char *entryStore; | |
8882 | }; | |
8883 | typedef void * | |
8884 | (* JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes); | |
8885 | typedef void | |
8886 | (* JSDHashFreeTable) (JSDHashTable *table, void *ptr); | |
8887 | typedef JSDHashNumber | |
8888 | (* JSDHashHashKey) (JSDHashTable *table, const void *key); | |
8889 | typedef JSBool | |
8890 | (* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, | |
8891 | const void *key); | |
8892 | typedef void | |
8893 | (* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, | |
8894 | JSDHashEntryHdr *to); | |
8895 | typedef void | |
8896 | (* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); | |
8897 | typedef void | |
8898 | (* JSDHashFinalize) (JSDHashTable *table); | |
8899 | typedef JSBool | |
8900 | (* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, | |
8901 | const void *key); | |
8902 | struct JSDHashTableOps { | |
8903 | JSDHashAllocTable allocTable; | |
8904 | JSDHashFreeTable freeTable; | |
8905 | JSDHashHashKey hashKey; | |
8906 | JSDHashMatchEntry matchEntry; | |
8907 | JSDHashMoveEntry moveEntry; | |
8908 | JSDHashClearEntry clearEntry; | |
8909 | JSDHashFinalize finalize; | |
8910 | JSDHashInitEntry initEntry; | |
8911 | }; | |
8912 | extern __attribute__((visibility ("default"))) void * | |
8913 | JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes); | |
8914 | extern __attribute__((visibility ("default"))) void | |
8915 | JS_DHashFreeTable(JSDHashTable *table, void *ptr); | |
8916 | extern __attribute__((visibility ("default"))) JSDHashNumber | |
8917 | JS_DHashStringKey(JSDHashTable *table, const void *key); | |
8918 | struct JSDHashEntryStub { | |
8919 | JSDHashEntryHdr hdr; | |
8920 | const void *key; | |
8921 | }; | |
8922 | extern __attribute__((visibility ("default"))) JSDHashNumber | |
8923 | JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); | |
8924 | extern __attribute__((visibility ("default"))) JSBool | |
8925 | JS_DHashMatchEntryStub(JSDHashTable *table, | |
8926 | const JSDHashEntryHdr *entry, | |
8927 | const void *key); | |
8928 | extern __attribute__((visibility ("default"))) JSBool | |
8929 | JS_DHashMatchStringKey(JSDHashTable *table, | |
8930 | const JSDHashEntryHdr *entry, | |
8931 | const void *key); | |
8932 | extern __attribute__((visibility ("default"))) void | |
8933 | JS_DHashMoveEntryStub(JSDHashTable *table, | |
8934 | const JSDHashEntryHdr *from, | |
8935 | JSDHashEntryHdr *to); | |
8936 | extern __attribute__((visibility ("default"))) void | |
8937 | JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); | |
8938 | extern __attribute__((visibility ("default"))) void | |
8939 | JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); | |
8940 | extern __attribute__((visibility ("default"))) void | |
8941 | JS_DHashFinalizeStub(JSDHashTable *table); | |
8942 | extern __attribute__((visibility ("default"))) const JSDHashTableOps * | |
8943 | JS_DHashGetStubOps(void); | |
8944 | extern __attribute__((visibility ("default"))) JSDHashTable * | |
8945 | JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize, | |
8946 | uint32 capacity); | |
8947 | extern __attribute__((visibility ("default"))) void | |
8948 | JS_DHashTableDestroy(JSDHashTable *table); | |
8949 | extern __attribute__((visibility ("default"))) JSBool | |
8950 | JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, | |
8951 | uint32 entrySize, uint32 capacity); | |
8952 | extern __attribute__((visibility ("default"))) void | |
8953 | JS_DHashTableSetAlphaBounds(JSDHashTable *table, | |
8954 | float maxAlpha, | |
8955 | float minAlpha); | |
8956 | extern __attribute__((visibility ("default"))) void | |
8957 | JS_DHashTableFinish(JSDHashTable *table); | |
8958 | typedef enum JSDHashOperator { | |
8959 | JS_DHASH_LOOKUP = 0, | |
8960 | JS_DHASH_ADD = 1, | |
8961 | JS_DHASH_REMOVE = 2, | |
8962 | JS_DHASH_NEXT = 0, | |
8963 | JS_DHASH_STOP = 1 | |
8964 | } JSDHashOperator; | |
8965 | extern __attribute__((visibility ("default"))) JSDHashEntryHdr * | |
8966 | JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); | |
8967 | extern __attribute__((visibility ("default"))) void | |
8968 | JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); | |
8969 | typedef JSDHashOperator | |
8970 | (* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, | |
8971 | void *arg); | |
8972 | extern __attribute__((visibility ("default"))) uint32 | |
8973 | JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); | |
8974 | } | |
8975 | extern "C" { | |
8976 | struct DtoaState; | |
8977 | DtoaState * | |
8978 | js_NewDtoaState(); | |
8979 | void | |
8980 | js_DestroyDtoaState(DtoaState *state); | |
8981 | double | |
8982 | js_strtod_harder(DtoaState *state, const char *s00, char **se, int *err); | |
8983 | typedef enum JSDToStrMode { | |
8984 | DTOSTR_STANDARD, | |
8985 | DTOSTR_STANDARD_EXPONENTIAL, | |
8986 | DTOSTR_FIXED, | |
8987 | DTOSTR_EXPONENTIAL, | |
8988 | DTOSTR_PRECISION | |
8989 | } JSDToStrMode; | |
8990 | char * | |
8991 | js_dtostr(DtoaState *state, char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, | |
8992 | double dval); | |
8993 | char * | |
8994 | js_dtobasestr(DtoaState *state, int base, double d); | |
8995 | } | |
8996 | extern "C" { | |
8997 | typedef enum JSOp { | |
8998 | JSOP_NOP = 0, | |
8999 | JSOP_PUSH = 1, | |
9000 | JSOP_POPV = 2, | |
9001 | JSOP_ENTERWITH = 3, | |
9002 | JSOP_LEAVEWITH = 4, | |
9003 | JSOP_RETURN = 5, | |
9004 | JSOP_GOTO = 6, | |
9005 | JSOP_IFEQ = 7, | |
9006 | JSOP_IFNE = 8, | |
9007 | JSOP_ARGUMENTS = 9, | |
9008 | JSOP_FORARG = 10, | |
9009 | JSOP_FORLOCAL = 11, | |
9010 | JSOP_DUP = 12, | |
9011 | JSOP_DUP2 = 13, | |
9012 | JSOP_SETCONST = 14, | |
9013 | JSOP_BITOR = 15, | |
9014 | JSOP_BITXOR = 16, | |
9015 | JSOP_BITAND = 17, | |
9016 | JSOP_EQ = 18, | |
9017 | JSOP_NE = 19, | |
9018 | JSOP_LT = 20, | |
9019 | JSOP_LE = 21, | |
9020 | JSOP_GT = 22, | |
9021 | JSOP_GE = 23, | |
9022 | JSOP_LSH = 24, | |
9023 | JSOP_RSH = 25, | |
9024 | JSOP_URSH = 26, | |
9025 | JSOP_ADD = 27, | |
9026 | JSOP_SUB = 28, | |
9027 | JSOP_MUL = 29, | |
9028 | JSOP_DIV = 30, | |
9029 | JSOP_MOD = 31, | |
9030 | JSOP_NOT = 32, | |
9031 | JSOP_BITNOT = 33, | |
9032 | JSOP_NEG = 34, | |
9033 | JSOP_POS = 35, | |
9034 | JSOP_DELNAME = 36, | |
9035 | JSOP_DELPROP = 37, | |
9036 | JSOP_DELELEM = 38, | |
9037 | JSOP_TYPEOF = 39, | |
9038 | JSOP_VOID = 40, | |
9039 | JSOP_INCNAME = 41, | |
9040 | JSOP_INCPROP = 42, | |
9041 | JSOP_INCELEM = 43, | |
9042 | JSOP_DECNAME = 44, | |
9043 | JSOP_DECPROP = 45, | |
9044 | JSOP_DECELEM = 46, | |
9045 | JSOP_NAMEINC = 47, | |
9046 | JSOP_PROPINC = 48, | |
9047 | JSOP_ELEMINC = 49, | |
9048 | JSOP_NAMEDEC = 50, | |
9049 | JSOP_PROPDEC = 51, | |
9050 | JSOP_ELEMDEC = 52, | |
9051 | JSOP_GETPROP = 53, | |
9052 | JSOP_SETPROP = 54, | |
9053 | JSOP_GETELEM = 55, | |
9054 | JSOP_SETELEM = 56, | |
9055 | JSOP_CALLNAME = 57, | |
9056 | JSOP_CALL = 58, | |
9057 | JSOP_NAME = 59, | |
9058 | JSOP_DOUBLE = 60, | |
9059 | JSOP_STRING = 61, | |
9060 | JSOP_ZERO = 62, | |
9061 | JSOP_ONE = 63, | |
9062 | JSOP_NULL = 64, | |
9063 | JSOP_THIS = 65, | |
9064 | JSOP_FALSE = 66, | |
9065 | JSOP_TRUE = 67, | |
9066 | JSOP_OR = 68, | |
9067 | JSOP_AND = 69, | |
9068 | JSOP_TABLESWITCH = 70, | |
9069 | JSOP_LOOKUPSWITCH = 71, | |
9070 | JSOP_STRICTEQ = 72, | |
9071 | JSOP_STRICTNE = 73, | |
9072 | JSOP_SETCALL = 74, | |
9073 | JSOP_ITER = 75, | |
9074 | JSOP_MOREITER = 76, | |
9075 | JSOP_ENDITER = 77, | |
9076 | JSOP_FUNAPPLY = 78, | |
9077 | JSOP_SWAP = 79, | |
9078 | JSOP_OBJECT = 80, | |
9079 | JSOP_POP = 81, | |
9080 | JSOP_NEW = 82, | |
9081 | JSOP_TRAP = 83, | |
9082 | JSOP_GETARG = 84, | |
9083 | JSOP_SETARG = 85, | |
9084 | JSOP_GETLOCAL = 86, | |
9085 | JSOP_SETLOCAL = 87, | |
9086 | JSOP_UINT16 = 88, | |
9087 | JSOP_NEWINIT = 89, | |
9088 | JSOP_NEWARRAY = 90, | |
9089 | JSOP_NEWOBJECT = 91, | |
9090 | JSOP_ENDINIT = 92, | |
9091 | JSOP_INITPROP = 93, | |
9092 | JSOP_INITELEM = 94, | |
9093 | JSOP_DEFSHARP = 95, | |
9094 | JSOP_USESHARP = 96, | |
9095 | JSOP_INCARG = 97, | |
9096 | JSOP_DECARG = 98, | |
9097 | JSOP_ARGINC = 99, | |
9098 | JSOP_ARGDEC = 100, | |
9099 | JSOP_INCLOCAL = 101, | |
9100 | JSOP_DECLOCAL = 102, | |
9101 | JSOP_LOCALINC = 103, | |
9102 | JSOP_LOCALDEC = 104, | |
9103 | JSOP_IMACOP = 105, | |
9104 | JSOP_FORNAME = 106, | |
9105 | JSOP_FORPROP = 107, | |
9106 | JSOP_FORELEM = 108, | |
9107 | JSOP_POPN = 109, | |
9108 | JSOP_BINDNAME = 110, | |
9109 | JSOP_SETNAME = 111, | |
9110 | JSOP_THROW = 112, | |
9111 | JSOP_IN = 113, | |
9112 | JSOP_INSTANCEOF = 114, | |
9113 | JSOP_DEBUGGER = 115, | |
9114 | JSOP_GOSUB = 116, | |
9115 | JSOP_RETSUB = 117, | |
9116 | JSOP_EXCEPTION = 118, | |
9117 | JSOP_LINENO = 119, | |
9118 | JSOP_CONDSWITCH = 120, | |
9119 | JSOP_CASE = 121, | |
9120 | JSOP_DEFAULT = 122, | |
9121 | JSOP_EVAL = 123, | |
9122 | JSOP_ENUMELEM = 124, | |
9123 | JSOP_GETTER = 125, | |
9124 | JSOP_SETTER = 126, | |
9125 | JSOP_DEFFUN = 127, | |
9126 | JSOP_DEFCONST = 128, | |
9127 | JSOP_DEFVAR = 129, | |
9128 | JSOP_LAMBDA = 130, | |
9129 | JSOP_CALLEE = 131, | |
9130 | JSOP_SETLOCALPOP = 132, | |
9131 | JSOP_PICK = 133, | |
9132 | JSOP_TRY = 134, | |
9133 | JSOP_FINALLY = 135, | |
9134 | JSOP_GETFCSLOT = 136, | |
9135 | JSOP_CALLFCSLOT = 137, | |
9136 | JSOP_ARGSUB = 138, | |
9137 | JSOP_ARGCNT = 139, | |
9138 | JSOP_DEFLOCALFUN = 140, | |
9139 | JSOP_GOTOX = 141, | |
9140 | JSOP_IFEQX = 142, | |
9141 | JSOP_IFNEX = 143, | |
9142 | JSOP_ORX = 144, | |
9143 | JSOP_ANDX = 145, | |
9144 | JSOP_GOSUBX = 146, | |
9145 | JSOP_CASEX = 147, | |
9146 | JSOP_DEFAULTX = 148, | |
9147 | JSOP_TABLESWITCHX = 149, | |
9148 | JSOP_LOOKUPSWITCHX = 150, | |
9149 | JSOP_BACKPATCH = 151, | |
9150 | JSOP_BACKPATCH_POP = 152, | |
9151 | JSOP_THROWING = 153, | |
9152 | JSOP_SETRVAL = 154, | |
9153 | JSOP_RETRVAL = 155, | |
9154 | JSOP_GETGNAME = 156, | |
9155 | JSOP_SETGNAME = 157, | |
9156 | JSOP_INCGNAME = 158, | |
9157 | JSOP_DECGNAME = 159, | |
9158 | JSOP_GNAMEINC = 160, | |
9159 | JSOP_GNAMEDEC = 161, | |
9160 | JSOP_REGEXP = 162, | |
9161 | JSOP_DEFXMLNS = 163, | |
9162 | JSOP_ANYNAME = 164, | |
9163 | JSOP_QNAMEPART = 165, | |
9164 | JSOP_QNAMECONST = 166, | |
9165 | JSOP_QNAME = 167, | |
9166 | JSOP_TOATTRNAME = 168, | |
9167 | JSOP_TOATTRVAL = 169, | |
9168 | JSOP_ADDATTRNAME = 170, | |
9169 | JSOP_ADDATTRVAL = 171, | |
9170 | JSOP_BINDXMLNAME = 172, | |
9171 | JSOP_SETXMLNAME = 173, | |
9172 | JSOP_XMLNAME = 174, | |
9173 | JSOP_DESCENDANTS = 175, | |
9174 | JSOP_FILTER = 176, | |
9175 | JSOP_ENDFILTER = 177, | |
9176 | JSOP_TOXML = 178, | |
9177 | JSOP_TOXMLLIST = 179, | |
9178 | JSOP_XMLTAGEXPR = 180, | |
9179 | JSOP_XMLELTEXPR = 181, | |
9180 | JSOP_NOTRACE = 182, | |
9181 | JSOP_XMLCDATA = 183, | |
9182 | JSOP_XMLCOMMENT = 184, | |
9183 | JSOP_XMLPI = 185, | |
9184 | JSOP_DELDESC = 186, | |
9185 | JSOP_CALLPROP = 187, | |
9186 | JSOP_BLOCKCHAIN = 188, | |
9187 | JSOP_NULLBLOCKCHAIN = 189, | |
9188 | JSOP_UINT24 = 190, | |
9189 | JSOP_INDEXBASE = 191, | |
9190 | JSOP_RESETBASE = 192, | |
9191 | JSOP_RESETBASE0 = 193, | |
9192 | JSOP_STARTXML = 194, | |
9193 | JSOP_STARTXMLEXPR = 195, | |
9194 | JSOP_CALLELEM = 196, | |
9195 | JSOP_STOP = 197, | |
9196 | JSOP_GETXPROP = 198, | |
9197 | JSOP_CALLXMLNAME = 199, | |
9198 | JSOP_TYPEOFEXPR = 200, | |
9199 | JSOP_ENTERBLOCK = 201, | |
9200 | JSOP_LEAVEBLOCK = 202, | |
9201 | JSOP_IFPRIMTOP = 203, | |
9202 | JSOP_PRIMTOP = 204, | |
9203 | JSOP_GENERATOR = 205, | |
9204 | JSOP_YIELD = 206, | |
9205 | JSOP_ARRAYPUSH = 207, | |
9206 | JSOP_GETFUNNS = 208, | |
9207 | JSOP_ENUMCONSTELEM = 209, | |
9208 | JSOP_LEAVEBLOCKEXPR = 210, | |
9209 | JSOP_GETTHISPROP = 211, | |
9210 | JSOP_GETARGPROP = 212, | |
9211 | JSOP_GETLOCALPROP = 213, | |
9212 | JSOP_INDEXBASE1 = 214, | |
9213 | JSOP_INDEXBASE2 = 215, | |
9214 | JSOP_INDEXBASE3 = 216, | |
9215 | JSOP_CALLGNAME = 217, | |
9216 | JSOP_CALLLOCAL = 218, | |
9217 | JSOP_CALLARG = 219, | |
9218 | JSOP_BINDGNAME = 220, | |
9219 | JSOP_INT8 = 221, | |
9220 | JSOP_INT32 = 222, | |
9221 | JSOP_LENGTH = 223, | |
9222 | JSOP_HOLE = 224, | |
9223 | JSOP_DEFFUN_FC = 225, | |
9224 | JSOP_DEFLOCALFUN_FC = 226, | |
9225 | JSOP_LAMBDA_FC = 227, | |
9226 | JSOP_OBJTOP = 228, | |
9227 | JSOP_TRACE = 229, | |
9228 | JSOP_GETUPVAR_DBG = 230, | |
9229 | JSOP_CALLUPVAR_DBG = 231, | |
9230 | JSOP_DEFFUN_DBGFC = 232, | |
9231 | JSOP_DEFLOCALFUN_DBGFC = 233, | |
9232 | JSOP_LAMBDA_DBGFC = 234, | |
9233 | JSOP_SETMETHOD = 235, | |
9234 | JSOP_INITMETHOD = 236, | |
9235 | JSOP_UNBRAND = 237, | |
9236 | JSOP_UNBRANDTHIS = 238, | |
9237 | JSOP_SHARPINIT = 239, | |
9238 | JSOP_GETGLOBAL = 240, | |
9239 | JSOP_CALLGLOBAL = 241, | |
9240 | JSOP_FUNCALL = 242, | |
9241 | JSOP_FORGNAME = 243, | |
9242 | JSOP_LIMIT, | |
9243 | JSOP_GETPROP2 = JSOP_LIMIT, | |
9244 | JSOP_GETELEM2 = JSOP_LIMIT + 1, | |
9245 | JSOP_FAKE_LIMIT = JSOP_GETELEM2 | |
9246 | } JSOp; | |
9247 | struct JSCodeSpec { | |
9248 | int8 length; | |
9249 | int8 nuses; | |
9250 | int8 ndefs; | |
9251 | uint8 prec; | |
9252 | uint32 format; | |
9253 | uint32 type() const { return ((format) & 0x001f); } | |
9254 | }; | |
9255 | extern const JSCodeSpec js_CodeSpec[]; | |
9256 | extern uintN js_NumCodeSpecs; | |
9257 | extern const char *js_CodeName[]; | |
9258 | extern const char js_EscapeMap[]; | |
9259 | extern JSString * | |
9260 | js_QuoteString(JSContext *cx, JSString *str, jschar quote); | |
9261 | extern JSPrinter * | |
9262 | js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun, | |
9263 | uintN indent, JSBool pretty, JSBool grouped, JSBool strict); | |
9264 | extern void | |
9265 | js_DestroyPrinter(JSPrinter *jp); | |
9266 | extern JSString * | |
9267 | js_GetPrinterOutput(JSPrinter *jp); | |
9268 | extern int | |
9269 | js_printf(JSPrinter *jp, const char *format, ...); | |
9270 | extern JSBool | |
9271 | js_puts(JSPrinter *jp, const char *s); | |
9272 | uintN | |
9273 | js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, | |
9274 | ptrdiff_t pcoff); | |
9275 | extern uintN | |
9276 | js_GetVariableBytecodeLength(jsbytecode *pc); | |
9277 | extern uintN | |
9278 | js_GetVariableStackUses(JSOp op, jsbytecode *pc); | |
9279 | extern uintN | |
9280 | js_GetEnterBlockStackDefs(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9281 | static inline uintN | |
9282 | js_GetStackUses(const JSCodeSpec *cs, JSOp op, jsbytecode *pc) | |
9283 | { | |
9284 | ((void) 0); | |
9285 | if (cs->nuses >= 0) | |
9286 | return cs->nuses; | |
9287 | return js_GetVariableStackUses(op, pc); | |
9288 | } | |
9289 | static inline uintN | |
9290 | js_GetStackDefs(JSContext *cx, const JSCodeSpec *cs, JSOp op, JSScript *script, | |
9291 | jsbytecode *pc) | |
9292 | { | |
9293 | ((void) 0); | |
9294 | if (cs->ndefs >= 0) | |
9295 | return cs->ndefs; | |
9296 | ((void) 0); | |
9297 | return js_GetEnterBlockStackDefs(cx, script, pc); | |
9298 | } | |
9299 | extern JSBool | |
9300 | js_DecompileScript(JSPrinter *jp, JSScript *script); | |
9301 | extern JSBool | |
9302 | js_DecompileFunctionBody(JSPrinter *jp); | |
9303 | extern JSBool | |
9304 | js_DecompileFunction(JSPrinter *jp); | |
9305 | typedef JSBool (* JSDecompilerPtr)(JSPrinter *); | |
9306 | extern JSString * | |
9307 | js_DecompileToString(JSContext *cx, const char *name, JSFunction *fun, | |
9308 | uintN indent, JSBool pretty, JSBool grouped, JSBool strict, | |
9309 | JSDecompilerPtr decompiler); | |
9310 | extern char * | |
9311 | js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, | |
9312 | JSString *fallback); | |
9313 | namespace js { | |
9314 | static inline char * | |
9315 | DecompileValueGenerator(JSContext *cx, intN spindex, const Value &v, | |
9316 | JSString *fallback) | |
9317 | { | |
9318 | return js_DecompileValueGenerator(cx, spindex, Jsvalify(v), fallback); | |
9319 | } | |
9320 | } | |
9321 | extern uintN | |
9322 | js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9323 | } | |
9324 | extern "C" { | |
9325 | extern __attribute__((visibility ("default"))) JSCrossCompartmentCall * | |
9326 | JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target); | |
9327 | } | |
9328 | namespace JS { | |
9329 | class __attribute__((visibility ("default"))) AutoEnterScriptCompartment | |
9330 | { | |
9331 | JSCrossCompartmentCall *call; | |
9332 | public: | |
9333 | AutoEnterScriptCompartment() : call(__null) {} | |
9334 | bool enter(JSContext *cx, JSScript *target); | |
9335 | bool entered() const { return call != __null; } | |
9336 | ~AutoEnterScriptCompartment() { | |
9337 | if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1)) | |
9338 | JS_LeaveCrossCompartmentCall(call); | |
9339 | } | |
9340 | }; | |
9341 | } | |
9342 | extern "C" { | |
9343 | extern __attribute__((visibility ("default"))) JSScript * | |
9344 | JS_GetScriptFromObject(JSObject *scriptObject); | |
9345 | extern __attribute__((visibility ("default"))) JSString * | |
9346 | JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, uintN indent); | |
9347 | extern __attribute__((visibility ("default"))) void | |
9348 | JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug); | |
9349 | extern __attribute__((visibility ("default"))) JSBool | |
9350 | JS_GetDebugMode(JSContext *cx); | |
9351 | __attribute__((visibility ("default"))) JSBool | |
9352 | JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug); | |
9353 | __attribute__((visibility ("default"))) JSBool | |
9354 | JS_SetDebugMode(JSContext *cx, JSBool debug); | |
9355 | extern __attribute__((visibility ("default"))) JSBool | |
9356 | js_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep); | |
9357 | extern __attribute__((visibility ("default"))) JSBool | |
9358 | JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep); | |
9359 | extern jsbytecode * | |
9360 | js_UntrapScriptCode(JSContext *cx, JSScript *script); | |
9361 | extern __attribute__((visibility ("default"))) JSBool | |
9362 | JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | |
9363 | JSTrapHandler handler, jsval closure); | |
9364 | extern __attribute__((visibility ("default"))) JSOp | |
9365 | JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9366 | extern __attribute__((visibility ("default"))) void | |
9367 | JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | |
9368 | JSTrapHandler *handlerp, jsval *closurep); | |
9369 | extern __attribute__((visibility ("default"))) void | |
9370 | JS_ClearScriptTraps(JSContext *cx, JSScript *script); | |
9371 | extern __attribute__((visibility ("default"))) void | |
9372 | JS_ClearAllTraps(JSContext *cx); | |
9373 | extern __attribute__((visibility ("default"))) JSTrapStatus | |
9374 | JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval); | |
9375 | extern __attribute__((visibility ("default"))) JSBool | |
9376 | JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure); | |
9377 | extern __attribute__((visibility ("default"))) JSBool | |
9378 | JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep); | |
9379 | extern __attribute__((visibility ("default"))) JSBool | |
9380 | JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id, | |
9381 | JSWatchPointHandler handler, JSObject *closure); | |
9382 | extern __attribute__((visibility ("default"))) JSBool | |
9383 | JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id, | |
9384 | JSWatchPointHandler *handlerp, JSObject **closurep); | |
9385 | extern __attribute__((visibility ("default"))) JSBool | |
9386 | JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj); | |
9387 | extern __attribute__((visibility ("default"))) JSBool | |
9388 | JS_ClearAllWatchPoints(JSContext *cx); | |
9389 | extern void | |
9390 | js_TraceWatchPoints(JSTracer *trc, JSObject *obj); | |
9391 | extern void | |
9392 | js_SweepWatchPoints(JSContext *cx); | |
9393 | extern JSBool | |
9394 | js_watch_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); | |
9395 | namespace js { | |
9396 | bool | |
9397 | IsWatchedProperty(JSContext *cx, const Shape *shape); | |
9398 | } | |
9399 | extern __attribute__((visibility ("default"))) uintN | |
9400 | JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9401 | extern __attribute__((visibility ("default"))) jsbytecode * | |
9402 | JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); | |
9403 | extern __attribute__((visibility ("default"))) jsbytecode * | |
9404 | JS_EndPC(JSContext *cx, JSScript *script); | |
9405 | extern __attribute__((visibility ("default"))) uintN | |
9406 | JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun); | |
9407 | extern __attribute__((visibility ("default"))) JSBool | |
9408 | JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun); | |
9409 | extern __attribute__((visibility ("default"))) jsuword * | |
9410 | JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp); | |
9411 | extern __attribute__((visibility ("default"))) JSAtom * | |
9412 | JS_LocalNameToAtom(jsuword w); | |
9413 | extern __attribute__((visibility ("default"))) JSString * | |
9414 | JS_AtomKey(JSAtom *atom); | |
9415 | extern __attribute__((visibility ("default"))) void | |
9416 | JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark); | |
9417 | extern __attribute__((visibility ("default"))) JSScript * | |
9418 | JS_GetFunctionScript(JSContext *cx, JSFunction *fun); | |
9419 | extern __attribute__((visibility ("default"))) JSNative | |
9420 | JS_GetFunctionNative(JSContext *cx, JSFunction *fun); | |
9421 | extern __attribute__((visibility ("default"))) JSPrincipals * | |
9422 | JS_GetScriptPrincipals(JSContext *cx, JSScript *script); | |
9423 | extern __attribute__((visibility ("default"))) JSStackFrame * | |
9424 | JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp); | |
9425 | extern __attribute__((visibility ("default"))) JSScript * | |
9426 | JS_GetFrameScript(JSContext *cx, JSStackFrame *fp); | |
9427 | extern __attribute__((visibility ("default"))) jsbytecode * | |
9428 | JS_GetFramePC(JSContext *cx, JSStackFrame *fp); | |
9429 | extern __attribute__((visibility ("default"))) JSStackFrame * | |
9430 | JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); | |
9431 | extern JSPrincipals * | |
9432 | js_StackFramePrincipals(JSContext *cx, JSStackFrame *fp); | |
9433 | JSPrincipals * | |
9434 | js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller); | |
9435 | extern __attribute__((visibility ("default"))) void * | |
9436 | JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp); | |
9437 | extern __attribute__((visibility ("default"))) void | |
9438 | JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation); | |
9439 | extern __attribute__((visibility ("default"))) void * | |
9440 | JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp); | |
9441 | extern __attribute__((visibility ("default"))) JSBool | |
9442 | JS_IsScriptFrame(JSContext *cx, JSStackFrame *fp); | |
9443 | extern __attribute__((visibility ("default"))) JSObject * | |
9444 | JS_GetFrameObject(JSContext *cx, JSStackFrame *fp); | |
9445 | extern __attribute__((visibility ("default"))) JSObject * | |
9446 | JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp); | |
9447 | extern __attribute__((visibility ("default"))) JSObject * | |
9448 | JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp); | |
9449 | extern __attribute__((visibility ("default"))) JSBool | |
9450 | JS_GetFrameThis(JSContext *cx, JSStackFrame *fp, jsval *thisv); | |
9451 | extern __attribute__((visibility ("default"))) JSFunction * | |
9452 | JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp); | |
9453 | extern __attribute__((visibility ("default"))) JSObject * | |
9454 | JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp); | |
9455 | extern __attribute__((visibility ("default"))) JSBool | |
9456 | JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp); | |
9457 | extern __attribute__((visibility ("default"))) JSBool | |
9458 | JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp); | |
9459 | extern __attribute__((visibility ("default"))) jsval | |
9460 | JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp); | |
9461 | extern __attribute__((visibility ("default"))) void | |
9462 | JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval); | |
9463 | extern __attribute__((visibility ("default"))) JSObject * | |
9464 | JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp); | |
9465 | extern __attribute__((visibility ("default"))) JSBool | |
9466 | JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp); | |
9467 | extern __attribute__((visibility ("default"))) const char * | |
9468 | JS_GetScriptFilename(JSContext *cx, JSScript *script); | |
9469 | extern __attribute__((visibility ("default"))) uintN | |
9470 | JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script); | |
9471 | extern __attribute__((visibility ("default"))) uintN | |
9472 | JS_GetScriptLineExtent(JSContext *cx, JSScript *script); | |
9473 | extern __attribute__((visibility ("default"))) JSVersion | |
9474 | JS_GetScriptVersion(JSContext *cx, JSScript *script); | |
9475 | extern __attribute__((visibility ("default"))) void | |
9476 | JS_SetNewScriptHookProc(JSRuntime *rt, JSNewScriptHook hook, void *callerdata); | |
9477 | extern __attribute__((visibility ("default"))) void | |
9478 | JS_SetDestroyScriptHookProc(JSRuntime *rt, JSDestroyScriptHook hook, | |
9479 | void *callerdata); | |
9480 | extern __attribute__((visibility ("default"))) JSBool | |
9481 | JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp, | |
9482 | const jschar *chars, uintN length, | |
9483 | const char *filename, uintN lineno, | |
9484 | jsval *rval); | |
9485 | extern __attribute__((visibility ("default"))) JSBool | |
9486 | JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp, | |
9487 | const char *bytes, uintN length, | |
9488 | const char *filename, uintN lineno, | |
9489 | jsval *rval); | |
9490 | typedef struct JSPropertyDesc { | |
9491 | jsval id; | |
9492 | jsval value; | |
9493 | uint8 flags; | |
9494 | uint8 spare; | |
9495 | uint16 slot; | |
9496 | jsval alias; | |
9497 | } JSPropertyDesc; | |
9498 | typedef struct JSPropertyDescArray { | |
9499 | uint32 length; | |
9500 | JSPropertyDesc *array; | |
9501 | } JSPropertyDescArray; | |
9502 | typedef struct JSScopeProperty JSScopeProperty; | |
9503 | extern __attribute__((visibility ("default"))) JSScopeProperty * | |
9504 | JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp); | |
9505 | extern __attribute__((visibility ("default"))) JSBool | |
9506 | JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *shape, | |
9507 | JSPropertyDesc *pd); | |
9508 | extern __attribute__((visibility ("default"))) JSBool | |
9509 | JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda); | |
9510 | extern __attribute__((visibility ("default"))) void | |
9511 | JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda); | |
9512 | extern __attribute__((visibility ("default"))) JSBool | |
9513 | JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure); | |
9514 | extern __attribute__((visibility ("default"))) JSBool | |
9515 | JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure); | |
9516 | extern __attribute__((visibility ("default"))) JSBool | |
9517 | JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); | |
9518 | extern __attribute__((visibility ("default"))) JSBool | |
9519 | JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); | |
9520 | extern __attribute__((visibility ("default"))) JSBool | |
9521 | JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure); | |
9522 | extern __attribute__((visibility ("default"))) JSBool | |
9523 | JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); | |
9524 | extern __attribute__((visibility ("default"))) size_t | |
9525 | JS_GetObjectTotalSize(JSContext *cx, JSObject *obj); | |
9526 | extern __attribute__((visibility ("default"))) size_t | |
9527 | JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun); | |
9528 | extern __attribute__((visibility ("default"))) size_t | |
9529 | JS_GetScriptTotalSize(JSContext *cx, JSScript *script); | |
9530 | extern __attribute__((visibility ("default"))) uint32 | |
9531 | JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp); | |
9532 | extern __attribute__((visibility ("default"))) uint32 | |
9533 | JS_GetScriptFilenameFlags(JSScript *script); | |
9534 | extern __attribute__((visibility ("default"))) JSBool | |
9535 | JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags); | |
9536 | extern __attribute__((visibility ("default"))) JSBool | |
9537 | JS_IsSystemObject(JSContext *cx, JSObject *obj); | |
9538 | extern __attribute__((visibility ("default"))) JSBool | |
9539 | JS_MakeSystemObject(JSContext *cx, JSObject *obj); | |
9540 | extern __attribute__((visibility ("default"))) JSObject * | |
9541 | JS_UnwrapObject(JSContext *cx, JSObject *obj); | |
9542 | extern __attribute__((visibility ("default"))) void | |
9543 | js_RevertVersion(JSContext *cx); | |
9544 | extern __attribute__((visibility ("default"))) const JSDebugHooks * | |
9545 | JS_GetGlobalDebugHooks(JSRuntime *rt); | |
9546 | extern __attribute__((visibility ("default"))) JSDebugHooks * | |
9547 | JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks); | |
9548 | extern __attribute__((visibility ("default"))) JSDebugHooks * | |
9549 | JS_ClearContextDebugHooks(JSContext *cx); | |
9550 | extern __attribute__((visibility ("default"))) JSBool | |
9551 | JS_StartProfiling(); | |
9552 | extern __attribute__((visibility ("default"))) void | |
9553 | JS_StopProfiling(); | |
9554 | extern __attribute__((visibility ("default"))) JSBool | |
9555 | JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj); | |
9556 | } | |
9557 | typedef enum JSTryNoteKind { | |
9558 | JSTRY_CATCH, | |
9559 | JSTRY_FINALLY, | |
9560 | JSTRY_ITER | |
9561 | } JSTryNoteKind; | |
9562 | namespace js { | |
9563 | class UpvarCookie | |
9564 | { | |
9565 | uint32 value; | |
9566 | static const uint32 FREE_VALUE = 0xfffffffful; | |
9567 | void checkInvariants() { | |
9568 | typedef int js_static_assert47[(sizeof(UpvarCookie) == sizeof(uint32)) ? 1 : -1]; | |
9569 | typedef int js_static_assert48[(UPVAR_LEVEL_LIMIT < FREE_LEVEL) ? 1 : -1]; | |
9570 | } | |
9571 | public: | |
9572 | static const uint16 FREE_LEVEL = 0x3fff; | |
9573 | static const uint16 UPVAR_LEVEL_LIMIT = 16; | |
9574 | static const uint16 CALLEE_SLOT = 0xffff; | |
9575 | static bool isLevelReserved(uint16 level) { return level >= FREE_LEVEL; } | |
9576 | bool isFree() const { return value == FREE_VALUE; } | |
9577 | uint32 asInteger() const { return value; } | |
9578 | uint16 level() const { ((void) 0); return uint16(value >> 16); } | |
9579 | uint16 slot() const { ((void) 0); return uint16(value); } | |
9580 | void set(const UpvarCookie &other) { set(other.level(), other.slot()); } | |
9581 | void set(uint16 newLevel, uint16 newSlot) { value = (uint32(newLevel) << 16) | newSlot; } | |
9582 | void makeFree() { set(0xffff, 0xffff); ((void) 0); } | |
9583 | void fromInteger(uint32 u32) { value = u32; } | |
9584 | }; | |
9585 | } | |
9586 | struct JSTryNote { | |
9587 | uint8 kind; | |
9588 | uint8 padding; | |
9589 | uint16 stackDepth; | |
9590 | uint32 start; | |
9591 | uint32 length; | |
9592 | }; | |
9593 | typedef struct JSTryNoteArray { | |
9594 | JSTryNote *vector; | |
9595 | uint32 length; | |
9596 | } JSTryNoteArray; | |
9597 | typedef struct JSObjectArray { | |
9598 | JSObject **vector; | |
9599 | uint32 length; | |
9600 | } JSObjectArray; | |
9601 | typedef struct JSUpvarArray { | |
9602 | js::UpvarCookie *vector; | |
9603 | uint32 length; | |
9604 | } JSUpvarArray; | |
9605 | typedef struct JSConstArray { | |
9606 | js::Value *vector; | |
9607 | uint32 length; | |
9608 | } JSConstArray; | |
9609 | struct JSArenaPool; | |
9610 | namespace js { | |
9611 | struct GlobalSlotArray { | |
9612 | struct Entry { | |
9613 | uint32 atomIndex; | |
9614 | uint32 slot; | |
9615 | }; | |
9616 | Entry *vector; | |
9617 | uint32 length; | |
9618 | }; | |
9619 | struct Shape; | |
9620 | enum BindingKind { NONE, ARGUMENT, VARIABLE, CONSTANT, UPVAR }; | |
9621 | class Bindings { | |
9622 | js::Shape *lastBinding; | |
9623 | uint16 nargs; | |
9624 | uint16 nvars; | |
9625 | uint16 nupvars; | |
9626 | public: | |
9627 | inline Bindings(JSContext *cx); | |
9628 | inline void transfer(JSContext *cx, Bindings *bindings); | |
9629 | inline void clone(JSContext *cx, Bindings *bindings); | |
9630 | uint16 countArgs() const { return nargs; } | |
9631 | uint16 countVars() const { return nvars; } | |
9632 | uint16 countUpvars() const { return nupvars; } | |
9633 | uintN countArgsAndVars() const { return nargs + nvars; } | |
9634 | uintN countLocalNames() const { return nargs + nvars + nupvars; } | |
9635 | bool hasUpvars() const { return nupvars > 0; } | |
9636 | bool hasLocalNames() const { return countLocalNames() > 0; } | |
9637 | inline const js::Shape *lastShape() const; | |
9638 | enum { | |
9639 | BINDING_COUNT_LIMIT = 0xFFFF | |
9640 | }; | |
9641 | bool add(JSContext *cx, JSAtom *name, BindingKind kind); | |
9642 | bool addVariable(JSContext *cx, JSAtom *name) { | |
9643 | return add(cx, name, VARIABLE); | |
9644 | } | |
9645 | bool addConstant(JSContext *cx, JSAtom *name) { | |
9646 | return add(cx, name, CONSTANT); | |
9647 | } | |
9648 | bool addUpvar(JSContext *cx, JSAtom *name) { | |
9649 | return add(cx, name, UPVAR); | |
9650 | } | |
9651 | bool addArgument(JSContext *cx, JSAtom *name, uint16 *slotp) { | |
9652 | ((void) 0); | |
9653 | *slotp = nargs; | |
9654 | return add(cx, name, ARGUMENT); | |
9655 | } | |
9656 | bool addDestructuring(JSContext *cx, uint16 *slotp) { | |
9657 | *slotp = nargs; | |
9658 | return add(cx, __null, ARGUMENT); | |
9659 | } | |
9660 | BindingKind lookup(JSContext *cx, JSAtom *name, uintN *indexp) const; | |
9661 | bool hasBinding(JSContext *cx, JSAtom *name) const { | |
9662 | return lookup(cx, name, __null) != NONE; | |
9663 | } | |
9664 | jsuword * | |
9665 | getLocalNameArray(JSContext *cx, JSArenaPool *pool); | |
9666 | int sharpSlotBase(JSContext *cx); | |
9667 | void makeImmutable(); | |
9668 | const js::Shape *lastArgument() const; | |
9669 | const js::Shape *lastVariable() const; | |
9670 | const js::Shape *lastUpvar() const; | |
9671 | void trace(JSTracer *trc); | |
9672 | }; | |
9673 | } | |
9674 | struct JSScript { | |
9675 | static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, | |
9676 | uint32 nobjects, uint32 nupvars, uint32 nregexps, | |
9677 | uint32 ntrynotes, uint32 nconsts, uint32 nglobals, | |
9678 | uint16 nClosedArgs, uint16 nClosedVars, JSVersion version); | |
9679 | static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); | |
9680 | JSCList links; | |
9681 | jsbytecode *code; | |
9682 | uint32 length; | |
9683 | private: | |
9684 | uint16 version; | |
9685 | size_t callCount_; | |
9686 | public: | |
9687 | uint16 nfixed; | |
9688 | uint8 objectsOffset; | |
9689 | uint8 upvarsOffset; | |
9690 | uint8 regexpsOffset; | |
9691 | uint8 trynotesOffset; | |
9692 | uint8 globalsOffset; | |
9693 | uint8 constOffset; | |
9694 | bool noScriptRval:1; | |
9695 | bool savedCallerFun:1; | |
9696 | bool hasSharps:1; | |
9697 | bool strictModeCode:1; | |
9698 | bool compileAndGo:1; | |
9699 | bool usesEval:1; | |
9700 | bool usesArguments:1; | |
9701 | bool warnedAboutTwoArgumentEval:1; | |
9702 | bool hasSingletons:1; | |
9703 | jsbytecode *main; | |
9704 | JSAtomMap atomMap; | |
9705 | JSCompartment *compartment; | |
9706 | const char *filename; | |
9707 | uint32 lineno; | |
9708 | uint16 nslots; | |
9709 | uint16 staticLevel; | |
9710 | uint16 nClosedArgs; | |
9711 | uint16 nClosedVars; | |
9712 | js::Bindings bindings; | |
9713 | JSPrincipals *principals; | |
9714 | union { | |
9715 | JSObject *object; | |
9716 | JSScript *nextToGC; | |
9717 | } u; | |
9718 | uint32 *closedSlots; | |
9719 | public: | |
9720 | jssrcnote *notes() { return (jssrcnote *)(code + length); } | |
9721 | static const uint8 INVALID_OFFSET = 0xFF; | |
9722 | static bool isValidOffset(uint8 offset) { return offset != INVALID_OFFSET; } | |
9723 | JSObjectArray *objects() { | |
9724 | ((void) 0); | |
9725 | return (JSObjectArray *)((uint8 *) (this + 1) + objectsOffset); | |
9726 | } | |
9727 | JSUpvarArray *upvars() { | |
9728 | ((void) 0); | |
9729 | return (JSUpvarArray *) ((uint8 *) (this + 1) + upvarsOffset); | |
9730 | } | |
9731 | JSObjectArray *regexps() { | |
9732 | ((void) 0); | |
9733 | return (JSObjectArray *) ((uint8 *) (this + 1) + regexpsOffset); | |
9734 | } | |
9735 | JSTryNoteArray *trynotes() { | |
9736 | ((void) 0); | |
9737 | return (JSTryNoteArray *) ((uint8 *) (this + 1) + trynotesOffset); | |
9738 | } | |
9739 | js::GlobalSlotArray *globals() { | |
9740 | ((void) 0); | |
9741 | return (js::GlobalSlotArray *) ((uint8 *) (this + 1) + globalsOffset); | |
9742 | } | |
9743 | JSConstArray *consts() { | |
9744 | ((void) 0); | |
9745 | return (JSConstArray *) ((uint8 *) (this + 1) + constOffset); | |
9746 | } | |
9747 | JSAtom *getAtom(size_t index) { | |
9748 | ((void) 0); | |
9749 | return atomMap.vector[index]; | |
9750 | } | |
9751 | JSObject *getObject(size_t index) { | |
9752 | JSObjectArray *arr = objects(); | |
9753 | ((void) 0); | |
9754 | return arr->vector[index]; | |
9755 | } | |
9756 | uint32 getGlobalSlot(size_t index) { | |
9757 | js::GlobalSlotArray *arr = globals(); | |
9758 | ((void) 0); | |
9759 | return arr->vector[index].slot; | |
9760 | } | |
9761 | JSAtom *getGlobalAtom(size_t index) { | |
9762 | js::GlobalSlotArray *arr = globals(); | |
9763 | ((void) 0); | |
9764 | return getAtom(arr->vector[index].atomIndex); | |
9765 | } | |
9766 | JSVersion getVersion() const { | |
9767 | return JSVersion(version); | |
9768 | } | |
9769 | inline JSFunction *getFunction(size_t index); | |
9770 | inline JSObject *getRegExp(size_t index); | |
9771 | const js::Value &getConst(size_t index) { | |
9772 | JSConstArray *arr = consts(); | |
9773 | ((void) 0); | |
9774 | return arr->vector[index]; | |
9775 | } | |
9776 | inline bool isEmpty() const; | |
9777 | uint32 getClosedArg(uint32 index) { | |
9778 | ((void) 0); | |
9779 | return closedSlots[index]; | |
9780 | } | |
9781 | uint32 getClosedVar(uint32 index) { | |
9782 | ((void) 0); | |
9783 | return closedSlots[nClosedArgs + index]; | |
9784 | } | |
9785 | void copyClosedSlotsTo(JSScript *other); | |
9786 | }; | |
9787 | static inline uintN | |
9788 | StackDepth(JSScript *script) | |
9789 | { | |
9790 | return script->nslots - script->nfixed; | |
9791 | } | |
9792 | extern __attribute__((visibility ("default"))) js::Class js_ScriptClass; | |
9793 | extern JSObject * | |
9794 | js_InitScriptClass(JSContext *cx, JSObject *obj); | |
9795 | extern JSBool | |
9796 | js_InitRuntimeScriptState(JSRuntime *rt); | |
9797 | extern void | |
9798 | js_FreeRuntimeScriptState(JSRuntime *rt); | |
9799 | extern const char * | |
9800 | js_SaveScriptFilename(JSContext *cx, const char *filename); | |
9801 | extern const char * | |
9802 | js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags); | |
9803 | extern uint32 | |
9804 | js_GetScriptFilenameFlags(const char *filename); | |
9805 | extern void | |
9806 | js_MarkScriptFilename(const char *filename); | |
9807 | extern void | |
9808 | js_MarkScriptFilenames(JSRuntime *rt); | |
9809 | extern void | |
9810 | js_SweepScriptFilenames(JSRuntime *rt); | |
9811 | extern __attribute__((visibility ("default"))) void | |
9812 | js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); | |
9813 | extern void | |
9814 | js_CallDestroyScriptHook(JSContext *cx, JSScript *script); | |
9815 | extern void | |
9816 | js_DestroyScript(JSContext *cx, JSScript *script); | |
9817 | extern void | |
9818 | js_DestroyScriptFromGC(JSContext *cx, JSScript *script); | |
9819 | extern void | |
9820 | js_DestroyCachedScript(JSContext *cx, JSScript *script); | |
9821 | extern void | |
9822 | js_TraceScript(JSTracer *trc, JSScript *script); | |
9823 | extern JSObject * | |
9824 | js_NewScriptObject(JSContext *cx, JSScript *script); | |
9825 | extern jssrcnote * | |
9826 | js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9827 | extern uintN | |
9828 | js_FramePCToLineNumber(JSContext *cx, JSStackFrame *fp); | |
9829 | extern uintN | |
9830 | js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); | |
9831 | extern jsbytecode * | |
9832 | js_LineNumberToPC(JSScript *script, uintN lineno); | |
9833 | extern __attribute__((visibility ("default"))) uintN | |
9834 | js_GetScriptLineExtent(JSScript *script); | |
9835 | static inline JSOp | |
9836 | js_GetOpcode(JSContext *cx, JSScript *script, jsbytecode *pc) | |
9837 | { | |
9838 | JSOp op = (JSOp) *pc; | |
9839 | if (op == JSOP_TRAP) | |
9840 | op = JS_GetTrapOpcode(cx, script, pc); | |
9841 | return op; | |
9842 | } | |
9843 | extern JSScript * | |
9844 | js_CloneScript(JSContext *cx, JSScript *script); | |
9845 | extern JSBool | |
9846 | js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic); | |
9847 | inline | |
9848 | bool | |
9849 | JSObject::isScript() const | |
9850 | { | |
9851 | return getClass() == &js_ScriptClass; | |
9852 | } | |
9853 | inline JSScript * | |
9854 | JSObject::getScript() const | |
9855 | { | |
9856 | ((void) 0); | |
9857 | return static_cast<JSScript *>(getPrivate()); | |
9858 | } | |
9859 | struct JSFunction : public JSObject_Slots2 | |
9860 | { | |
9861 | uint16 nargs; | |
9862 | uint16 flags; | |
9863 | union U { | |
9864 | struct { | |
9865 | js::Native native; | |
9866 | js::Class *clasp; | |
9867 | JSNativeTraceInfo *trcinfo; | |
9868 | } n; | |
9869 | struct Scripted { | |
9870 | JSScript *script; | |
9871 | uint16 skipmin; | |
9872 | JSPackedBool wrapper; | |
9873 | js::Shape *names; | |
9874 | } i; | |
9875 | void *nativeOrScript; | |
9876 | } u; | |
9877 | JSAtom *atom; | |
9878 | bool optimizedClosure() const { return ((this)->flags & 0xc000) > 0x4000; } | |
9879 | bool needsWrapper() const { return (((this)->flags & 0xc000) == 0xc000) && u.i.skipmin != 0; } | |
9880 | bool isInterpreted() const { return (((this)->flags & 0xc000) >= 0x4000); } | |
9881 | bool isNative() const { return !(((this)->flags & 0xc000) >= 0x4000); } | |
9882 | bool isConstructor() const { return flags & 0x0200; } | |
9883 | bool isHeavyweight() const { return ((flags) & 0x80); } | |
9884 | bool isFlatClosure() const { return ((this)->flags & 0xc000) == 0x8000; } | |
9885 | bool isFunctionPrototype() const { return flags & 0x0800; } | |
9886 | inline bool inStrictMode() const; | |
9887 | void setArgCount(uint16 nargs) { | |
9888 | ((void) 0); | |
9889 | this->nargs = nargs; | |
9890 | } | |
9891 | enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) }; | |
9892 | bool mightEscape() const { | |
9893 | return isInterpreted() && (isFlatClosure() || !script()->bindings.hasUpvars()); | |
9894 | } | |
9895 | bool joinable() const { | |
9896 | return flags & 0x0001; | |
9897 | } | |
9898 | JSObject &compiledFunObj() { | |
9899 | return *this; | |
9900 | } | |
9901 | private: | |
9902 | enum { | |
9903 | METHOD_ATOM_SLOT = JSSLOT_FUN_METHOD_ATOM | |
9904 | }; | |
9905 | public: | |
9906 | void setJoinable() { | |
9907 | ((void) 0); | |
9908 | getSlotRef(METHOD_ATOM_SLOT).setNull(); | |
9909 | flags |= 0x0001; | |
9910 | } | |
9911 | JSAtom *methodAtom() const { | |
9912 | return (joinable() && getSlot(METHOD_ATOM_SLOT).isString()) | |
9913 | ? (((void) 0), (JSAtom *)getSlot(METHOD_ATOM_SLOT).toString()) | |
9914 | : __null; | |
9915 | } | |
9916 | void setMethodAtom(JSAtom *atom) { | |
9917 | ((void) 0); | |
9918 | getSlotRef(METHOD_ATOM_SLOT).setString((atom)); | |
9919 | } | |
9920 | js::Native maybeNative() const { | |
9921 | return isInterpreted() ? __null : u.n.native; | |
9922 | } | |
9923 | JSScript *script() const { | |
9924 | ((void) 0); | |
9925 | return u.i.script; | |
9926 | } | |
9927 | static uintN offsetOfNativeOrScript() { | |
9928 | typedef int js_static_assert49[(__builtin_offsetof (U, n.native) == __builtin_offsetof (U, i.script)) ? 1 : -1]; | |
9929 | typedef int js_static_assert50[(__builtin_offsetof (U, n.native) == __builtin_offsetof (U, nativeOrScript)) ? 1 : -1]; | |
9930 | return __builtin_offsetof (JSFunction, u.nativeOrScript); | |
9931 | } | |
9932 | static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS; | |
9933 | }; | |
9934 | extern js::Class js_ArgumentsClass; | |
9935 | namespace js { | |
9936 | extern Class StrictArgumentsClass; | |
9937 | struct ArgumentsData { | |
9938 | js::Value callee; | |
9939 | js::Value slots[1]; | |
9940 | }; | |
9941 | } | |
9942 | inline | |
9943 | bool | |
9944 | JSObject::isNormalArguments() const | |
9945 | { | |
9946 | return getClass() == &js_ArgumentsClass; | |
9947 | } | |
9948 | inline | |
9949 | bool | |
9950 | JSObject::isStrictArguments() const | |
9951 | { | |
9952 | return getClass() == &js::StrictArgumentsClass; | |
9953 | } | |
9954 | inline | |
9955 | bool | |
9956 | JSObject::isArguments() const | |
9957 | { | |
9958 | return isNormalArguments() || isStrictArguments(); | |
9959 | } | |
9960 | extern __attribute__((visibility ("default"))) js::Class js_CallClass; | |
9961 | extern __attribute__((visibility ("default"))) js::Class js_FunctionClass; | |
9962 | extern js::Class js_DeclEnvClass; | |
9963 | inline | |
9964 | bool | |
9965 | JSObject::isCall() const | |
9966 | { | |
9967 | return getClass() == &js_CallClass; | |
9968 | } | |
9969 | inline | |
9970 | bool | |
9971 | JSObject::isFunction() const | |
9972 | { | |
9973 | return getClass() == &js_FunctionClass; | |
9974 | } | |
9975 | inline JSFunction * | |
9976 | JSObject::getFunctionPrivate() const | |
9977 | { | |
9978 | ((void) 0); | |
9979 | return reinterpret_cast<JSFunction *>(getPrivate()); | |
9980 | } | |
9981 | namespace js { | |
9982 | extern JSObject * | |
9983 | NewCallObject(JSContext *cx, js::Bindings *bindings, JSObject &scopeChain, JSObject *callee); | |
9984 | static __attribute__((always_inline)) inline | |
9985 | bool | |
9986 | IsFunctionObject(const js::Value &v) | |
9987 | { | |
9988 | return v.isObject() && v.toObject().isFunction(); | |
9989 | } | |
9990 | static __attribute__((always_inline)) inline | |
9991 | bool | |
9992 | IsFunctionObject(const js::Value &v, JSObject **funobj) | |
9993 | { | |
9994 | return v.isObject() && (*funobj = &v.toObject())->isFunction(); | |
9995 | } | |
9996 | static __attribute__((always_inline)) inline | |
9997 | bool | |
9998 | IsFunctionObject(const js::Value &v, JSFunction **fun) | |
9999 | { | |
10000 | JSObject *funobj; | |
10001 | bool b = IsFunctionObject(v, &funobj); | |
10002 | if (b) | |
10003 | *fun = funobj->getFunctionPrivate(); | |
10004 | return b; | |
10005 | } | |
10006 | extern __attribute__((always_inline)) inline | |
10007 | bool | |
10008 | SameTraceType(const Value &lhs, const Value &rhs) | |
10009 | { | |
10010 | return SameType(lhs, rhs) && | |
10011 | (lhs.isPrimitive() || | |
10012 | lhs.toObject().isFunction() == rhs.toObject().isFunction()); | |
10013 | } | |
10014 | inline | |
10015 | bool | |
10016 | IsInternalFunctionObject(JSObject *funobj) | |
10017 | { | |
10018 | ((void) 0); | |
10019 | JSFunction *fun = (JSFunction *) funobj->getPrivate(); | |
10020 | return funobj == fun && (fun->flags & 0x08) && !funobj->getParent(); | |
10021 | } | |
10022 | static __attribute__((always_inline)) inline | |
10023 | bool | |
10024 | IsConstructing(const Value *vp) | |
10025 | { | |
10026 | return vp[1].isMagic(); | |
10027 | } | |
10028 | static __attribute__((always_inline)) inline | |
10029 | bool | |
10030 | IsConstructing_PossiblyWithGivenThisObject(const Value *vp, JSObject **ctorThis) | |
10031 | { | |
10032 | bool isCtor = vp[1].isMagic(); | |
10033 | if (isCtor) | |
10034 | *ctorThis = vp[1].getMagicObjectOrNullPayload(); | |
10035 | return isCtor; | |
10036 | } | |
10037 | inline const char * | |
10038 | GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes) | |
10039 | { | |
10040 | if (fun->atom) | |
10041 | return bytes->encode(cx, (fun->atom)); | |
10042 | return js_anonymous_str; | |
10043 | } | |
10044 | extern __attribute__((visibility ("default"))) bool | |
10045 | IsBuiltinFunctionConstructor(JSFunction *fun); | |
10046 | const Shape * | |
10047 | LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj); | |
10048 | } | |
10049 | extern JSString * | |
10050 | fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent); | |
10051 | extern JSFunction * | |
10052 | js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs, | |
10053 | uintN flags, JSObject *parent, JSAtom *atom); | |
10054 | extern JSObject * | |
10055 | js_InitFunctionClass(JSContext *cx, JSObject *obj); | |
10056 | extern JSObject * | |
10057 | js_InitArgumentsClass(JSContext *cx, JSObject *obj); | |
10058 | extern void | |
10059 | js_TraceFunction(JSTracer *trc, JSFunction *fun); | |
10060 | extern void | |
10061 | js_FinalizeFunction(JSContext *cx, JSFunction *fun); | |
10062 | extern JSObject * | |
10063 | js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, | |
10064 | JSObject *proto); | |
10065 | inline JSObject * | |
10066 | CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent) | |
10067 | { | |
10068 | ((void) 0); | |
10069 | JSObject *proto; | |
10070 | if (!js_GetClassPrototype(cx, parent, JSProto_Function, &proto)) | |
10071 | return __null; | |
10072 | return js_CloneFunctionObject(cx, fun, parent, proto); | |
10073 | } | |
10074 | extern JSObject * | |
10075 | js_AllocFlatClosure(JSContext *cx, JSFunction *fun, JSObject *scopeChain); | |
10076 | extern JSObject * | |
10077 | js_NewFlatClosure(JSContext *cx, JSFunction *fun, JSOp op, size_t oplen); | |
10078 | extern JSObject * | |
10079 | js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun); | |
10080 | extern JSFunction * | |
10081 | js_DefineFunction(JSContext *cx, JSObject *obj, jsid id, js::Native native, | |
10082 | uintN nargs, uintN flags); | |
10083 | extern JSFunction * | |
10084 | js_ValueToFunction(JSContext *cx, const js::Value *vp, uintN flags); | |
10085 | extern JSObject * | |
10086 | js_ValueToFunctionObject(JSContext *cx, js::Value *vp, uintN flags); | |
10087 | extern JSObject * | |
10088 | js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags); | |
10089 | extern void | |
10090 | js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags); | |
10091 | extern JSObject * | |
10092 | js_GetCallObject(JSContext *cx, JSStackFrame *fp); | |
10093 | extern JSObject * | |
10094 | js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain); | |
10095 | extern void | |
10096 | js_PutCallObject(JSContext *cx, JSStackFrame *fp); | |
10097 | extern JSBool | |
10098 | js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs, | |
10099 | js::Value *argv, uint32 nvars, js::Value *slots); | |
10100 | namespace js { | |
10101 | extern JSBool | |
10102 | GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
10103 | extern JSBool | |
10104 | GetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
10105 | extern JSBool | |
10106 | GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
10107 | extern JSBool | |
10108 | GetCallUpvar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
10109 | extern JSBool | |
10110 | SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); | |
10111 | extern JSBool | |
10112 | SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); | |
10113 | extern JSBool | |
10114 | SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); | |
10115 | } | |
10116 | extern JSBool | |
10117 | js_GetArgsValue(JSContext *cx, JSStackFrame *fp, js::Value *vp); | |
10118 | extern JSBool | |
10119 | js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, js::Value *vp); | |
10120 | extern JSObject * | |
10121 | js_GetArgsObject(JSContext *cx, JSStackFrame *fp); | |
10122 | extern void | |
10123 | js_PutArgsObject(JSContext *cx, JSStackFrame *fp); | |
10124 | inline | |
10125 | bool | |
10126 | js_IsNamedLambda(JSFunction *fun) { return (fun->flags & 0x08) && fun->atom; } | |
10127 | const uint32 JS_ARGS_LENGTH_MAX = ((JSUint32)1 << (19)) - 1024; | |
10128 | typedef int js_static_assert51[(JS_ARGS_LENGTH_MAX <= ((JSUint32)1 << (30))) ? 1 : -1]; | |
10129 | typedef int js_static_assert52[(((JS_ARGS_LENGTH_MAX << 1) | 1) <= ((jsint)0x7fffffff)) ? 1 : -1]; | |
10130 | extern JSBool | |
10131 | js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp); | |
10132 | extern JSBool | |
10133 | js_fun_apply(JSContext *cx, uintN argc, js::Value *vp); | |
10134 | extern JSBool | |
10135 | js_fun_call(JSContext *cx, uintN argc, js::Value *vp); | |
10136 | extern "C" { | |
10137 | typedef long int __jmp_buf[64] __attribute__ ((__aligned__ (16))); | |
10138 | struct __jmp_buf_tag | |
10139 | { | |
10140 | __jmp_buf __jmpbuf; | |
10141 | int __mask_was_saved; | |
10142 | __sigset_t __saved_mask; | |
10143 | }; | |
10144 | typedef struct __jmp_buf_tag jmp_buf[1]; | |
10145 | extern int setjmp (jmp_buf __env) throw (); | |
10146 | extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) throw (); | |
10147 | extern int _setjmp (struct __jmp_buf_tag __env[1]) throw (); | |
10148 | extern void longjmp (struct __jmp_buf_tag __env[1], int __val) | |
10149 | throw () __attribute__ ((__noreturn__)); | |
10150 | extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) | |
10151 | throw () __attribute__ ((__noreturn__)); | |
10152 | typedef struct __jmp_buf_tag sigjmp_buf[1]; | |
10153 | extern void siglongjmp (sigjmp_buf __env, int __val) | |
10154 | throw () __attribute__ ((__noreturn__)); | |
10155 | extern void longjmp (struct __jmp_buf_tag __env[1], int __val) throw () __asm__ ("" "__longjmp_chk") | |
10156 | __attribute__ ((__noreturn__)); | |
10157 | extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) throw () __asm__ ("" "__longjmp_chk") | |
10158 | __attribute__ ((__noreturn__)); | |
10159 | extern void siglongjmp (struct __jmp_buf_tag __env[1], int __val) throw () __asm__ ("" "__longjmp_chk") | |
10160 | __attribute__ ((__noreturn__)); | |
10161 | } | |
10162 | namespace js { | |
10163 | const size_t GC_CHUNK_SHIFT = 20; | |
10164 | const size_t GC_CHUNK_SIZE = size_t(1) << GC_CHUNK_SHIFT; | |
10165 | const size_t GC_CHUNK_MASK = GC_CHUNK_SIZE - 1; | |
10166 | __attribute__((visibility ("default"))) void * | |
10167 | AllocGCChunk(); | |
10168 | __attribute__((visibility ("default"))) void | |
10169 | FreeGCChunk(void *p); | |
10170 | class GCChunkAllocator { | |
10171 | public: | |
10172 | GCChunkAllocator() {} | |
10173 | void *alloc() { | |
10174 | void *chunk = doAlloc(); | |
10175 | ((void) 0); | |
10176 | return chunk; | |
10177 | } | |
10178 | void free(void *chunk) { | |
10179 | ((void) 0); | |
10180 | ((void) 0); | |
10181 | doFree(chunk); | |
10182 | } | |
10183 | private: | |
10184 | virtual void *doAlloc() { | |
10185 | return AllocGCChunk(); | |
10186 | } | |
10187 | virtual void doFree(void *chunk) { | |
10188 | FreeGCChunk(chunk); | |
10189 | } | |
10190 | GCChunkAllocator(const GCChunkAllocator &); | |
10191 | void operator=(const GCChunkAllocator &); | |
10192 | }; | |
10193 | extern GCChunkAllocator defaultGCChunkAllocator; | |
10194 | } | |
10195 | namespace js { | |
10196 | namespace gc { | |
10197 | enum ConservativeGCTest { | |
10198 | CGCT_VALID, | |
10199 | CGCT_VALIDWITHOFFSET, | |
10200 | CGCT_LOWBITSET, | |
10201 | CGCT_NOTARENA, | |
10202 | CGCT_NOTCHUNK, | |
10203 | CGCT_FREEARENA, | |
10204 | CGCT_WRONGTAG, | |
10205 | CGCT_NOTLIVE, | |
10206 | CGCT_END | |
10207 | }; | |
10208 | struct ConservativeGCStats { | |
10209 | uint32 counter[gc::CGCT_END]; | |
10210 | void add(const ConservativeGCStats &another) { | |
10211 | for (size_t i = 0; i != (sizeof (counter) / sizeof (counter)[0]); ++i) | |
10212 | counter[i] += another.counter[i]; | |
10213 | } | |
10214 | void dump(FILE *fp); | |
10215 | }; | |
10216 | } | |
10217 | } | |
10218 | extern __attribute__((visibility ("default"))) void | |
10219 | js_DumpGCStats(JSRuntime *rt, FILE *fp); | |
10220 | struct JSCompartment; | |
10221 | extern "C" void | |
10222 | js_TraceXML(JSTracer *trc, JSXML* thing); | |
10223 | namespace js { | |
10224 | struct Shape; | |
10225 | namespace gc { | |
10226 | enum FinalizeKind { | |
10227 | FINALIZE_OBJECT0, | |
10228 | FINALIZE_OBJECT2, | |
10229 | FINALIZE_OBJECT4, | |
10230 | FINALIZE_OBJECT8, | |
10231 | FINALIZE_OBJECT12, | |
10232 | FINALIZE_OBJECT16, | |
10233 | FINALIZE_OBJECT_LAST = FINALIZE_OBJECT16, | |
10234 | FINALIZE_FUNCTION, | |
10235 | FINALIZE_XML, | |
10236 | FINALIZE_SHORT_STRING, | |
10237 | FINALIZE_STRING, | |
10238 | FINALIZE_EXTERNAL_STRING, | |
10239 | FINALIZE_LIMIT | |
10240 | }; | |
10241 | const uintN JS_FINALIZE_OBJECT_LIMIT = 6; | |
10242 | struct ArenaHeader { | |
10243 | JSCompartment *compartment; | |
10244 | Arena<FreeCell> *next; | |
10245 | FreeCell *freeList; | |
10246 | unsigned thingKind; | |
10247 | bool isUsed; | |
10248 | size_t thingSize; | |
10249 | }; | |
10250 | template <typename T> | |
10251 | union ThingOrCell { | |
10252 | T t; | |
10253 | FreeCell cell; | |
10254 | }; | |
10255 | template <typename T, size_t N, size_t R> | |
10256 | struct Things { | |
10257 | ThingOrCell<T> things[N]; | |
10258 | char filler[R]; | |
10259 | }; | |
10260 | template <typename T, size_t N> | |
10261 | struct Things<T, N, 0> { | |
10262 | ThingOrCell<T> things[N]; | |
10263 | }; | |
10264 | template <typename T> | |
10265 | struct Arena { | |
10266 | static const size_t ArenaSize = 4096; | |
10267 | struct AlignedArenaHeader { | |
10268 | T align[(sizeof(ArenaHeader) + sizeof(T) - 1) / sizeof(T)]; | |
10269 | }; | |
10270 | union { | |
10271 | ArenaHeader aheader; | |
10272 | AlignedArenaHeader align; | |
10273 | }; | |
10274 | static const size_t ThingsPerArena = (ArenaSize - sizeof(AlignedArenaHeader)) / sizeof(T); | |
10275 | static const size_t FillerSize = ArenaSize - sizeof(AlignedArenaHeader) - sizeof(T) * ThingsPerArena; | |
10276 | Things<T, ThingsPerArena, FillerSize> t; | |
10277 | inline Chunk *chunk() const; | |
10278 | inline size_t arenaIndex() const; | |
10279 | inline ArenaHeader *header() { return &aheader; }; | |
10280 | inline MarkingDelay *getMarkingDelay() const; | |
10281 | inline ArenaBitmap *bitmap() const; | |
10282 | inline ConservativeGCTest mark(T *thing, JSTracer *trc); | |
10283 | void markDelayedChildren(JSTracer *trc); | |
10284 | inline bool inFreeList(void *thing) const; | |
10285 | inline T *getAlignedThing(void *thing); | |
10286 | void init(JSCompartment *compartment, unsigned thingKind); | |
10287 | }; | |
10288 | typedef int js_static_assert53[(sizeof(Arena<FreeCell>) == 4096) ? 1 : -1]; | |
10289 | static const uint32 BLACK = 0; | |
10290 | struct ArenaBitmap { | |
10291 | static const size_t BitCount = Arena<FreeCell>::ArenaSize / Cell::CellSize; | |
10292 | static const size_t BitWords = BitCount / (8 * 8); | |
10293 | uintptr_t bitmap[BitWords]; | |
10294 | __attribute__((always_inline)) inline bool isMarked(size_t bit, uint32 color) { | |
10295 | bit += color; | |
10296 | ((void) 0); | |
10297 | uintptr_t *word = &bitmap[bit / (8 * 8)]; | |
10298 | return *word & (uintptr_t(1) << (bit % (8 * 8))); | |
10299 | } | |
10300 | __attribute__((always_inline)) inline bool markIfUnmarked(size_t bit, uint32 color) { | |
10301 | ((void) 0); | |
10302 | uintptr_t *word = &bitmap[bit / (8 * 8)]; | |
10303 | uintptr_t mask = (uintptr_t(1) << (bit % (8 * 8))); | |
10304 | if (*word & mask) | |
10305 | return false; | |
10306 | *word |= mask; | |
10307 | if (color != BLACK) { | |
10308 | bit += color; | |
10309 | word = &bitmap[bit / (8 * 8)]; | |
10310 | mask = (uintptr_t(1) << (bit % (8 * 8))); | |
10311 | if (*word & mask) | |
10312 | return false; | |
10313 | *word |= mask; | |
10314 | } | |
10315 | return true; | |
10316 | } | |
10317 | __attribute__((always_inline)) inline void unmark(size_t bit, uint32 color) { | |
10318 | bit += color; | |
10319 | ((void) 0); | |
10320 | uintptr_t *word = &bitmap[bit / (8 * 8)]; | |
10321 | *word &= ~(uintptr_t(1) << (bit % (8 * 8))); | |
10322 | } | |
10323 | }; | |
10324 | typedef int js_static_assert54[(Arena<FreeCell>::ArenaSize % Cell::CellSize == 0) ? 1 : -1]; | |
10325 | typedef int js_static_assert55[(ArenaBitmap::BitCount % (8 * 8) == 0) ? 1 : -1]; | |
10326 | struct MarkingDelay { | |
10327 | Arena<Cell> *link; | |
10328 | uintptr_t unmarkedChildren; | |
10329 | jsuword start; | |
10330 | void init() | |
10331 | { | |
10332 | link = __null; | |
10333 | unmarkedChildren = 0; | |
10334 | } | |
10335 | }; | |
10336 | struct EmptyArenaLists { | |
10337 | Arena<FreeCell> *cellFreeList; | |
10338 | Arena<FreeCell> *freeLists[FINALIZE_LIMIT]; | |
10339 | void init() { | |
10340 | PodZero(this); | |
10341 | } | |
10342 | Arena<FreeCell> *getOtherArena() { | |
10343 | Arena<FreeCell> *arena = cellFreeList; | |
10344 | if (arena) { | |
10345 | cellFreeList = arena->header()->next; | |
10346 | return arena; | |
10347 | } | |
10348 | for (int i = 0; i < FINALIZE_LIMIT; i++) { | |
10349 | if ((arena = (Arena<FreeCell> *) freeLists[i])) { | |
10350 | freeLists[i] = freeLists[i]->header()->next; | |
10351 | return arena; | |
10352 | } | |
10353 | } | |
10354 | ; | |
10355 | return __null; | |
10356 | } | |
10357 | template <typename T> | |
10358 | inline Arena<T> *getTypedFreeList(unsigned thingKind); | |
10359 | template <typename T> | |
10360 | inline Arena<T> *getNext(JSCompartment *comp, unsigned thingKind); | |
10361 | template <typename T> | |
10362 | inline void insert(Arena<T> *arena); | |
10363 | }; | |
10364 | template <typename T> | |
10365 | inline Arena<T> * | |
10366 | EmptyArenaLists::getTypedFreeList(unsigned thingKind) { | |
10367 | ((void) 0); | |
10368 | Arena<T> *arena = (Arena<T>*) freeLists[thingKind]; | |
10369 | if (arena) { | |
10370 | freeLists[thingKind] = freeLists[thingKind]->header()->next; | |
10371 | return arena; | |
10372 | } | |
10373 | return __null; | |
10374 | } | |
10375 | template<typename T> | |
10376 | inline Arena<T> * | |
10377 | EmptyArenaLists::getNext(JSCompartment *comp, unsigned thingKind) { | |
10378 | Arena<T> *arena = getTypedFreeList<T>(thingKind); | |
10379 | if (arena) { | |
10380 | ((void) 0); | |
10381 | ((void) 0); | |
10382 | arena->header()->isUsed = true; | |
10383 | arena->header()->thingKind = thingKind; | |
10384 | arena->header()->compartment = comp; | |
10385 | return arena; | |
10386 | } | |
10387 | arena = (Arena<T> *)getOtherArena(); | |
10388 | ((void) 0); | |
10389 | arena->init(comp, thingKind); | |
10390 | return arena; | |
10391 | } | |
10392 | template <typename T> | |
10393 | inline void | |
10394 | EmptyArenaLists::insert(Arena<T> *arena) { | |
10395 | unsigned thingKind = arena->header()->thingKind; | |
10396 | ((void) 0); | |
10397 | arena->header()->next = freeLists[thingKind]; | |
10398 | freeLists[thingKind] = (Arena<FreeCell> *) arena; | |
10399 | } | |
10400 | struct ChunkInfo { | |
10401 | Chunk *link; | |
10402 | JSRuntime *runtime; | |
10403 | EmptyArenaLists emptyArenaLists; | |
10404 | size_t age; | |
10405 | size_t numFree; | |
10406 | }; | |
10407 | struct Chunk { | |
10408 | static const size_t BytesPerArena = sizeof(Arena<FreeCell>) + | |
10409 | sizeof(ArenaBitmap) + | |
10410 | sizeof(MarkingDelay); | |
10411 | static const size_t ArenasPerChunk = (GC_CHUNK_SIZE - sizeof(ChunkInfo)) / BytesPerArena; | |
10412 | Arena<FreeCell> arenas[ArenasPerChunk]; | |
10413 | ArenaBitmap bitmaps[ArenasPerChunk]; | |
10414 | MarkingDelay markingDelay[ArenasPerChunk]; | |
10415 | ChunkInfo info; | |
10416 | void clearMarkBitmap(); | |
10417 | void init(JSRuntime *rt); | |
10418 | bool unused(); | |
10419 | bool hasAvailableArenas(); | |
10420 | bool withinArenasRange(Cell *cell); | |
10421 | template <typename T> | |
10422 | Arena<T> *allocateArena(JSCompartment *comp, unsigned thingKind); | |
10423 | template <typename T> | |
10424 | void releaseArena(Arena<T> *a); | |
10425 | JSRuntime *getRuntime(); | |
10426 | }; | |
10427 | typedef int js_static_assert56[(sizeof(Chunk) <= GC_CHUNK_SIZE) ? 1 : -1]; | |
10428 | typedef int js_static_assert57[(sizeof(Chunk) + Chunk::BytesPerArena > GC_CHUNK_SIZE) ? 1 : -1]; | |
10429 | Arena<Cell> * | |
10430 | Cell::arena() const | |
10431 | { | |
10432 | uintptr_t addr = uintptr_t(this); | |
10433 | ((void) 0); | |
10434 | addr &= ~(Arena<FreeCell>::ArenaSize - 1); | |
10435 | return reinterpret_cast<Arena<Cell> *>(addr); | |
10436 | } | |
10437 | Chunk * | |
10438 | Cell::chunk() const | |
10439 | { | |
10440 | uintptr_t addr = uintptr_t(this); | |
10441 | ((void) 0); | |
10442 | addr &= ~(GC_CHUNK_SIZE - 1); | |
10443 | return reinterpret_cast<Chunk *>(addr); | |
10444 | } | |
10445 | ArenaBitmap * | |
10446 | Cell::bitmap() const | |
10447 | { | |
10448 | return &chunk()->bitmaps[arena()->arenaIndex()]; | |
10449 | } | |
10450 | size_t | |
10451 | Cell::cellIndex() const | |
10452 | { | |
10453 | return reinterpret_cast<const FreeCell *>(this) - reinterpret_cast<FreeCell *>(&arena()->t); | |
10454 | } | |
10455 | template <typename T> | |
10456 | Chunk * | |
10457 | Arena<T>::chunk() const | |
10458 | { | |
10459 | uintptr_t addr = uintptr_t(this); | |
10460 | ((void) 0); | |
10461 | addr &= ~(GC_CHUNK_SIZE - 1); | |
10462 | return reinterpret_cast<Chunk *>(addr); | |
10463 | } | |
10464 | template <typename T> | |
10465 | size_t | |
10466 | Arena<T>::arenaIndex() const | |
10467 | { | |
10468 | return reinterpret_cast<const Arena<FreeCell> *>(this) - chunk()->arenas; | |
10469 | } | |
10470 | template <typename T> | |
10471 | MarkingDelay * | |
10472 | Arena<T>::getMarkingDelay() const | |
10473 | { | |
10474 | return &chunk()->markingDelay[arenaIndex()]; | |
10475 | } | |
10476 | template <typename T> | |
10477 | ArenaBitmap * | |
10478 | Arena<T>::bitmap() const | |
10479 | { | |
10480 | return &chunk()->bitmaps[arenaIndex()]; | |
10481 | } | |
10482 | template <typename T> | |
10483 | inline T * | |
10484 | Arena<T>::getAlignedThing(void *thing) | |
10485 | { | |
10486 | jsuword start = reinterpret_cast<jsuword>(&t.things[0]); | |
10487 | jsuword offset = reinterpret_cast<jsuword>(thing) - start; | |
10488 | offset -= offset % aheader.thingSize; | |
10489 | return reinterpret_cast<T *>(start + offset); | |
10490 | } | |
10491 | static void | |
10492 | AssertValidColor(const void *thing, uint32 color) | |
10493 | { | |
10494 | ((void) 0); | |
10495 | } | |
10496 | inline | |
10497 | bool | |
10498 | Cell::isMarked(uint32 color = BLACK) const | |
10499 | { | |
10500 | AssertValidColor(this, color); | |
10501 | return bitmap()->isMarked(cellIndex(), color); | |
10502 | } | |
10503 | bool | |
10504 | Cell::markIfUnmarked(uint32 color = BLACK) const | |
10505 | { | |
10506 | AssertValidColor(this, color); | |
10507 | return bitmap()->markIfUnmarked(cellIndex(), color); | |
10508 | } | |
10509 | void | |
10510 | Cell::unmark(uint32 color) const | |
10511 | { | |
10512 | ((void) 0); | |
10513 | AssertValidColor(this, color); | |
10514 | bitmap()->unmark(cellIndex(), color); | |
10515 | } | |
10516 | JSCompartment * | |
10517 | Cell::compartment() const | |
10518 | { | |
10519 | return arena()->header()->compartment; | |
10520 | } | |
10521 | template <typename T> | |
10522 | static inline | |
10523 | Arena<T> * | |
10524 | GetArena(Cell *cell) | |
10525 | { | |
10526 | return reinterpret_cast<Arena<T> *>(cell->arena()); | |
10527 | } | |
10528 | const size_t GC_ARENA_ALLOCATION_TRIGGER = 30 * js::GC_CHUNK_SIZE; | |
10529 | const float GC_HEAP_GROWTH_FACTOR = 3.0f; | |
10530 | static inline size_t | |
10531 | GetFinalizableTraceKind(size_t thingKind) | |
10532 | { | |
10533 | typedef int js_static_assert58[(JSExternalString::TYPE_LIMIT == 8) ? 1 : -1]; | |
10534 | static const uint8 map[FINALIZE_LIMIT] = { | |
10535 | 0, | |
10536 | 0, | |
10537 | 0, | |
10538 | 0, | |
10539 | 0, | |
10540 | 0, | |
10541 | 0, | |
10542 | 2, | |
10543 | 1, | |
10544 | 1, | |
10545 | 1, | |
10546 | }; | |
10547 | ((void) 0); | |
10548 | return map[thingKind]; | |
10549 | } | |
10550 | static inline | |
10551 | bool | |
10552 | IsFinalizableStringKind(unsigned thingKind) | |
10553 | { | |
10554 | return unsigned(FINALIZE_SHORT_STRING) <= thingKind && | |
10555 | thingKind <= unsigned(FINALIZE_EXTERNAL_STRING); | |
10556 | } | |
10557 | static inline intN | |
10558 | GetExternalStringGCType(JSExternalString *str) | |
10559 | { | |
10560 | typedef int js_static_assert59[(FINALIZE_STRING + 1 == FINALIZE_EXTERNAL_STRING) ? 1 : -1]; | |
10561 | ((void) 0); | |
10562 | unsigned thingKind = str->externalStringType; | |
10563 | ((void) 0); | |
10564 | return intN(thingKind); | |
10565 | } | |
10566 | static inline uint32 | |
10567 | GetGCThingTraceKind(void *thing) | |
10568 | { | |
10569 | ((void) 0); | |
10570 | if (JSString::isStatic(thing)) | |
10571 | return 1; | |
10572 | Cell *cell = reinterpret_cast<Cell *>(thing); | |
10573 | return GetFinalizableTraceKind(cell->arena()->header()->thingKind); | |
10574 | } | |
10575 | static inline JSRuntime * | |
10576 | GetGCThingRuntime(void *thing) | |
10577 | { | |
10578 | return reinterpret_cast<FreeCell *>(thing)->chunk()->info.runtime; | |
10579 | } | |
10580 | struct ArenaList { | |
10581 | Arena<FreeCell> *head; | |
10582 | Arena<FreeCell> *cursor; | |
10583 | inline void init() { | |
10584 | head = __null; | |
10585 | cursor = __null; | |
10586 | } | |
10587 | inline Arena<FreeCell> *getNextWithFreeList() { | |
10588 | Arena<FreeCell> *a; | |
10589 | while (cursor != __null) { | |
10590 | ArenaHeader *aheader = cursor->header(); | |
10591 | a = cursor; | |
10592 | cursor = aheader->next; | |
10593 | if (aheader->freeList) | |
10594 | return a; | |
10595 | } | |
10596 | return __null; | |
10597 | } | |
10598 | inline void insert(Arena<FreeCell> *a) { | |
10599 | a->header()->next = head; | |
10600 | head = a; | |
10601 | } | |
10602 | void releaseAll() { | |
10603 | while (head) { | |
10604 | Arena<FreeCell> *next = head->header()->next; | |
10605 | head->chunk()->releaseArena(head); | |
10606 | head = next; | |
10607 | } | |
10608 | head = __null; | |
10609 | cursor = __null; | |
10610 | } | |
10611 | inline bool isEmpty() const { | |
10612 | return (head == __null); | |
10613 | } | |
10614 | }; | |
10615 | struct FreeLists { | |
10616 | FreeCell **finalizables[FINALIZE_LIMIT]; | |
10617 | void purge(); | |
10618 | inline FreeCell *getNext(uint32 kind) { | |
10619 | FreeCell *top = __null; | |
10620 | if (finalizables[kind]) { | |
10621 | top = *finalizables[kind]; | |
10622 | if (top) { | |
10623 | *finalizables[kind] = top->link; | |
10624 | } else { | |
10625 | finalizables[kind] = __null; | |
10626 | } | |
10627 | } | |
10628 | return top; | |
10629 | } | |
10630 | template <typename T> | |
10631 | inline void populate(Arena<T> *a, uint32 thingKind) { | |
10632 | finalizables[thingKind] = &a->header()->freeList; | |
10633 | } | |
10634 | }; | |
10635 | } | |
10636 | typedef Vector<gc::Chunk *, 32, SystemAllocPolicy> GCChunks; | |
10637 | struct GCPtrHasher | |
10638 | { | |
10639 | typedef void *Lookup; | |
10640 | static HashNumber hash(void *key) { | |
10641 | return HashNumber(uintptr_t(key) >> JS_GCTHING_ZEROBITS); | |
10642 | } | |
10643 | static bool match(void *l, void *k) { return l == k; } | |
10644 | }; | |
10645 | typedef HashMap<void *, uint32, GCPtrHasher, SystemAllocPolicy> GCLocks; | |
10646 | struct RootInfo { | |
10647 | RootInfo() {} | |
10648 | RootInfo(const char *name, JSGCRootType type) : name(name), type(type) {} | |
10649 | const char *name; | |
10650 | JSGCRootType type; | |
10651 | }; | |
10652 | typedef js::HashMap<void *, | |
10653 | RootInfo, | |
10654 | js::DefaultHasher<void *>, | |
10655 | js::SystemAllocPolicy> RootedValueMap; | |
10656 | typedef int js_static_assert60[(sizeof(HashNumber) == 4) ? 1 : -1]; | |
10657 | struct WrapperHasher | |
10658 | { | |
10659 | typedef Value Lookup; | |
10660 | static HashNumber hash(Value key) { | |
10661 | uint64 bits = (Jsvalify(key)); | |
10662 | return (uint32)bits ^ (uint32)(bits >> 32); | |
10663 | } | |
10664 | static bool match(const Value &l, const Value &k) { return l == k; } | |
10665 | }; | |
10666 | typedef HashMap<Value, Value, WrapperHasher, SystemAllocPolicy> WrapperMap; | |
10667 | class AutoValueVector; | |
10668 | class AutoIdVector; | |
10669 | } | |
10670 | static inline void | |
10671 | CheckGCFreeListLink(js::gc::FreeCell *cell) | |
10672 | { | |
10673 | ((void) 0) | |
10674 | ; | |
10675 | ((void) 0); | |
10676 | } | |
10677 | extern | |
10678 | bool | |
10679 | RefillFinalizableFreeList(JSContext *cx, unsigned thingKind); | |
10680 | extern intN | |
10681 | js_GetExternalStringGCType(JSString *str); | |
10682 | extern __attribute__((visibility ("default"))) uint32 | |
10683 | js_GetGCThingTraceKind(void *thing); | |
10684 | extern JSBool | |
10685 | js_InitGC(JSRuntime *rt, uint32 maxbytes); | |
10686 | extern void | |
10687 | js_FinishGC(JSRuntime *rt); | |
10688 | extern JSBool | |
10689 | js_AddRoot(JSContext *cx, js::Value *vp, const char *name); | |
10690 | extern JSBool | |
10691 | js_AddGCThingRoot(JSContext *cx, void **rp, const char *name); | |
10692 | extern uint32 | |
10693 | js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); | |
10694 | typedef struct JSPtrTable { | |
10695 | size_t count; | |
10696 | void **array; | |
10697 | } JSPtrTable; | |
10698 | extern JSBool | |
10699 | js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); | |
10700 | extern JSBool | |
10701 | js_LockGCThingRT(JSRuntime *rt, void *thing); | |
10702 | extern void | |
10703 | js_UnlockGCThingRT(JSRuntime *rt, void *thing); | |
10704 | extern __attribute__((visibility ("default"))) bool | |
10705 | IsAboutToBeFinalized(JSContext *cx, void *thing); | |
10706 | extern __attribute__((visibility ("default"))) bool | |
10707 | js_GCThingIsMarked(void *thing, uintN color); | |
10708 | extern void | |
10709 | js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp); | |
10710 | namespace js { | |
10711 | extern void | |
10712 | MarkRuntime(JSTracer *trc); | |
10713 | extern void | |
10714 | TraceRuntime(JSTracer *trc); | |
10715 | extern __attribute__((visibility ("default"))) void | |
10716 | MarkContext(JSTracer *trc, JSContext *acx); | |
10717 | extern void | |
10718 | TriggerGC(JSRuntime *rt); | |
10719 | extern void | |
10720 | TriggerCompartmentGC(JSCompartment *comp); | |
10721 | extern void | |
10722 | MaybeGC(JSContext *cx); | |
10723 | } | |
10724 | typedef enum JSGCInvocationKind { | |
10725 | GC_NORMAL = 0, | |
10726 | GC_LAST_CONTEXT = 1 | |
10727 | } JSGCInvocationKind; | |
10728 | extern void | |
10729 | js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind); | |
10730 | extern void | |
10731 | js_WaitForGC(JSRuntime *rt); | |
10732 | extern void | |
10733 | js_DestroyScriptsToGC(JSContext *cx, JSCompartment *comp); | |
10734 | namespace js { | |
10735 | class GCHelperThread { | |
10736 | static const size_t FREE_ARRAY_SIZE = size_t(1) << 16; | |
10737 | static const size_t FREE_ARRAY_LENGTH = FREE_ARRAY_SIZE / sizeof(void *); | |
10738 | PRThread* thread; | |
10739 | PRCondVar* wakeup; | |
10740 | PRCondVar* sweepingDone; | |
10741 | bool shutdown; | |
10742 | bool sweeping; | |
10743 | Vector<void **, 16, js::SystemAllocPolicy> freeVector; | |
10744 | void **freeCursor; | |
10745 | void **freeCursorEnd; | |
10746 | __attribute__((visibility ("default"))) void | |
10747 | replenishAndFreeLater(void *ptr); | |
10748 | static void freeElementsAndArray(void **array, void **end) { | |
10749 | ((void) 0); | |
10750 | for (void **p = array; p != end; ++p) | |
10751 | js_free(*p); | |
10752 | js_free(array); | |
10753 | } | |
10754 | static void threadMain(void* arg); | |
10755 | void threadLoop(JSRuntime *rt); | |
10756 | void doSweep(); | |
10757 | public: | |
10758 | GCHelperThread() | |
10759 | : thread(__null), | |
10760 | wakeup(__null), | |
10761 | sweepingDone(__null), | |
10762 | shutdown(false), | |
10763 | sweeping(false), | |
10764 | freeCursor(__null), | |
10765 | freeCursorEnd(__null) { } | |
10766 | bool init(JSRuntime *rt); | |
10767 | void finish(JSRuntime *rt); | |
10768 | void startBackgroundSweep(JSRuntime *rt); | |
10769 | void waitBackgroundSweepEnd(JSRuntime *rt); | |
10770 | void freeLater(void *ptr) { | |
10771 | ((void) 0); | |
10772 | if (freeCursor != freeCursorEnd) | |
10773 | *freeCursor++ = ptr; | |
10774 | else | |
10775 | replenishAndFreeLater(ptr); | |
10776 | } | |
10777 | }; | |
10778 | struct GCChunkHasher { | |
10779 | typedef gc::Chunk *Lookup; | |
10780 | static HashNumber hash(gc::Chunk *chunk) { | |
10781 | ((void) 0); | |
10782 | return HashNumber(jsuword(chunk) >> GC_CHUNK_SHIFT); | |
10783 | } | |
10784 | static bool match(gc::Chunk *k, gc::Chunk *l) { | |
10785 | ((void) 0); | |
10786 | ((void) 0); | |
10787 | return k == l; | |
10788 | } | |
10789 | }; | |
10790 | typedef HashSet<js::gc::Chunk *, GCChunkHasher, SystemAllocPolicy> GCChunkSet; | |
10791 | struct ConservativeGCThreadData { | |
10792 | jsuword *nativeStackTop; | |
10793 | union { | |
10794 | jmp_buf jmpbuf; | |
10795 | jsuword words[(((sizeof(jmp_buf))+(sizeof(jsuword))-1)/(sizeof(jsuword)))]; | |
10796 | } registerSnapshot; | |
10797 | unsigned requestThreshold; | |
10798 | __attribute__((noinline)) void recordStackTop(); | |
10799 | void updateForRequestEnd(unsigned suspendCount) { | |
10800 | if (suspendCount) | |
10801 | recordStackTop(); | |
10802 | else | |
10803 | nativeStackTop = __null; | |
10804 | } | |
10805 | bool hasStackToScan() const { | |
10806 | return !!nativeStackTop; | |
10807 | } | |
10808 | }; | |
10809 | struct GCMarker : public JSTracer { | |
10810 | private: | |
10811 | uint32 color; | |
10812 | public: | |
10813 | jsuword stackLimit; | |
10814 | js::gc::Arena<js::gc::Cell> *unmarkedArenaStackTop; | |
10815 | public: | |
10816 | explicit GCMarker(JSContext *cx); | |
10817 | ~GCMarker(); | |
10818 | uint32 getMarkColor() const { | |
10819 | return color; | |
10820 | } | |
10821 | void setMarkColor(uint32 newColor) { | |
10822 | markDelayedChildren(); | |
10823 | color = newColor; | |
10824 | } | |
10825 | void delayMarkingChildren(void *thing); | |
10826 | __attribute__((visibility ("default"))) void markDelayedChildren(); | |
10827 | }; | |
10828 | void | |
10829 | MarkStackRangeConservatively(JSTracer *trc, Value *begin, Value *end); | |
10830 | } | |
10831 | extern void | |
10832 | js_FinalizeStringRT(JSRuntime *rt, JSString *str); | |
10833 | extern void | |
10834 | js_MarkTraps(JSTracer *trc); | |
10835 | namespace js { | |
10836 | namespace gc { | |
10837 | extern | |
10838 | bool | |
10839 | SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto); | |
10840 | JSCompartment * | |
10841 | NewCompartment(JSContext *cx, JSPrincipals *principals); | |
10842 | } | |
10843 | } | |
10844 | inline JSCompartment * | |
10845 | JSObject::getCompartment() const | |
10846 | { | |
10847 | return compartment(); | |
10848 | } | |
10849 | struct JSFrameRegs | |
10850 | { | |
10851 | ||
10852 | js::Value *sp; | |
10853 | jsbytecode *pc; | |
10854 | JSStackFrame *fp; | |
10855 | }; | |
10856 | enum JSInterpMode | |
10857 | { | |
10858 | JSINTERP_NORMAL = 0, | |
10859 | JSINTERP_RECORD = 1, | |
10860 | JSINTERP_SAFEPOINT = 2, | |
10861 | JSINTERP_PROFILE = 3 | |
10862 | }; | |
10863 | enum JSFrameFlags | |
10864 | { | |
10865 | JSFRAME_GLOBAL = 0x1, | |
10866 | JSFRAME_FUNCTION = 0x2, | |
10867 | JSFRAME_DUMMY = 0x4, | |
10868 | JSFRAME_EVAL = 0x8, | |
10869 | JSFRAME_DEBUGGER = 0x10, | |
10870 | JSFRAME_GENERATOR = 0x20, | |
10871 | JSFRAME_FLOATING_GENERATOR = 0x40, | |
10872 | JSFRAME_CONSTRUCTING = 0x80, | |
10873 | JSFRAME_ASSIGNING = 0x100, | |
10874 | JSFRAME_YIELDING = 0x200, | |
10875 | JSFRAME_FINISHED_IN_INTERPRETER = 0x400, | |
10876 | JSFRAME_OVERRIDE_ARGS = 0x1000, | |
10877 | JSFRAME_OVERFLOW_ARGS = 0x2000, | |
10878 | JSFRAME_UNDERFLOW_ARGS = 0x4000, | |
10879 | JSFRAME_HAS_IMACRO_PC = 0x8000, | |
10880 | JSFRAME_HAS_CALL_OBJ = 0x10000, | |
10881 | JSFRAME_HAS_ARGS_OBJ = 0x20000, | |
10882 | JSFRAME_HAS_HOOK_DATA = 0x40000, | |
10883 | JSFRAME_HAS_ANNOTATION = 0x80000, | |
10884 | JSFRAME_HAS_RVAL = 0x100000, | |
10885 | JSFRAME_HAS_SCOPECHAIN = 0x200000, | |
10886 | JSFRAME_HAS_PREVPC = 0x400000 | |
10887 | }; | |
10888 | namespace js { namespace mjit { struct JITScript; } } | |
10889 | struct JSStackFrame | |
10890 | { | |
10891 | private: | |
10892 | mutable uint32 flags_; | |
10893 | union { | |
10894 | JSScript *script; | |
10895 | JSFunction *fun; | |
10896 | } exec; | |
10897 | union { | |
10898 | uintN nactual; | |
10899 | JSObject *obj; | |
10900 | JSScript *script; | |
10901 | } args; | |
10902 | mutable JSObject *scopeChain_; | |
10903 | JSStackFrame *prev_; | |
10904 | void *ncode_; | |
10905 | js::Value rval_; | |
10906 | jsbytecode *prevpc_; | |
10907 | jsbytecode *imacropc_; | |
10908 | void *hookData_; | |
10909 | void *annotation_; | |
10910 | friend class js::StackSpace; | |
10911 | friend class js::FrameRegsIter; | |
10912 | friend struct JSContext; | |
10913 | inline void initPrev(JSContext *cx); | |
10914 | public: | |
10915 | bool isFunctionFrame() const { | |
10916 | return !!(flags_ & JSFRAME_FUNCTION); | |
10917 | } | |
10918 | bool isGlobalFrame() const { | |
10919 | return !!(flags_ & JSFRAME_GLOBAL); | |
10920 | } | |
10921 | bool isDummyFrame() const { | |
10922 | return !!(flags_ & JSFRAME_DUMMY); | |
10923 | } | |
10924 | bool isScriptFrame() const { | |
10925 | return !!(flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL)); | |
10926 | } | |
10927 | bool isEvalFrame() const { | |
10928 | ((void) 0); | |
10929 | return flags_ & JSFRAME_EVAL; | |
10930 | } | |
10931 | bool isExecuteFrame() const { | |
10932 | return !!(flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL)); | |
10933 | } | |
10934 | inline void initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun, | |
10935 | uint32 nactual, uint32 flags); | |
10936 | inline void resetInvokeCallFrame(); | |
10937 | inline void initCallFrameCallerHalf(JSContext *cx, uint32 flags, void *ncode); | |
10938 | inline void initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual); | |
10939 | inline void initCallFrameLatePrologue(); | |
10940 | inline void initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev, | |
10941 | uint32 flags); | |
10942 | inline void initGlobalFrame(JSScript *script, JSObject &chain, uint32 flags); | |
10943 | inline void stealFrameAndSlots(js::Value *vp, JSStackFrame *otherfp, | |
10944 | js::Value *othervp, js::Value *othersp); | |
10945 | inline void initDummyFrame(JSContext *cx, JSObject &chain); | |
10946 | JSStackFrame *prev() const { | |
10947 | return prev_; | |
10948 | } | |
10949 | inline void resetGeneratorPrev(JSContext *cx); | |
10950 | js::Value *slots() const { | |
10951 | return (js::Value *)(this + 1); | |
10952 | } | |
10953 | js::Value *base() const { | |
10954 | return slots() + script()->nfixed; | |
10955 | } | |
10956 | js::Value &varSlot(uintN i) { | |
10957 | ((void) 0); | |
10958 | ((void) 0); | |
10959 | return slots()[i]; | |
10960 | } | |
10961 | jsbytecode *pc(JSContext *cx, JSStackFrame *next = __null); | |
10962 | jsbytecode *prevpc() { | |
10963 | ((void) 0); | |
10964 | return prevpc_; | |
10965 | } | |
10966 | JSScript *script() const { | |
10967 | ((void) 0); | |
10968 | return isFunctionFrame() | |
10969 | ? isEvalFrame() ? args.script : fun()->script() | |
10970 | : exec.script; | |
10971 | } | |
10972 | JSScript *functionScript() const { | |
10973 | ((void) 0); | |
10974 | return isEvalFrame() ? args.script : fun()->script(); | |
10975 | } | |
10976 | JSScript *globalScript() const { | |
10977 | ((void) 0); | |
10978 | return exec.script; | |
10979 | } | |
10980 | JSScript *maybeScript() const { | |
10981 | return isScriptFrame() ? script() : __null; | |
10982 | } | |
10983 | size_t numFixed() const { | |
10984 | return script()->nfixed; | |
10985 | } | |
10986 | size_t numSlots() const { | |
10987 | return script()->nslots; | |
10988 | } | |
10989 | size_t numGlobalVars() const { | |
10990 | ((void) 0); | |
10991 | return exec.script->nfixed; | |
10992 | } | |
10993 | JSFunction* fun() const { | |
10994 | ((void) 0); | |
10995 | return exec.fun; | |
10996 | } | |
10997 | JSFunction* maybeFun() const { | |
10998 | return isFunctionFrame() ? fun() : __null; | |
10999 | } | |
11000 | bool hasArgs() const { | |
11001 | return isFunctionFrame() && !isEvalFrame(); | |
11002 | } | |
11003 | uintN numFormalArgs() const { | |
11004 | ((void) 0); | |
11005 | return fun()->nargs; | |
11006 | } | |
11007 | js::Value &formalArg(uintN i) const { | |
11008 | ((void) 0); | |
11009 | return formalArgs()[i]; | |
11010 | } | |
11011 | js::Value *formalArgs() const { | |
11012 | ((void) 0); | |
11013 | return (js::Value *)this - numFormalArgs(); | |
11014 | } | |
11015 | js::Value *formalArgsEnd() const { | |
11016 | ((void) 0); | |
11017 | return (js::Value *)this; | |
11018 | } | |
11019 | js::Value *maybeFormalArgs() const { | |
11020 | return (flags_ & (JSFRAME_FUNCTION | JSFRAME_EVAL)) == JSFRAME_FUNCTION | |
11021 | ? formalArgs() | |
11022 | : __null; | |
11023 | } | |
11024 | inline uintN numActualArgs() const; | |
11025 | inline js::Value *actualArgs() const; | |
11026 | inline js::Value *actualArgsEnd() const; | |
11027 | inline js::Value &canonicalActualArg(uintN i) const; | |
11028 | template <class Op> inline void forEachCanonicalActualArg(Op op); | |
11029 | template <class Op> inline void forEachFormalArg(Op op); | |
11030 | inline void clearMissingArgs(); | |
11031 | bool hasArgsObj() const { | |
11032 | return !!(flags_ & JSFRAME_HAS_ARGS_OBJ); | |
11033 | } | |
11034 | JSObject &argsObj() const { | |
11035 | ((void) 0); | |
11036 | ((void) 0); | |
11037 | return *args.obj; | |
11038 | } | |
11039 | JSObject *maybeArgsObj() const { | |
11040 | return hasArgsObj() ? &argsObj() : __null; | |
11041 | } | |
11042 | inline void setArgsObj(JSObject &obj); | |
11043 | inline void clearArgsObj(); | |
11044 | js::Value &functionThis() const { | |
11045 | ((void) 0); | |
11046 | if (isEvalFrame()) | |
11047 | return ((js::Value *)this)[-1]; | |
11048 | return formalArgs()[-1]; | |
11049 | } | |
11050 | JSObject &constructorThis() const { | |
11051 | ((void) 0); | |
11052 | return formalArgs()[-1].toObject(); | |
11053 | } | |
11054 | js::Value &globalThis() const { | |
11055 | ((void) 0); | |
11056 | return ((js::Value *)this)[-1]; | |
11057 | } | |
11058 | js::Value &thisValue() const { | |
11059 | if (flags_ & (JSFRAME_EVAL | JSFRAME_GLOBAL)) | |
11060 | return ((js::Value *)this)[-1]; | |
11061 | return formalArgs()[-1]; | |
11062 | } | |
11063 | inline bool computeThis(JSContext *cx); | |
11064 | js::Value &calleeValue() const { | |
11065 | ((void) 0); | |
11066 | if (isEvalFrame()) | |
11067 | return ((js::Value *)this)[-2]; | |
11068 | return formalArgs()[-2]; | |
11069 | } | |
11070 | JSObject &callee() const { | |
11071 | ((void) 0); | |
11072 | return calleeValue().toObject(); | |
11073 | } | |
11074 | JSObject *maybeCallee() const { | |
11075 | return isFunctionFrame() ? &callee() : __null; | |
11076 | } | |
11077 | bool getValidCalleeObject(JSContext *cx, js::Value *vp); | |
11078 | JSObject &scopeChain() const { | |
11079 | ((void) 0); | |
11080 | if (!(flags_ & JSFRAME_HAS_SCOPECHAIN)) { | |
11081 | scopeChain_ = callee().getParent(); | |
11082 | flags_ |= JSFRAME_HAS_SCOPECHAIN; | |
11083 | } | |
11084 | return *scopeChain_; | |
11085 | } | |
11086 | bool hasCallObj() const { | |
11087 | return !!(flags_ & JSFRAME_HAS_CALL_OBJ); | |
11088 | } | |
11089 | inline JSObject &callObj() const; | |
11090 | inline JSObject *maybeCallObj() const; | |
11091 | inline void setScopeChainNoCallObj(JSObject &obj); | |
11092 | inline void setScopeChainAndCallObj(JSObject &obj); | |
11093 | inline void clearCallObj(); | |
11094 | bool hasImacropc() const { | |
11095 | return flags_ & JSFRAME_HAS_IMACRO_PC; | |
11096 | } | |
11097 | jsbytecode *imacropc() const { | |
11098 | ((void) 0); | |
11099 | return imacropc_; | |
11100 | } | |
11101 | jsbytecode *maybeImacropc() const { | |
11102 | return hasImacropc() ? imacropc() : __null; | |
11103 | } | |
11104 | void clearImacropc() { | |
11105 | flags_ &= ~JSFRAME_HAS_IMACRO_PC; | |
11106 | } | |
11107 | void setImacropc(jsbytecode *pc) { | |
11108 | ((void) 0); | |
11109 | ((void) 0); | |
11110 | imacropc_ = pc; | |
11111 | flags_ |= JSFRAME_HAS_IMACRO_PC; | |
11112 | } | |
11113 | void* annotation() const { | |
11114 | return (flags_ & JSFRAME_HAS_ANNOTATION) ? annotation_ : __null; | |
11115 | } | |
11116 | void setAnnotation(void *annot) { | |
11117 | flags_ |= JSFRAME_HAS_ANNOTATION; | |
11118 | annotation_ = annot; | |
11119 | } | |
11120 | bool hasHookData() const { | |
11121 | return !!(flags_ & JSFRAME_HAS_HOOK_DATA); | |
11122 | } | |
11123 | void* hookData() const { | |
11124 | ((void) 0); | |
11125 | return hookData_; | |
11126 | } | |
11127 | void* maybeHookData() const { | |
11128 | return hasHookData() ? hookData_ : __null; | |
11129 | } | |
11130 | void setHookData(void *v) { | |
11131 | hookData_ = v; | |
11132 | flags_ |= JSFRAME_HAS_HOOK_DATA; | |
11133 | } | |
11134 | const js::Value &returnValue() { | |
11135 | if (!(flags_ & JSFRAME_HAS_RVAL)) | |
11136 | rval_.setUndefined(); | |
11137 | return rval_; | |
11138 | } | |
11139 | void markReturnValue() { | |
11140 | flags_ |= JSFRAME_HAS_RVAL; | |
11141 | } | |
11142 | void setReturnValue(const js::Value &v) { | |
11143 | rval_ = v; | |
11144 | markReturnValue(); | |
11145 | } | |
11146 | void clearReturnValue() { | |
11147 | rval_.setUndefined(); | |
11148 | markReturnValue(); | |
11149 | } | |
11150 | void *nativeReturnAddress() const { | |
11151 | return ncode_; | |
11152 | } | |
11153 | void setNativeReturnAddress(void *addr) { | |
11154 | ncode_ = addr; | |
11155 | } | |
11156 | void **addressOfNativeReturnAddress() { | |
11157 | return &ncode_; | |
11158 | } | |
11159 | bool isGeneratorFrame() const { | |
11160 | return !!(flags_ & JSFRAME_GENERATOR); | |
11161 | } | |
11162 | bool isFloatingGenerator() const { | |
11163 | ((void) 0); | |
11164 | return !!(flags_ & JSFRAME_FLOATING_GENERATOR); | |
11165 | } | |
11166 | void initFloatingGenerator() { | |
11167 | ((void) 0); | |
11168 | flags_ |= (JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR); | |
11169 | } | |
11170 | void unsetFloatingGenerator() { | |
11171 | flags_ &= ~JSFRAME_FLOATING_GENERATOR; | |
11172 | } | |
11173 | void setFloatingGenerator() { | |
11174 | flags_ |= JSFRAME_FLOATING_GENERATOR; | |
11175 | } | |
11176 | bool isConstructing() const { | |
11177 | return !!(flags_ & JSFRAME_CONSTRUCTING); | |
11178 | } | |
11179 | uint32 isConstructingFlag() const { | |
11180 | ((void) 0); | |
11181 | ((void) 0); | |
11182 | return flags_; | |
11183 | } | |
11184 | bool isDebuggerFrame() const { | |
11185 | return !!(flags_ & JSFRAME_DEBUGGER); | |
11186 | } | |
11187 | bool isEvalOrDebuggerFrame() const { | |
11188 | return !!(flags_ & (JSFRAME_EVAL | JSFRAME_DEBUGGER)); | |
11189 | } | |
11190 | bool hasOverriddenArgs() const { | |
11191 | return !!(flags_ & JSFRAME_OVERRIDE_ARGS); | |
11192 | } | |
11193 | bool hasOverflowArgs() const { | |
11194 | return !!(flags_ & JSFRAME_OVERFLOW_ARGS); | |
11195 | } | |
11196 | void setOverriddenArgs() { | |
11197 | flags_ |= JSFRAME_OVERRIDE_ARGS; | |
11198 | } | |
11199 | bool isAssigning() const { | |
11200 | return !!(flags_ & JSFRAME_ASSIGNING); | |
11201 | } | |
11202 | void setAssigning() { | |
11203 | flags_ |= JSFRAME_ASSIGNING; | |
11204 | } | |
11205 | void clearAssigning() { | |
11206 | flags_ &= ~JSFRAME_ASSIGNING; | |
11207 | } | |
11208 | bool isYielding() { | |
11209 | return !!(flags_ & JSFRAME_YIELDING); | |
11210 | } | |
11211 | void setYielding() { | |
11212 | flags_ |= JSFRAME_YIELDING; | |
11213 | } | |
11214 | void clearYielding() { | |
11215 | flags_ &= ~JSFRAME_YIELDING; | |
11216 | } | |
11217 | void setFinishedInInterpreter() { | |
11218 | flags_ |= JSFRAME_FINISHED_IN_INTERPRETER; | |
11219 | } | |
11220 | bool finishedInInterpreter() const { | |
11221 | return !!(flags_ & JSFRAME_FINISHED_IN_INTERPRETER); | |
11222 | } | |
11223 | inline JSObject &varobj(js::StackSegment *seg) const; | |
11224 | inline JSObject &varobj(JSContext *cx) const; | |
11225 | static size_t offsetOfFlags() { | |
11226 | return __builtin_offsetof (JSStackFrame, flags_); | |
11227 | } | |
11228 | static size_t offsetOfExec() { | |
11229 | return __builtin_offsetof (JSStackFrame, exec); | |
11230 | } | |
11231 | void *addressOfArgs() { | |
11232 | return &args; | |
11233 | } | |
11234 | static size_t offsetOfScopeChain() { | |
11235 | return __builtin_offsetof (JSStackFrame, scopeChain_); | |
11236 | } | |
11237 | JSObject **addressOfScopeChain() { | |
11238 | ((void) 0); | |
11239 | return &scopeChain_; | |
11240 | } | |
11241 | static size_t offsetOfPrev() { | |
11242 | return __builtin_offsetof (JSStackFrame, prev_); | |
11243 | } | |
11244 | static size_t offsetOfReturnValue() { | |
11245 | return __builtin_offsetof (JSStackFrame, rval_); | |
11246 | } | |
11247 | static ptrdiff_t offsetOfncode() { | |
11248 | return __builtin_offsetof (JSStackFrame, ncode_); | |
11249 | } | |
11250 | static ptrdiff_t offsetOfCallee(JSFunction *fun) { | |
11251 | ((void) 0); | |
11252 | return -(fun->nargs + 2) * sizeof(js::Value); | |
11253 | } | |
11254 | static ptrdiff_t offsetOfThis(JSFunction *fun) { | |
11255 | return fun == __null | |
11256 | ? -1 * ptrdiff_t(sizeof(js::Value)) | |
11257 | : -(fun->nargs + 1) * ptrdiff_t(sizeof(js::Value)); | |
11258 | } | |
11259 | static ptrdiff_t offsetOfFormalArg(JSFunction *fun, uintN i) { | |
11260 | ((void) 0); | |
11261 | return (-(int)fun->nargs + i) * sizeof(js::Value); | |
11262 | } | |
11263 | static size_t offsetOfFixed(uintN i) { | |
11264 | return sizeof(JSStackFrame) + i * sizeof(js::Value); | |
11265 | } | |
11266 | void staticAsserts() { | |
11267 | typedef int js_static_assert61[(__builtin_offsetof (JSStackFrame, rval_) % sizeof(js::Value) == 0) ? 1 : -1]; | |
11268 | typedef int js_static_assert62[(sizeof(JSStackFrame) % sizeof(js::Value) == 0) ? 1 : -1]; | |
11269 | } | |
11270 | void methodjitStaticAsserts(); | |
11271 | }; | |
11272 | namespace js { | |
11273 | static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(Value); | |
11274 | extern JSObject * | |
11275 | GetBlockChain(JSContext *cx, JSStackFrame *fp); | |
11276 | extern JSObject * | |
11277 | GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen); | |
11278 | extern JSObject * | |
11279 | GetScopeChain(JSContext *cx); | |
11280 | extern JSObject * | |
11281 | GetScopeChain(JSContext *cx, JSStackFrame *fp); | |
11282 | extern JSObject * | |
11283 | GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen); | |
11284 | void | |
11285 | ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp); | |
11286 | template <typename T> | |
11287 | bool GetPrimitiveThis(JSContext *cx, Value *vp, T *v); | |
11288 | inline void | |
11289 | PutActivationObjects(JSContext *cx, JSStackFrame *fp); | |
11290 | inline void | |
11291 | PutOwnedActivationObjects(JSContext *cx, JSStackFrame *fp); | |
11292 | extern | |
11293 | bool | |
11294 | BoxThisForVp(JSContext *cx, js::Value *vp); | |
11295 | struct CallArgs | |
11296 | { | |
11297 | Value *argv_; | |
11298 | uintN argc_; | |
11299 | protected: | |
11300 | CallArgs() {} | |
11301 | CallArgs(Value *argv, uintN argc) : argv_(argv), argc_(argc) {} | |
11302 | public: | |
11303 | Value *base() const { return argv_ - 2; } | |
11304 | Value &callee() const { return argv_[-2]; } | |
11305 | Value &thisv() const { return argv_[-1]; } | |
11306 | Value &operator[](unsigned i) const { ((void) 0); return argv_[i]; } | |
11307 | Value *argv() const { return argv_; } | |
11308 | uintN argc() const { return argc_; } | |
11309 | Value &rval() const { return argv_[-2]; } | |
11310 | }; | |
11311 | extern | |
11312 | bool | |
11313 | Invoke(JSContext *cx, const CallArgs &args, uint32 flags); | |
11314 | class InvokeSessionGuard; | |
11315 | extern | |
11316 | bool | |
11317 | ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, | |
11318 | uintN argc, Value *argv, Value *rval); | |
11319 | extern | |
11320 | bool | |
11321 | ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, | |
11322 | JSAccessMode mode, uintN argc, Value *argv, Value *rval); | |
11323 | extern | |
11324 | bool | |
11325 | InvokeConstructor(JSContext *cx, const CallArgs &args); | |
11326 | extern | |
11327 | bool | |
11328 | InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval, | |
11329 | uintN argc, Value *argv, Value *rval); | |
11330 | extern | |
11331 | bool | |
11332 | ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, | |
11333 | Value *rval); | |
11334 | extern | |
11335 | bool | |
11336 | DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp); | |
11337 | extern | |
11338 | bool | |
11339 | DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp); | |
11340 | extern | |
11341 | bool | |
11342 | Execute(JSContext *cx, JSObject *chain, JSScript *script, | |
11343 | JSStackFrame *prev, uintN flags, Value *result); | |
11344 | extern __attribute__((noinline)) | |
11345 | bool | |
11346 | Interpret(JSContext *cx, JSStackFrame *stopFp, uintN inlineCallCount = 0, JSInterpMode mode = JSINTERP_NORMAL); | |
11347 | extern | |
11348 | bool | |
11349 | RunScript(JSContext *cx, JSScript *script, JSStackFrame *fp); | |
11350 | extern | |
11351 | bool | |
11352 | CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs); | |
11353 | extern | |
11354 | bool | |
11355 | StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *equal); | |
11356 | extern | |
11357 | bool | |
11358 | SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same); | |
11359 | extern JSType | |
11360 | TypeOfValue(JSContext *cx, const Value &v); | |
11361 | inline | |
11362 | bool | |
11363 | InstanceOf(JSContext *cx, JSObject *obj, Class *clasp, Value *argv) | |
11364 | { | |
11365 | if (obj && obj->getClass() == clasp) | |
11366 | return true; | |
11367 | extern bool InstanceOfSlow(JSContext *, JSObject *, Class *, Value *); | |
11368 | return InstanceOfSlow(cx, obj, clasp, argv); | |
11369 | } | |
11370 | extern JSBool | |
11371 | HasInstance(JSContext *cx, JSObject *obj, const js::Value *v, JSBool *bp); | |
11372 | inline void * | |
11373 | GetInstancePrivate(JSContext *cx, JSObject *obj, Class *clasp, Value *argv) | |
11374 | { | |
11375 | if (!InstanceOf(cx, obj, clasp, argv)) | |
11376 | return __null; | |
11377 | return obj->getPrivate(); | |
11378 | } | |
11379 | extern | |
11380 | bool | |
11381 | ValueToId(JSContext *cx, const Value &v, jsid *idp); | |
11382 | extern const js::Value & | |
11383 | GetUpvar(JSContext *cx, uintN level, js::UpvarCookie cookie); | |
11384 | } | |
11385 | extern JSBool | |
11386 | js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen); | |
11387 | extern void | |
11388 | js_LeaveWith(JSContext *cx); | |
11389 | extern JSBool | |
11390 | js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2); | |
11391 | extern void | |
11392 | js_LogOpcode(JSContext *cx); | |
11393 | extern void | |
11394 | js_MeterOpcodePair(JSOp op1, JSOp op2); | |
11395 | extern void | |
11396 | js_MeterSlotOpcode(JSOp op, uint32 slot); | |
11397 | extern JSBool | |
11398 | js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind); | |
11399 | extern JSBool | |
11400 | js_OnUnknownMethod(JSContext *cx, js::Value *vp); | |
11401 | extern js::Class * | |
11402 | js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth); | |
11403 | namespace js { | |
11404 | typedef double (*UnaryFunType)(double); | |
11405 | class MathCache | |
11406 | { | |
11407 | static const unsigned SizeLog2 = 12; | |
11408 | static const unsigned Size = 1 << SizeLog2; | |
11409 | struct Entry { double in; UnaryFunType f; double out; }; | |
11410 | Entry table[Size]; | |
11411 | public: | |
11412 | MathCache(); | |
11413 | uintN hash(double x) { | |
11414 | union { double d; struct { uint32 one, two; } s; } u = { x }; | |
11415 | uint32 hash32 = u.s.one ^ u.s.two; | |
11416 | uint16 hash16 = (uint16)(hash32 ^ (hash32 >> 16)); | |
11417 | return (hash16 & (Size - 1)) ^ (hash16 >> (16 - SizeLog2)); | |
11418 | } | |
11419 | double lookup(UnaryFunType f, double x) { | |
11420 | uintN index = hash(x); | |
11421 | Entry &e = table[index]; | |
11422 | if (e.in == x && e.f == f) | |
11423 | return e.out; | |
11424 | e.in = x; | |
11425 | e.f = f; | |
11426 | return (e.out = f(x)); | |
11427 | } | |
11428 | }; | |
11429 | } | |
11430 | extern js::Class js_MathClass; | |
11431 | extern JSObject * | |
11432 | js_InitMathClass(JSContext *cx, JSObject *obj); | |
11433 | extern | |
11434 | bool | |
11435 | js_IsMathFunction(JSNative native); | |
11436 | extern void | |
11437 | js_InitRandom(JSContext *cx); | |
11438 | extern JSBool | |
11439 | js_math_abs(JSContext *cx, uintN argc, js::Value *vp); | |
11440 | extern JSBool | |
11441 | js_math_ceil(JSContext *cx, uintN argc, js::Value *vp); | |
11442 | extern JSBool | |
11443 | js_math_floor(JSContext *cx, uintN argc, js::Value *vp); | |
11444 | extern JSBool | |
11445 | js_math_max(JSContext *cx, uintN argc, js::Value *vp); | |
11446 | extern JSBool | |
11447 | js_math_min(JSContext *cx, uintN argc, js::Value *vp); | |
11448 | extern JSBool | |
11449 | js_math_round(JSContext *cx, uintN argc, js::Value *vp); | |
11450 | extern jsdouble | |
11451 | js_math_ceil_impl(jsdouble x); | |
11452 | extern jsdouble | |
11453 | js_math_floor_impl(jsdouble x); | |
11454 | extern jsdouble | |
11455 | js_math_round_impl(jsdouble x); | |
11456 | namespace js { | |
11457 | enum { | |
11458 | PCVCAP_PROTOBITS = 4, | |
11459 | PCVCAP_PROTOSIZE = ((JSUint32)1 << (PCVCAP_PROTOBITS)), | |
11460 | PCVCAP_PROTOMASK = (((JSUint32)1 << (PCVCAP_PROTOBITS)) - 1), | |
11461 | PCVCAP_SCOPEBITS = 4, | |
11462 | PCVCAP_SCOPESIZE = ((JSUint32)1 << (PCVCAP_SCOPEBITS)), | |
11463 | PCVCAP_SCOPEMASK = (((JSUint32)1 << (PCVCAP_SCOPEBITS)) - 1), | |
11464 | PCVCAP_TAGBITS = PCVCAP_PROTOBITS + PCVCAP_SCOPEBITS, | |
11465 | PCVCAP_TAGMASK = (((JSUint32)1 << (PCVCAP_TAGBITS)) - 1) | |
11466 | }; | |
11467 | const uint32 SHAPE_OVERFLOW_BIT = ((JSUint32)1 << (32 - PCVCAP_TAGBITS)); | |
11468 | class PCVal | |
11469 | { | |
11470 | private: | |
11471 | enum { | |
11472 | OBJECT = 0, | |
11473 | SLOT = 1, | |
11474 | SHAPE = 2, | |
11475 | TAG = 3 | |
11476 | }; | |
11477 | jsuword v; | |
11478 | public: | |
11479 | bool isNull() const { return v == 0; } | |
11480 | void setNull() { v = 0; } | |
11481 | bool isFunObj() const { return (v & TAG) == OBJECT; } | |
11482 | JSObject &toFunObj() const { | |
11483 | ((void) 0); | |
11484 | return *reinterpret_cast<JSObject *>(v); | |
11485 | } | |
11486 | void setFunObj(JSObject &obj) { | |
11487 | v = reinterpret_cast<jsuword>(&obj); | |
11488 | } | |
11489 | bool isSlot() const { return v & SLOT; } | |
11490 | uint32 toSlot() const { ((void) 0); return uint32(v) >> 1; } | |
11491 | void setSlot(uint32 slot) { v = (jsuword(slot) << 1) | SLOT; } | |
11492 | bool isShape() const { return (v & TAG) == SHAPE; } | |
11493 | const js::Shape *toShape() const { | |
11494 | ((void) 0); | |
11495 | return reinterpret_cast<js::Shape *>(v & ~TAG); | |
11496 | } | |
11497 | void setShape(const js::Shape *shape) { | |
11498 | ((void) 0); | |
11499 | v = reinterpret_cast<jsuword>(shape) | SHAPE; | |
11500 | } | |
11501 | }; | |
11502 | struct PropertyCacheEntry | |
11503 | { | |
11504 | jsbytecode *kpc; | |
11505 | jsuword kshape; | |
11506 | jsuword vcap; | |
11507 | PCVal vword; | |
11508 | bool adding() const { return vcapTag() == 0 && kshape != vshape(); } | |
11509 | bool directHit() const { return vcapTag() == 0 && kshape == vshape(); } | |
11510 | jsuword vcapTag() const { return vcap & PCVCAP_TAGMASK; } | |
11511 | uint32 vshape() const { return uint32(vcap >> PCVCAP_TAGBITS); } | |
11512 | jsuword scopeIndex() const { return (vcap >> PCVCAP_PROTOBITS) & PCVCAP_SCOPEMASK; } | |
11513 | jsuword protoIndex() const { return vcap & PCVCAP_PROTOMASK; } | |
11514 | void assign(jsbytecode *kpc, jsuword kshape, jsuword vshape, | |
11515 | uintN scopeIndex, uintN protoIndex, PCVal vword) { | |
11516 | ((void) 0); | |
11517 | ((void) 0); | |
11518 | ((void) 0); | |
11519 | ((void) 0); | |
11520 | this->kpc = kpc; | |
11521 | this->kshape = kshape; | |
11522 | this->vcap = (vshape << PCVCAP_TAGBITS) | (scopeIndex << PCVCAP_PROTOBITS) | protoIndex; | |
11523 | this->vword = vword; | |
11524 | } | |
11525 | }; | |
11526 | class PropertyCache | |
11527 | { | |
11528 | private: | |
11529 | enum { | |
11530 | SIZE_LOG2 = 12, | |
11531 | SIZE = ((JSUint32)1 << (SIZE_LOG2)), | |
11532 | MASK = (((JSUint32)1 << (SIZE_LOG2)) - 1) | |
11533 | }; | |
11534 | PropertyCacheEntry table[SIZE]; | |
11535 | JSBool empty; | |
11536 | static inline jsuword | |
11537 | hash(jsbytecode *pc, jsuword kshape) | |
11538 | { | |
11539 | return ((((jsuword(pc) >> SIZE_LOG2) ^ jsuword(pc)) + kshape) & MASK); | |
11540 | } | |
11541 | static inline bool matchShape(JSContext *cx, JSObject *obj, uint32 shape); | |
11542 | JSAtom *fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, | |
11543 | JSObject **pobjp, PropertyCacheEntry *entry); | |
11544 | inline void assertEmpty() {} | |
11545 | public: | |
11546 | __attribute__((always_inline)) inline void test(JSContext *cx, jsbytecode *pc, | |
11547 | JSObject *&obj, JSObject *&pobj, | |
11548 | PropertyCacheEntry *&entry, JSAtom *&atom); | |
11549 | __attribute__((always_inline)) inline bool testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj, | |
11550 | PropertyCacheEntry **entryp, JSObject **obj2p, | |
11551 | JSAtom **atomp); | |
11552 | __attribute__((always_inline)) inline bool testForInit(JSRuntime *rt, jsbytecode *pc, JSObject *obj, | |
11553 | const js::Shape **shapep, PropertyCacheEntry **entryp); | |
11554 | PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, uintN scopeIndex, | |
11555 | uintN protoIndex, JSObject *pobj, | |
11556 | const js::Shape *shape, JSBool adding = false); | |
11557 | void purge(JSContext *cx); | |
11558 | void purgeForScript(JSContext *cx, JSScript *script); | |
11559 | }; | |
11560 | } | |
11561 | namespace js { | |
11562 | struct ShapeHasher { | |
11563 | typedef js::Shape *Key; | |
11564 | typedef const js::Shape *Lookup; | |
11565 | static inline HashNumber hash(const Lookup l); | |
11566 | static inline bool match(Key k, Lookup l); | |
11567 | }; | |
11568 | typedef HashSet<js::Shape *, ShapeHasher, SystemAllocPolicy> KidsHash; | |
11569 | class KidsPointer { | |
11570 | private: | |
11571 | enum { | |
11572 | SHAPE = 0, | |
11573 | HASH = 1, | |
11574 | TAG = 1 | |
11575 | }; | |
11576 | jsuword w; | |
11577 | public: | |
11578 | bool isNull() const { return !w; } | |
11579 | void setNull() { w = 0; } | |
11580 | bool isShape() const { return (w & TAG) == SHAPE && !isNull(); } | |
11581 | js::Shape *toShape() const { | |
11582 | ((void) 0); | |
11583 | return reinterpret_cast<js::Shape *>(w & ~jsuword(TAG)); | |
11584 | } | |
11585 | void setShape(js::Shape *shape) { | |
11586 | ((void) 0); | |
11587 | ((void) 0); | |
11588 | w = reinterpret_cast<jsuword>(shape) | SHAPE; | |
11589 | } | |
11590 | bool isHash() const { return (w & TAG) == HASH; } | |
11591 | KidsHash *toHash() const { | |
11592 | ((void) 0); | |
11593 | return reinterpret_cast<KidsHash *>(w & ~jsuword(TAG)); | |
11594 | } | |
11595 | void setHash(KidsHash *hash) { | |
11596 | ((void) 0); | |
11597 | ((void) 0); | |
11598 | w = reinterpret_cast<jsuword>(hash) | HASH; | |
11599 | } | |
11600 | }; | |
11601 | class PropertyTree | |
11602 | { | |
11603 | friend struct ::JSFunction; | |
11604 | JSCompartment *compartment; | |
11605 | JSArenaPool arenaPool; | |
11606 | js::Shape *freeList; | |
11607 | bool insertChild(JSContext *cx, js::Shape *parent, js::Shape *child); | |
11608 | void removeChild(js::Shape *child); | |
11609 | PropertyTree(); | |
11610 | public: | |
11611 | enum { MAX_HEIGHT = 128 }; | |
11612 | PropertyTree(JSCompartment *comp) | |
11613 | : compartment(comp), freeList(__null) | |
11614 | { | |
11615 | PodZero(&arenaPool); | |
11616 | } | |
11617 | bool init(); | |
11618 | void finish(); | |
11619 | js::Shape *newShapeUnchecked(); | |
11620 | js::Shape *newShape(JSContext *cx); | |
11621 | js::Shape *getChild(JSContext *cx, js::Shape *parent, const js::Shape &child); | |
11622 | void orphanChildren(js::Shape *shape); | |
11623 | void sweepShapes(JSContext *cx); | |
11624 | void unmarkShapes(JSContext *cx); | |
11625 | static void dumpShapes(JSContext *cx); | |
11626 | }; | |
11627 | } | |
11628 | extern "C" { | |
11629 | struct timex | |
11630 | { | |
11631 | unsigned int modes; | |
11632 | __syscall_slong_t offset; | |
11633 | __syscall_slong_t freq; | |
11634 | __syscall_slong_t maxerror; | |
11635 | __syscall_slong_t esterror; | |
11636 | int status; | |
11637 | __syscall_slong_t constant; | |
11638 | __syscall_slong_t precision; | |
11639 | __syscall_slong_t tolerance; | |
11640 | struct timeval time; | |
11641 | __syscall_slong_t tick; | |
11642 | __syscall_slong_t ppsfreq; | |
11643 | __syscall_slong_t jitter; | |
11644 | int shift; | |
11645 | __syscall_slong_t stabil; | |
11646 | __syscall_slong_t jitcnt; | |
11647 | __syscall_slong_t calcnt; | |
11648 | __syscall_slong_t errcnt; | |
11649 | __syscall_slong_t stbcnt; | |
11650 | int tai; | |
11651 | int :32; int :32; int :32; int :32; | |
11652 | int :32; int :32; int :32; int :32; | |
11653 | int :32; int :32; int :32; | |
11654 | }; | |
11655 | extern "C" { | |
11656 | extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) throw (); | |
11657 | } | |
11658 | struct tm | |
11659 | { | |
11660 | int tm_sec; | |
11661 | int tm_min; | |
11662 | int tm_hour; | |
11663 | int tm_mday; | |
11664 | int tm_mon; | |
11665 | int tm_year; | |
11666 | int tm_wday; | |
11667 | int tm_yday; | |
11668 | int tm_isdst; | |
11669 | long int tm_gmtoff; | |
11670 | const char *tm_zone; | |
11671 | }; | |
11672 | struct itimerspec | |
11673 | { | |
11674 | struct timespec it_interval; | |
11675 | struct timespec it_value; | |
11676 | }; | |
11677 | struct sigevent; | |
11678 | extern clock_t clock (void) throw (); | |
11679 | extern time_t time (time_t *__timer) throw (); | |
11680 | extern double difftime (time_t __time1, time_t __time0) | |
11681 | throw () __attribute__ ((__const__)); | |
11682 | extern time_t mktime (struct tm *__tp) throw (); | |
11683 | extern size_t strftime (char *__restrict __s, size_t __maxsize, | |
11684 | const char *__restrict __format, | |
11685 | const struct tm *__restrict __tp) throw (); | |
11686 | extern char *strptime (const char *__restrict __s, | |
11687 | const char *__restrict __fmt, struct tm *__tp) | |
11688 | throw (); | |
11689 | extern size_t strftime_l (char *__restrict __s, size_t __maxsize, | |
11690 | const char *__restrict __format, | |
11691 | const struct tm *__restrict __tp, | |
11692 | __locale_t __loc) throw (); | |
11693 | extern char *strptime_l (const char *__restrict __s, | |
11694 | const char *__restrict __fmt, struct tm *__tp, | |
11695 | __locale_t __loc) throw (); | |
11696 | extern struct tm *gmtime (const time_t *__timer) throw (); | |
11697 | extern struct tm *localtime (const time_t *__timer) throw (); | |
11698 | extern struct tm *gmtime_r (const time_t *__restrict __timer, | |
11699 | struct tm *__restrict __tp) throw (); | |
11700 | extern struct tm *localtime_r (const time_t *__restrict __timer, | |
11701 | struct tm *__restrict __tp) throw (); | |
11702 | extern char *asctime (const struct tm *__tp) throw (); | |
11703 | extern char *ctime (const time_t *__timer) throw (); | |
11704 | extern char *asctime_r (const struct tm *__restrict __tp, | |
11705 | char *__restrict __buf) throw (); | |
11706 | extern char *ctime_r (const time_t *__restrict __timer, | |
11707 | char *__restrict __buf) throw (); | |
11708 | extern char *__tzname[2]; | |
11709 | extern int __daylight; | |
11710 | extern long int __timezone; | |
11711 | extern char *tzname[2]; | |
11712 | extern void tzset (void) throw (); | |
11713 | extern int daylight; | |
11714 | extern long int timezone; | |
11715 | extern int stime (const time_t *__when) throw (); | |
11716 | extern time_t timegm (struct tm *__tp) throw (); | |
11717 | extern time_t timelocal (struct tm *__tp) throw (); | |
11718 | extern int dysize (int __year) throw () __attribute__ ((__const__)); | |
11719 | extern int nanosleep (const struct timespec *__requested_time, | |
11720 | struct timespec *__remaining); | |
11721 | extern int clock_getres (clockid_t __clock_id, struct timespec *__res) throw (); | |
11722 | extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) throw (); | |
11723 | extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp) | |
11724 | throw (); | |
11725 | extern int clock_nanosleep (clockid_t __clock_id, int __flags, | |
11726 | const struct timespec *__req, | |
11727 | struct timespec *__rem); | |
11728 | extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) throw (); | |
11729 | extern int timer_create (clockid_t __clock_id, | |
11730 | struct sigevent *__restrict __evp, | |
11731 | timer_t *__restrict __timerid) throw (); | |
11732 | extern int timer_delete (timer_t __timerid) throw (); | |
11733 | extern int timer_settime (timer_t __timerid, int __flags, | |
11734 | const struct itimerspec *__restrict __value, | |
11735 | struct itimerspec *__restrict __ovalue) throw (); | |
11736 | extern int timer_gettime (timer_t __timerid, struct itimerspec *__value) | |
11737 | throw (); | |
11738 | extern int timer_getoverrun (timer_t __timerid) throw (); | |
11739 | extern int timespec_get (struct timespec *__ts, int __base) | |
11740 | throw () __attribute__ ((__nonnull__ (1))); | |
11741 | extern int getdate_err; | |
11742 | extern struct tm *getdate (const char *__string); | |
11743 | extern int getdate_r (const char *__restrict __string, | |
11744 | struct tm *__restrict __resbufp); | |
11745 | } | |
11746 | struct JSContext; | |
11747 | class DSTOffsetCache { | |
11748 | public: | |
11749 | inline DSTOffsetCache(); | |
11750 | JSInt64 getDSTOffsetMilliseconds(int64 localTimeMilliseconds, JSContext *cx); | |
11751 | inline void purge(); | |
11752 | private: | |
11753 | JSInt64 computeDSTOffsetMilliseconds(int64 localTimeSeconds); | |
11754 | JSInt64 offsetMilliseconds; | |
11755 | JSInt64 rangeStartSeconds, rangeEndSeconds; | |
11756 | JSInt64 oldOffsetMilliseconds; | |
11757 | JSInt64 oldRangeStartSeconds, oldRangeEndSeconds; | |
11758 | static const JSInt64 MAX_UNIX_TIMET = 2145859200; | |
11759 | static const JSInt64 MILLISECONDS_PER_SECOND = 1000; | |
11760 | static const JSInt64 SECONDS_PER_MINUTE = 60; | |
11761 | static const JSInt64 SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE; | |
11762 | static const JSInt64 SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR; | |
11763 | static const JSInt64 RANGE_EXPANSION_AMOUNT = 30 * SECONDS_PER_DAY; | |
11764 | private: | |
11765 | void sanityCheck(); | |
11766 | void noteOffsetCalculation() { | |
11767 | ((void)0); | |
11768 | } | |
11769 | void noteCacheHit() { | |
11770 | ((void)0); | |
11771 | } | |
11772 | void noteCacheMissIncrease() { | |
11773 | ((void)0); | |
11774 | } | |
11775 | void noteCacheMissDecrease() { | |
11776 | ((void)0); | |
11777 | } | |
11778 | void noteCacheMissIncreasingOffsetChangeUpper() { | |
11779 | ((void)0); | |
11780 | } | |
11781 | void noteCacheMissIncreasingOffsetChangeExpand() { | |
11782 | ((void)0); | |
11783 | } | |
11784 | void noteCacheMissLargeIncrease() { | |
11785 | ((void)0); | |
11786 | } | |
11787 | void noteCacheMissDecreasingOffsetChangeLower() { | |
11788 | ((void)0); | |
11789 | } | |
11790 | void noteCacheMissDecreasingOffsetChangeExpand() { | |
11791 | ((void)0); | |
11792 | } | |
11793 | void noteCacheMissLargeDecrease() { | |
11794 | ((void)0); | |
11795 | } | |
11796 | }; | |
11797 | extern "C" { | |
11798 | typedef struct PRMJTime PRMJTime; | |
11799 | struct PRMJTime { | |
11800 | JSInt32 tm_usec; | |
11801 | JSInt8 tm_sec; | |
11802 | JSInt8 tm_min; | |
11803 | JSInt8 tm_hour; | |
11804 | JSInt8 tm_mday; | |
11805 | JSInt8 tm_mon; | |
11806 | JSInt8 tm_wday; | |
11807 | JSInt32 tm_year; | |
11808 | JSInt16 tm_yday; | |
11809 | JSInt8 tm_isdst; | |
11810 | }; | |
11811 | extern JSInt64 | |
11812 | PRMJ_Now(void); | |
11813 | extern JSInt32 | |
11814 | PRMJ_LocalGMTDifference(void); | |
11815 | extern size_t | |
11816 | PRMJ_FormatTime(char *buf, int buflen, const char *fmt, PRMJTime *tm); | |
11817 | } | |
11818 | typedef struct JSGSNCache { | |
11819 | jsbytecode *code; | |
11820 | JSDHashTable table; | |
11821 | } JSGSNCache; | |
11822 | extern void | |
11823 | js_PurgeGSNCache(JSGSNCache *cache); | |
11824 | namespace nanojit { | |
11825 | class Assembler; | |
11826 | class CodeAlloc; | |
11827 | class Fragment; | |
11828 | template<typename K> struct DefaultHash; | |
11829 | template<typename K, typename V, typename H> class HashMap; | |
11830 | template<typename T> class Seq; | |
11831 | } | |
11832 | namespace js { | |
11833 | static const size_t MONITOR_N_GLOBAL_STATES = 4; | |
11834 | static const size_t FRAGMENT_TABLE_SIZE = 512; | |
11835 | static const size_t MAX_NATIVE_STACK_SLOTS = 4096; | |
11836 | static const size_t MAX_CALL_STACK_ENTRIES = 500; | |
11837 | static const size_t MAX_GLOBAL_SLOTS = 4096; | |
11838 | static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1; | |
11839 | static const size_t MAX_SLOW_NATIVE_EXTRA_SLOTS = 16; | |
11840 | class VMAllocator; | |
11841 | class FrameInfoCache; | |
11842 | struct FrameInfo; | |
11843 | struct VMSideExit; | |
11844 | struct TreeFragment; | |
11845 | struct TracerState; | |
11846 | template<typename T> class Queue; | |
11847 | typedef Queue<uint16> SlotList; | |
11848 | class TypeMap; | |
11849 | class LoopProfile; | |
11850 | namespace mjit { | |
11851 | class JaegerCompartment; | |
11852 | } | |
11853 | class ContextAllocPolicy | |
11854 | { | |
11855 | JSContext *cx; | |
11856 | public: | |
11857 | ContextAllocPolicy(JSContext *cx) : cx(cx) {} | |
11858 | JSContext *context() const { return cx; } | |
11859 | void *malloc(size_t bytes); | |
11860 | void free(void *p); | |
11861 | void *realloc(void *p, size_t bytes); | |
11862 | void reportAllocOverflow() const; | |
11863 | }; | |
11864 | class StackSegment | |
11865 | { | |
11866 | JSContext *cx; | |
11867 | StackSegment *previousInContext; | |
11868 | StackSegment *previousInMemory; | |
11869 | JSStackFrame *initialFrame; | |
11870 | JSFrameRegs *suspendedRegs; | |
11871 | JSObject *initialVarObj; | |
11872 | bool saved; | |
11873 | public: | |
11874 | StackSegment() | |
11875 | : cx(__null), previousInContext(__null), previousInMemory(__null), | |
11876 | initialFrame(__null), suspendedRegs(((JSFrameRegs *)0x1)), | |
11877 | initialVarObj(__null), saved(false) | |
11878 | { | |
11879 | ((void) 0); | |
11880 | } | |
11881 | Value *valueRangeBegin() const { | |
11882 | return (Value *)(this + 1); | |
11883 | } | |
11884 | bool inContext() const { | |
11885 | ((void) 0); | |
11886 | ((void) 0); | |
11887 | return cx; | |
11888 | } | |
11889 | bool isActive() const { | |
11890 | ((void) 0); | |
11891 | ((void) 0); | |
11892 | return !suspendedRegs; | |
11893 | } | |
11894 | bool isSuspended() const { | |
11895 | ((void) 0); | |
11896 | ((void) 0); | |
11897 | return cx && suspendedRegs; | |
11898 | } | |
11899 | bool isSaved() const { | |
11900 | ((void) 0); | |
11901 | return saved; | |
11902 | } | |
11903 | void joinContext(JSContext *cx, JSStackFrame *f) { | |
11904 | ((void) 0); | |
11905 | this->cx = cx; | |
11906 | initialFrame = f; | |
11907 | suspendedRegs = __null; | |
11908 | ((void) 0); | |
11909 | } | |
11910 | void leaveContext() { | |
11911 | ((void) 0); | |
11912 | this->cx = __null; | |
11913 | initialFrame = __null; | |
11914 | suspendedRegs = ((JSFrameRegs *)0x1); | |
11915 | ((void) 0); | |
11916 | } | |
11917 | JSContext *maybeContext() const { | |
11918 | return cx; | |
11919 | } | |
11920 | void suspend(JSFrameRegs *regs) { | |
11921 | ((void) 0); | |
11922 | ((void) 0); | |
11923 | suspendedRegs = regs; | |
11924 | ((void) 0); | |
11925 | } | |
11926 | void resume() { | |
11927 | ((void) 0); | |
11928 | suspendedRegs = __null; | |
11929 | ((void) 0); | |
11930 | } | |
11931 | void save(JSFrameRegs *regs) { | |
11932 | ((void) 0); | |
11933 | suspend(regs); | |
11934 | saved = true; | |
11935 | ((void) 0); | |
11936 | } | |
11937 | void restore() { | |
11938 | ((void) 0); | |
11939 | saved = false; | |
11940 | resume(); | |
11941 | ((void) 0); | |
11942 | } | |
11943 | JSStackFrame *getInitialFrame() const { | |
11944 | ((void) 0); | |
11945 | return initialFrame; | |
11946 | } | |
11947 | inline JSFrameRegs *getCurrentRegs() const; | |
11948 | inline JSStackFrame *getCurrentFrame() const; | |
11949 | JSFrameRegs *getSuspendedRegs() const { | |
11950 | ((void) 0); | |
11951 | return suspendedRegs; | |
11952 | } | |
11953 | JSStackFrame *getSuspendedFrame() const { | |
11954 | return suspendedRegs->fp; | |
11955 | } | |
11956 | void setPreviousInContext(StackSegment *seg) { | |
11957 | previousInContext = seg; | |
11958 | } | |
11959 | StackSegment *getPreviousInContext() const { | |
11960 | return previousInContext; | |
11961 | } | |
11962 | void setPreviousInMemory(StackSegment *seg) { | |
11963 | previousInMemory = seg; | |
11964 | } | |
11965 | StackSegment *getPreviousInMemory() const { | |
11966 | return previousInMemory; | |
11967 | } | |
11968 | void setInitialVarObj(JSObject *obj) { | |
11969 | ((void) 0); | |
11970 | initialVarObj = obj; | |
11971 | } | |
11972 | bool hasInitialVarObj() { | |
11973 | ((void) 0); | |
11974 | return initialVarObj != __null; | |
11975 | } | |
11976 | JSObject &getInitialVarObj() const { | |
11977 | ((void) 0); | |
11978 | return *initialVarObj; | |
11979 | } | |
11980 | }; | |
11981 | static const size_t VALUES_PER_STACK_SEGMENT = sizeof(StackSegment) / sizeof(Value); | |
11982 | typedef int js_static_assert63[(sizeof(StackSegment) % sizeof(Value) == 0) ? 1 : -1]; | |
11983 | class InvokeArgsGuard : public CallArgs | |
11984 | { | |
11985 | friend class StackSpace; | |
11986 | JSContext *cx; | |
11987 | StackSegment *seg; | |
11988 | Value *prevInvokeArgEnd; | |
11989 | public: | |
11990 | InvokeArgsGuard() : cx(__null), seg(__null) {} | |
11991 | ~InvokeArgsGuard(); | |
11992 | bool pushed() const { return cx != __null; } | |
11993 | }; | |
11994 | struct InvokeArgsAlreadyOnTheStack : CallArgs | |
11995 | { | |
11996 | InvokeArgsAlreadyOnTheStack(Value *vp, uintN argc) : CallArgs(vp + 2, argc) {} | |
11997 | }; | |
11998 | class InvokeFrameGuard | |
11999 | { | |
12000 | friend class StackSpace; | |
12001 | JSContext *cx_; | |
12002 | JSFrameRegs regs_; | |
12003 | JSFrameRegs *prevRegs_; | |
12004 | public: | |
12005 | InvokeFrameGuard() : cx_(__null) {} | |
12006 | ~InvokeFrameGuard() { if (pushed()) pop(); } | |
12007 | bool pushed() const { return cx_ != __null; } | |
12008 | JSContext *pushedFrameContext() const { ((void) 0); return cx_; } | |
12009 | void pop(); | |
12010 | JSStackFrame *fp() const { return regs_.fp; } | |
12011 | }; | |
12012 | class FrameGuard | |
12013 | { | |
12014 | friend class StackSpace; | |
12015 | JSContext *cx_; | |
12016 | StackSegment *seg_; | |
12017 | Value *vp_; | |
12018 | JSStackFrame *fp_; | |
12019 | public: | |
12020 | FrameGuard() : cx_(__null), vp_(__null), fp_(__null) {} | |
12021 | ~FrameGuard(); | |
12022 | bool pushed() const { return cx_ != __null; } | |
12023 | StackSegment *segment() const { return seg_; } | |
12024 | Value *vp() const { return vp_; } | |
12025 | JSStackFrame *fp() const { return fp_; } | |
12026 | }; | |
12027 | class ExecuteFrameGuard : public FrameGuard | |
12028 | { | |
12029 | friend class StackSpace; | |
12030 | JSFrameRegs regs_; | |
12031 | }; | |
12032 | class DummyFrameGuard : public FrameGuard | |
12033 | { | |
12034 | friend class StackSpace; | |
12035 | JSFrameRegs regs_; | |
12036 | }; | |
12037 | class GeneratorFrameGuard : public FrameGuard | |
12038 | {}; | |
12039 | class StackSpace | |
12040 | { | |
12041 | Value *base; | |
12042 | Value *end; | |
12043 | StackSegment *currentSegment; | |
12044 | Value *invokeArgEnd; | |
12045 | friend class InvokeArgsGuard; | |
12046 | friend class InvokeFrameGuard; | |
12047 | friend class FrameGuard; | |
12048 | bool pushSegmentForInvoke(JSContext *cx, uintN argc, InvokeArgsGuard *ag); | |
12049 | void popSegmentForInvoke(const InvokeArgsGuard &ag); | |
12050 | bool pushInvokeFrameSlow(JSContext *cx, const InvokeArgsGuard &ag, | |
12051 | InvokeFrameGuard *fg); | |
12052 | void popInvokeFrameSlow(const CallArgs &args); | |
12053 | bool getSegmentAndFrame(JSContext *cx, uintN vplen, uintN nslots, | |
12054 | FrameGuard *fg) const; | |
12055 | void pushSegmentAndFrame(JSContext *cx, JSFrameRegs *regs, FrameGuard *fg); | |
12056 | void popSegmentAndFrame(JSContext *cx); | |
12057 | struct EnsureSpaceCheck { | |
12058 | inline bool operator()(const StackSpace &, JSContext *, Value *, uintN); | |
12059 | }; | |
12060 | struct LimitCheck { | |
12061 | JSStackFrame *base; | |
12062 | Value **limit; | |
12063 | LimitCheck(JSStackFrame *base, Value **limit) : base(base), limit(limit) {} | |
12064 | inline bool operator()(const StackSpace &, JSContext *, Value *, uintN); | |
12065 | }; | |
12066 | template <class Check> | |
12067 | inline JSStackFrame *getCallFrame(JSContext *cx, Value *sp, uintN nactual, | |
12068 | JSFunction *fun, JSScript *script, | |
12069 | uint32 *pflags, Check check) const; | |
12070 | inline void popInvokeArgs(const InvokeArgsGuard &args); | |
12071 | inline void popInvokeFrame(const InvokeFrameGuard &ag); | |
12072 | inline Value *firstUnused() const; | |
12073 | inline bool isCurrentAndActive(JSContext *cx) const; | |
12074 | friend class AllFramesIter; | |
12075 | StackSegment *getCurrentSegment() const { return currentSegment; } | |
12076 | public: | |
12077 | static const size_t CAPACITY_VALS = 512 * 1024; | |
12078 | static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(Value); | |
12079 | static const size_t COMMIT_VALS = 16 * 1024; | |
12080 | static const size_t COMMIT_BYTES = COMMIT_VALS * sizeof(Value); | |
12081 | static const size_t STACK_QUOTA = (VALUES_PER_STACK_FRAME + 18) * | |
12082 | 3000; | |
12083 | bool init(); | |
12084 | void finish(); | |
12085 | inline bool ensureEnoughSpaceToEnterTrace(); | |
12086 | static const ptrdiff_t MAX_TRACE_SPACE_VALS = | |
12087 | MAX_NATIVE_STACK_SLOTS + MAX_CALL_STACK_ENTRIES * VALUES_PER_STACK_FRAME + | |
12088 | (VALUES_PER_STACK_SEGMENT + VALUES_PER_STACK_FRAME ); | |
12089 | void mark(JSTracer *trc); | |
12090 | bool pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag); | |
12091 | bool getInvokeFrame(JSContext *cx, const CallArgs &args, JSFunction *fun, | |
12092 | JSScript *script, uint32 *flags, InvokeFrameGuard *fg) const; | |
12093 | void pushInvokeFrame(JSContext *cx, const CallArgs &args, InvokeFrameGuard *fg); | |
12094 | bool getExecuteFrame(JSContext *cx, JSScript *script, ExecuteFrameGuard *fg) const; | |
12095 | void pushExecuteFrame(JSContext *cx, JSObject *initialVarObj, ExecuteFrameGuard *fg); | |
12096 | inline JSStackFrame *getInlineFrame(JSContext *cx, Value *sp, uintN nactual, | |
12097 | JSFunction *fun, JSScript *script, | |
12098 | uint32 *flags) const; | |
12099 | inline void pushInlineFrame(JSContext *cx, JSScript *script, JSStackFrame *fp, | |
12100 | JSFrameRegs *regs); | |
12101 | inline void popInlineFrame(JSContext *cx, JSStackFrame *prev, js::Value *newsp); | |
12102 | bool getGeneratorFrame(JSContext *cx, uintN vplen, uintN nslots, | |
12103 | GeneratorFrameGuard *fg); | |
12104 | void pushGeneratorFrame(JSContext *cx, JSFrameRegs *regs, GeneratorFrameGuard *fg); | |
12105 | bool pushDummyFrame(JSContext *cx, JSObject &scopeChain, DummyFrameGuard *fg); | |
12106 | inline JSStackFrame *getInlineFrameWithinLimit(JSContext *cx, Value *sp, uintN nactual, | |
12107 | JSFunction *fun, JSScript *script, uint32 *flags, | |
12108 | JSStackFrame *base, Value **limit) const; | |
12109 | inline Value *getStackLimit(JSContext *cx); | |
12110 | bool bumpCommitAndLimit(JSStackFrame *base, Value *from, uintN nvals, Value **limit) const; | |
12111 | inline bool ensureSpace(JSContext *maybecx, Value *from, ptrdiff_t nvals) const; | |
12112 | }; | |
12113 | typedef int js_static_assert64[(StackSpace::CAPACITY_VALS % StackSpace::COMMIT_VALS == 0) ? 1 : -1]; | |
12114 | class FrameRegsIter | |
12115 | { | |
12116 | JSContext *cx; | |
12117 | StackSegment *curseg; | |
12118 | JSStackFrame *curfp; | |
12119 | Value *cursp; | |
12120 | jsbytecode *curpc; | |
12121 | void initSlow(); | |
12122 | void incSlow(JSStackFrame *fp, JSStackFrame *prev); | |
12123 | public: | |
12124 | inline FrameRegsIter(JSContext *cx); | |
12125 | bool done() const { return curfp == __null; } | |
12126 | inline FrameRegsIter &operator++(); | |
12127 | JSStackFrame *fp() const { return curfp; } | |
12128 | Value *sp() const { return cursp; } | |
12129 | jsbytecode *pc() const { return curpc; } | |
12130 | }; | |
12131 | class AllFramesIter | |
12132 | { | |
12133 | public: | |
12134 | AllFramesIter(JSContext *cx); | |
12135 | bool done() const { return curfp == __null; } | |
12136 | AllFramesIter& operator++(); | |
12137 | JSStackFrame *fp() const { return curfp; } | |
12138 | private: | |
12139 | StackSegment *curcs; | |
12140 | JSStackFrame *curfp; | |
12141 | }; | |
12142 | } | |
12143 | struct JSPendingProxyOperation { | |
12144 | JSPendingProxyOperation *next; | |
12145 | JSObject *object; | |
12146 | }; | |
12147 | struct JSThreadData { | |
12148 | unsigned requestDepth; | |
12149 | volatile int32 interruptFlags; | |
12150 | js::StackSpace stackSpace; | |
12151 | bool waiveGCQuota; | |
12152 | JSGSNCache gsnCache; | |
12153 | js::PropertyCache propertyCache; | |
12154 | DtoaState *dtoaState; | |
12155 | jsuword *nativeStackBase; | |
12156 | JSPendingProxyOperation *pendingProxyOperation; | |
12157 | js::ConservativeGCThreadData conservativeGC; | |
12158 | bool init(); | |
12159 | void finish(); | |
12160 | void mark(JSTracer *trc); | |
12161 | void purge(JSContext *cx); | |
12162 | inline void triggerOperationCallback(JSRuntime *rt); | |
12163 | }; | |
12164 | struct JSThread { | |
12165 | typedef js::HashMap<void *, | |
12166 | JSThread *, | |
12167 | js::DefaultHasher<void *>, | |
12168 | js::SystemAllocPolicy> Map; | |
12169 | JSCList contextList; | |
12170 | void *id; | |
12171 | unsigned suspendCount; | |
12172 | JSThreadData data; | |
12173 | }; | |
12174 | extern JSThread * | |
12175 | js_CurrentThread(JSRuntime *rt); | |
12176 | extern JSBool | |
12177 | js_InitContextThread(JSContext *cx); | |
12178 | extern void | |
12179 | js_ClearContextThread(JSContext *cx); | |
12180 | typedef enum JSDestroyContextMode { | |
12181 | JSDCM_NO_GC, | |
12182 | JSDCM_MAYBE_GC, | |
12183 | JSDCM_FORCE_GC, | |
12184 | JSDCM_NEW_FAILED | |
12185 | } JSDestroyContextMode; | |
12186 | typedef enum JSRuntimeState { | |
12187 | JSRTS_DOWN, | |
12188 | JSRTS_LAUNCHING, | |
12189 | JSRTS_UP, | |
12190 | JSRTS_LANDING | |
12191 | } JSRuntimeState; | |
12192 | typedef struct JSPropertyTreeEntry { | |
12193 | JSDHashEntryHdr hdr; | |
12194 | js::Shape *child; | |
12195 | } JSPropertyTreeEntry; | |
12196 | typedef void | |
12197 | (* JSActivityCallback)(void *arg, JSBool active); | |
12198 | namespace js { | |
12199 | typedef js::Vector<JSCompartment *, 0, js::SystemAllocPolicy> WrapperVector; | |
12200 | } | |
12201 | struct JSRuntime { | |
12202 | JSCompartment *atomsCompartment; | |
12203 | bool atomsCompartmentIsLocked; | |
12204 | js::WrapperVector compartments; | |
12205 | JSRuntimeState state; | |
12206 | JSContextCallback cxCallback; | |
12207 | JSCompartmentCallback compartmentCallback; | |
12208 | void setActivityCallback(JSActivityCallback cb, void *arg) { | |
12209 | activityCallback = cb; | |
12210 | activityCallbackArg = arg; | |
12211 | } | |
12212 | JSActivityCallback activityCallback; | |
12213 | void *activityCallbackArg; | |
12214 | uint32 protoHazardShape; | |
12215 | js::GCChunkSet gcChunkSet; | |
12216 | js::RootedValueMap gcRootsHash; | |
12217 | js::GCLocks gcLocksHash; | |
12218 | jsrefcount gcKeepAtoms; | |
12219 | size_t gcBytes; | |
12220 | size_t gcTriggerBytes; | |
12221 | size_t gcLastBytes; | |
12222 | size_t gcMaxBytes; | |
12223 | size_t gcMaxMallocBytes; | |
12224 | size_t gcChunksWaitingToExpire; | |
12225 | uint32 gcEmptyArenaPoolLifespan; | |
12226 | uint32 gcNumber; | |
12227 | js::GCMarker *gcMarkingTracer; | |
12228 | uint32 gcTriggerFactor; | |
12229 | int64 gcJitReleaseTime; | |
12230 | JSGCMode gcMode; | |
12231 | volatile bool gcIsNeeded; | |
12232 | JSCompartment *gcTriggerCompartment; | |
12233 | JSCompartment *gcCurrentCompartment; | |
12234 | bool gcPoke; | |
12235 | bool gcMarkAndSweep; | |
12236 | bool gcRunning; | |
12237 | bool gcRegenShapes; | |
12238 | JSGCCallback gcCallback; | |
12239 | private: | |
12240 | volatile ptrdiff_t gcMallocBytes; | |
12241 | public: | |
12242 | js::GCChunkAllocator *gcChunkAllocator; | |
12243 | void setCustomGCChunkAllocator(js::GCChunkAllocator *allocator) { | |
12244 | ((void) 0); | |
12245 | ((void) 0); | |
12246 | gcChunkAllocator = allocator; | |
12247 | } | |
12248 | JSTraceDataOp gcExtraRootsTraceOp; | |
12249 | void *gcExtraRootsData; | |
12250 | js::Value NaNValue; | |
12251 | js::Value negativeInfinityValue; | |
12252 | js::Value positiveInfinityValue; | |
12253 | JSFlatString *emptyString; | |
12254 | JSCList contextList; | |
12255 | JSDebugHooks globalDebugHooks; | |
12256 | JSBool debugMode; | |
12257 | JSCList trapList; | |
12258 | JSCList watchPointList; | |
12259 | void *data; | |
12260 | PRLock *gcLock; | |
12261 | PRCondVar *gcDone; | |
12262 | PRCondVar *requestDone; | |
12263 | uint32 requestCount; | |
12264 | JSThread *gcThread; | |
12265 | js::GCHelperThread gcHelperThread; | |
12266 | PRLock *rtLock; | |
12267 | PRCondVar *stateChange; | |
12268 | PRLock *debuggerLock; | |
12269 | JSThread::Map threads; | |
12270 | uint32 debuggerMutations; | |
12271 | JSSecurityCallbacks *securityCallbacks; | |
12272 | const JSStructuredCloneCallbacks *structuredCloneCallbacks; | |
12273 | int32 propertyRemovals; | |
12274 | struct JSHashTable *scriptFilenameTable; | |
12275 | JSCList scriptFilenamePrefixes; | |
12276 | PRLock *scriptFilenameTableLock; | |
12277 | const char *thousandsSeparator; | |
12278 | const char *decimalSeparator; | |
12279 | const char *numGrouping; | |
12280 | JSObject *anynameObject; | |
12281 | JSObject *functionNamespaceObject; | |
12282 | volatile int32 interruptCounter; | |
12283 | volatile uint32 shapeGen; | |
12284 | JSAtomState atomState; | |
12285 | JSWrapObjectCallback wrapObjectCallback; | |
12286 | JSPreWrapCallback preWrapObjectCallback; | |
12287 | uint32 stringMemoryUsed; | |
12288 | JSRuntime(); | |
12289 | ~JSRuntime(); | |
12290 | bool init(uint32 maxbytes); | |
12291 | void setGCTriggerFactor(uint32 factor); | |
12292 | void setGCLastBytes(size_t lastBytes); | |
12293 | void* malloc(size_t bytes, JSContext *cx = __null) { | |
12294 | updateMallocCounter(bytes); | |
12295 | void *p = ::js_malloc(bytes); | |
12296 | return (__builtin_expect((!!p), 1)) ? p : onOutOfMemory(__null, bytes, cx); | |
12297 | } | |
12298 | void* calloc(size_t bytes, JSContext *cx = __null) { | |
12299 | updateMallocCounter(bytes); | |
12300 | void *p = ::js_calloc(bytes); | |
12301 | return (__builtin_expect((!!p), 1)) ? p : onOutOfMemory(reinterpret_cast<void *>(1), bytes, cx); | |
12302 | } | |
12303 | void* realloc(void* p, size_t oldBytes, size_t newBytes, JSContext *cx = __null) { | |
12304 | ((void) 0); | |
12305 | updateMallocCounter(newBytes - oldBytes); | |
12306 | void *p2 = ::js_realloc(p, newBytes); | |
12307 | return (__builtin_expect((!!p2), 1)) ? p2 : onOutOfMemory(p, newBytes, cx); | |
12308 | } | |
12309 | void* realloc(void* p, size_t bytes, JSContext *cx = __null) { | |
12310 | if (!p) | |
12311 | updateMallocCounter(bytes); | |
12312 | void *p2 = ::js_realloc(p, bytes); | |
12313 | return (__builtin_expect((!!p2), 1)) ? p2 : onOutOfMemory(p, bytes, cx); | |
12314 | } | |
12315 | void free(void* p) { ::js_free(p); } | |
12316 | bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; } | |
12317 | void resetGCMallocBytes() { gcMallocBytes = ptrdiff_t(gcMaxMallocBytes); } | |
12318 | void setGCMaxMallocBytes(size_t value) { | |
12319 | gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1; | |
12320 | resetGCMallocBytes(); | |
12321 | } | |
12322 | void updateMallocCounter(size_t nbytes) { | |
12323 | ptrdiff_t newCount = gcMallocBytes - ptrdiff_t(nbytes); | |
12324 | gcMallocBytes = newCount; | |
12325 | if ((__builtin_expect((newCount <= 0), 0))) | |
12326 | onTooMuchMalloc(); | |
12327 | } | |
12328 | private: | |
12329 | __attribute__((visibility ("default"))) void onTooMuchMalloc(); | |
12330 | __attribute__((visibility ("default"))) void * onOutOfMemory(void *p, size_t nbytes, JSContext *cx); | |
12331 | }; | |
12332 | struct JSArgumentFormatMap { | |
12333 | const char *format; | |
12334 | size_t length; | |
12335 | JSArgumentFormatter formatter; | |
12336 | JSArgumentFormatMap *next; | |
12337 | }; | |
12338 | typedef struct JSResolvingKey { | |
12339 | JSObject *obj; | |
12340 | jsid id; | |
12341 | } JSResolvingKey; | |
12342 | typedef struct JSResolvingEntry { | |
12343 | JSDHashEntryHdr hdr; | |
12344 | JSResolvingKey key; | |
12345 | uint32 flags; | |
12346 | } JSResolvingEntry; | |
12347 | extern const JSDebugHooks js_NullDebugHooks; | |
12348 | namespace js { | |
12349 | class AutoGCRooter; | |
12350 | static inline | |
12351 | bool | |
12352 | OptionsHasXML(uint32 options) | |
12353 | { | |
12354 | return !!(options & ((JSUint32)1 << (6))); | |
12355 | } | |
12356 | static inline | |
12357 | bool | |
12358 | OptionsHasAnonFunFix(uint32 options) | |
12359 | { | |
12360 | return !!(options & ((JSUint32)1 << (10))); | |
12361 | } | |
12362 | static inline | |
12363 | bool | |
12364 | OptionsSameVersionFlags(uint32 self, uint32 other) | |
12365 | { | |
12366 | static const uint32 mask = ((JSUint32)1 << (6)) | ((JSUint32)1 << (10)); | |
12367 | return !((self & mask) ^ (other & mask)); | |
12368 | } | |
12369 | namespace VersionFlags { | |
12370 | static const uintN MASK = 0x0FFF; | |
12371 | static const uintN HAS_XML = 0x1000; | |
12372 | static const uintN ANONFUNFIX = 0x2000; | |
12373 | static const uintN FULL_MASK = 0x3FFF; | |
12374 | } | |
12375 | static inline JSVersion | |
12376 | VersionNumber(JSVersion version) | |
12377 | { | |
12378 | return JSVersion(uint32(version) & VersionFlags::MASK); | |
12379 | } | |
12380 | static inline | |
12381 | bool | |
12382 | VersionHasXML(JSVersion version) | |
12383 | { | |
12384 | return !!(version & VersionFlags::HAS_XML); | |
12385 | } | |
12386 | static inline | |
12387 | bool | |
12388 | VersionShouldParseXML(JSVersion version) | |
12389 | { | |
12390 | return VersionHasXML(version) || VersionNumber(version) >= JSVERSION_1_6; | |
12391 | } | |
12392 | static inline | |
12393 | bool | |
12394 | VersionHasAnonFunFix(JSVersion version) | |
12395 | { | |
12396 | return !!(version & VersionFlags::ANONFUNFIX); | |
12397 | } | |
12398 | static inline void | |
12399 | VersionSetXML(JSVersion *version, bool enable) | |
12400 | { | |
12401 | if (enable) | |
12402 | *version = JSVersion(uint32(*version) | VersionFlags::HAS_XML); | |
12403 | else | |
12404 | *version = JSVersion(uint32(*version) & ~VersionFlags::HAS_XML); | |
12405 | } | |
12406 | static inline void | |
12407 | VersionSetAnonFunFix(JSVersion *version, bool enable) | |
12408 | { | |
12409 | if (enable) | |
12410 | *version = JSVersion(uint32(*version) | VersionFlags::ANONFUNFIX); | |
12411 | else | |
12412 | *version = JSVersion(uint32(*version) & ~VersionFlags::ANONFUNFIX); | |
12413 | } | |
12414 | static inline JSVersion | |
12415 | VersionExtractFlags(JSVersion version) | |
12416 | { | |
12417 | return JSVersion(uint32(version) & ~VersionFlags::MASK); | |
12418 | } | |
12419 | static inline void | |
12420 | VersionCopyFlags(JSVersion *version, JSVersion from) | |
12421 | { | |
12422 | *version = JSVersion(VersionNumber(*version) | VersionExtractFlags(from)); | |
12423 | } | |
12424 | static inline | |
12425 | bool | |
12426 | VersionHasFlags(JSVersion version) | |
12427 | { | |
12428 | return !!VersionExtractFlags(version); | |
12429 | } | |
12430 | static inline uintN | |
12431 | VersionFlagsToOptions(JSVersion version) | |
12432 | { | |
12433 | uintN copts = (VersionHasXML(version) ? ((JSUint32)1 << (6)) : 0) | | |
12434 | (VersionHasAnonFunFix(version) ? ((JSUint32)1 << (10)) : 0); | |
12435 | ((void) 0); | |
12436 | return copts; | |
12437 | } | |
12438 | static inline JSVersion | |
12439 | OptionFlagsToVersion(uintN options, JSVersion version) | |
12440 | { | |
12441 | VersionSetXML(&version, OptionsHasXML(options)); | |
12442 | VersionSetAnonFunFix(&version, OptionsHasAnonFunFix(options)); | |
12443 | return version; | |
12444 | } | |
12445 | static inline | |
12446 | bool | |
12447 | VersionIsKnown(JSVersion version) | |
12448 | { | |
12449 | return VersionNumber(version) != JSVERSION_UNKNOWN; | |
12450 | } | |
12451 | typedef js::HashSet<JSObject *, | |
12452 | js::DefaultHasher<JSObject *>, | |
12453 | js::SystemAllocPolicy> BusyArraysMap; | |
12454 | } | |
12455 | struct JSContext | |
12456 | { | |
12457 | explicit JSContext(JSRuntime *rt); | |
12458 | JSCList link; | |
12459 | private: | |
12460 | JSVersion defaultVersion; | |
12461 | JSVersion versionOverride; | |
12462 | bool hasVersionOverride; | |
12463 | JSBool throwing; | |
12464 | js::Value exception; | |
12465 | uintN runOptions; | |
12466 | public: | |
12467 | JSLocaleCallbacks *localeCallbacks; | |
12468 | JSDHashTable *resolvingTable; | |
12469 | JSPackedBool generatingError; | |
12470 | jsuword stackLimit; | |
12471 | size_t scriptStackQuota; | |
12472 | JSRuntime *const runtime; | |
12473 | JSCompartment *compartment; | |
12474 | ||
12475 | JSFrameRegs *regs; | |
12476 | JSStackFrame* fp() { | |
12477 | ((void) 0); | |
12478 | return regs->fp; | |
12479 | } | |
12480 | JSStackFrame* maybefp() { | |
12481 | ((void) 0); | |
12482 | return regs ? regs->fp : __null; | |
12483 | } | |
12484 | bool hasfp() { | |
12485 | ((void) 0); | |
12486 | return !!regs; | |
12487 | } | |
12488 | public: | |
12489 | friend class js::StackSpace; | |
12490 | friend bool js::Interpret(JSContext *, JSStackFrame *, uintN, JSInterpMode); | |
12491 | void resetCompartment(); | |
12492 | void wrapPendingException(); | |
12493 | void setCurrentRegs(JSFrameRegs *regs) { | |
12494 | ((void) 0); | |
12495 | this->regs = regs; | |
12496 | } | |
12497 | JSArenaPool tempPool; | |
12498 | JSArenaPool regExpPool; | |
12499 | JSObject *globalObject; | |
12500 | JSSharpObjectMap sharpObjectMap; | |
12501 | js::BusyArraysMap busyArrays; | |
12502 | JSArgumentFormatMap *argumentFormatMap; | |
12503 | char *lastMessage; | |
12504 | JSErrorReporter errorReporter; | |
12505 | JSOperationCallback operationCallback; | |
12506 | uintN interpLevel; | |
12507 | void *data; | |
12508 | void *data2; | |
12509 | private: | |
12510 | js::StackSegment *currentSegment; | |
12511 | public: | |
12512 | void assertSegmentsInSync() const { | |
12513 | } | |
12514 | bool hasActiveSegment() const { | |
12515 | assertSegmentsInSync(); | |
12516 | return !!regs; | |
12517 | } | |
12518 | js::StackSegment *activeSegment() const { | |
12519 | ((void) 0); | |
12520 | return currentSegment; | |
12521 | } | |
12522 | js::StackSegment *getCurrentSegment() const { | |
12523 | assertSegmentsInSync(); | |
12524 | return currentSegment; | |
12525 | } | |
12526 | inline js::RegExpStatics *regExpStatics(); | |
12527 | void pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs ®s); | |
12528 | void popSegmentAndFrame(); | |
12529 | void saveActiveSegment(); | |
12530 | void restoreSegment(); | |
12531 | inline JSStackFrame *computeNextFrame(JSStackFrame *fp); | |
12532 | js::StackSegment *containingSegment(const JSStackFrame *target); | |
12533 | JSStackFrame *findFrameAtLevel(uintN targetLevel) const { | |
12534 | JSStackFrame *fp = regs->fp; | |
12535 | while (true) { | |
12536 | ((void) 0); | |
12537 | if (fp->script()->staticLevel == targetLevel) | |
12538 | break; | |
12539 | fp = fp->prev(); | |
12540 | } | |
12541 | return fp; | |
12542 | } | |
12543 | public: | |
12544 | bool canSetDefaultVersion() const { | |
12545 | return !regs && !hasVersionOverride; | |
12546 | } | |
12547 | void overrideVersion(JSVersion newVersion) { | |
12548 | ((void) 0); | |
12549 | versionOverride = newVersion; | |
12550 | hasVersionOverride = true; | |
12551 | } | |
12552 | void setDefaultVersion(JSVersion version) { | |
12553 | defaultVersion = version; | |
12554 | } | |
12555 | void clearVersionOverride() { hasVersionOverride = false; } | |
12556 | JSVersion getDefaultVersion() const { return defaultVersion; } | |
12557 | bool isVersionOverridden() const { return hasVersionOverride; } | |
12558 | JSVersion getVersionOverride() const { | |
12559 | ((void) 0); | |
12560 | return versionOverride; | |
12561 | } | |
12562 | bool maybeOverrideVersion(JSVersion newVersion) { | |
12563 | if (canSetDefaultVersion()) { | |
12564 | setDefaultVersion(newVersion); | |
12565 | return false; | |
12566 | } | |
12567 | overrideVersion(newVersion); | |
12568 | return true; | |
12569 | } | |
12570 | private: | |
12571 | void maybeMigrateVersionOverride() { | |
12572 | if ((__builtin_expect((!isVersionOverridden() || currentSegment), 1))) | |
12573 | return; | |
12574 | defaultVersion = versionOverride; | |
12575 | clearVersionOverride(); | |
12576 | } | |
12577 | public: | |
12578 | JSVersion findVersion() const { | |
12579 | if (hasVersionOverride) | |
12580 | return versionOverride; | |
12581 | if (regs) { | |
12582 | JSStackFrame *fp = regs->fp; | |
12583 | while (fp && !fp->isScriptFrame()) | |
12584 | fp = fp->prev(); | |
12585 | if (fp) | |
12586 | return fp->script()->getVersion(); | |
12587 | } | |
12588 | return defaultVersion; | |
12589 | } | |
12590 | void setRunOptions(uintN ropts) { | |
12591 | ((void) 0); | |
12592 | runOptions = ropts; | |
12593 | } | |
12594 | void setCompileOptions(uintN newcopts) { | |
12595 | ((void) 0); | |
12596 | if ((__builtin_expect((getCompileOptions() == newcopts), 1))) | |
12597 | return; | |
12598 | JSVersion version = findVersion(); | |
12599 | JSVersion newVersion = js::OptionFlagsToVersion(newcopts, version); | |
12600 | maybeOverrideVersion(newVersion); | |
12601 | } | |
12602 | uintN getRunOptions() const { return runOptions; } | |
12603 | uintN getCompileOptions() const { return js::VersionFlagsToOptions(findVersion()); } | |
12604 | uintN allOptions() const { return getRunOptions() | getCompileOptions(); } | |
12605 | bool hasRunOption(uintN ropt) const { | |
12606 | ((void) 0); | |
12607 | return !!(runOptions & ropt); | |
12608 | } | |
12609 | bool hasStrictOption() const { return hasRunOption(((JSUint32)1 << (0))); } | |
12610 | bool hasWErrorOption() const { return hasRunOption(((JSUint32)1 << (1))); } | |
12611 | bool hasAtLineOption() const { return hasRunOption(((JSUint32)1 << (5))); } | |
12612 | JSThread *thread; | |
12613 | unsigned outstandingRequests; | |
12614 | JSCList threadLinks; | |
12615 | js::AutoGCRooter *autoGCRooters; | |
12616 | const JSDebugHooks *debugHooks; | |
12617 | JSSecurityCallbacks *securityCallbacks; | |
12618 | uintN resolveFlags; | |
12619 | int64 rngSeed; | |
12620 | js::Value iterValue; | |
12621 | void updateJITEnabled(); | |
12622 | DSTOffsetCache dstOffsetCache; | |
12623 | JSObject *enumerators; | |
12624 | private: | |
12625 | js::Vector<JSGenerator *, 2, js::SystemAllocPolicy> genStack; | |
12626 | public: | |
12627 | JSGenerator *generatorFor(JSStackFrame *fp) const; | |
12628 | inline bool ensureGeneratorStackSpace(); | |
12629 | bool enterGenerator(JSGenerator *gen) { | |
12630 | return genStack.append(gen); | |
12631 | } | |
12632 | void leaveGenerator(JSGenerator *gen) { | |
12633 | ((void) 0); | |
12634 | genStack.popBack(); | |
12635 | } | |
12636 | js::GCHelperThread *gcBackgroundFree; | |
12637 | inline void* malloc(size_t bytes) { | |
12638 | return runtime->malloc(bytes, this); | |
12639 | } | |
12640 | inline void* mallocNoReport(size_t bytes) { | |
12641 | ((void) 0); | |
12642 | return runtime->malloc(bytes, __null); | |
12643 | } | |
12644 | inline void* calloc(size_t bytes) { | |
12645 | ((void) 0); | |
12646 | return runtime->calloc(bytes, this); | |
12647 | } | |
12648 | inline void* realloc(void* p, size_t bytes) { | |
12649 | return runtime->realloc(p, bytes, this); | |
12650 | } | |
12651 | inline void* realloc(void* p, size_t oldBytes, size_t newBytes) { | |
12652 | return runtime->realloc(p, oldBytes, newBytes, this); | |
12653 | } | |
12654 | inline void free(void* p) { | |
12655 | if (gcBackgroundFree) { | |
12656 | gcBackgroundFree->freeLater(p); | |
12657 | return; | |
12658 | } | |
12659 | runtime->free(p); | |
12660 | } | |
12661 | template <class T> | |
12662 | __attribute__((always_inline)) inline T *create() { | |
12663 | void *memory = this->malloc(sizeof(T)); if (!memory) return __null; return new(memory) T (); | |
12664 | } | |
12665 | template <class T, class P1> | |
12666 | __attribute__((always_inline)) inline T *create(const P1 &p1) { | |
12667 | void *memory = this->malloc(sizeof(T)); if (!memory) return __null; return new(memory) T (p1); | |
12668 | } | |
12669 | template <class T, class P1, class P2> | |
12670 | __attribute__((always_inline)) inline T *create(const P1 &p1, const P2 &p2) { | |
12671 | void *memory = this->malloc(sizeof(T)); if (!memory) return __null; return new(memory) T (p1, p2); | |
12672 | } | |
12673 | template <class T, class P1, class P2, class P3> | |
12674 | __attribute__((always_inline)) inline T *create(const P1 &p1, const P2 &p2, const P3 &p3) { | |
12675 | void *memory = this->malloc(sizeof(T)); if (!memory) return __null; return new(memory) T (p1, p2, p3); | |
12676 | } | |
12677 | template <class T> | |
12678 | __attribute__((always_inline)) inline void destroy(T *p) { | |
12679 | p->~T(); | |
12680 | this->free(p); | |
12681 | } | |
12682 | void purge(); | |
12683 | js::StackSpace &stack() const { | |
12684 | return (&(this)->thread->data)->stackSpace; | |
12685 | } | |
12686 | void assertValidStackDepth(uintN ) {} | |
12687 | bool isExceptionPending() { | |
12688 | return throwing; | |
12689 | } | |
12690 | js::Value getPendingException() { | |
12691 | ((void) 0); | |
12692 | return exception; | |
12693 | } | |
12694 | void setPendingException(js::Value v); | |
12695 | void clearPendingException() { | |
12696 | this->throwing = false; | |
12697 | this->exception.setUndefined(); | |
12698 | } | |
12699 | private: | |
12700 | __attribute__((visibility ("default"))) void checkMallocGCPressure(void *p); | |
12701 | }; | |
12702 | static inline uintN | |
12703 | FramePCOffset(JSContext *cx, JSStackFrame* fp) | |
12704 | { | |
12705 | jsbytecode *pc = fp->hasImacropc() ? fp->imacropc() : fp->pc(cx); | |
12706 | return uintN(pc - fp->script()->code); | |
12707 | } | |
12708 | static inline JSAtom ** | |
12709 | FrameAtomBase(JSContext *cx, JSStackFrame *fp) | |
12710 | { | |
12711 | return fp->hasImacropc() | |
12712 | ? ((JSAtom **)((uint8 *)(&cx->runtime->atomState) + __builtin_offsetof (JSAtomState, emptyAtom))) | |
12713 | : fp->script()->atomMap.vector; | |
12714 | } | |
12715 | namespace js { | |
12716 | class AutoGCRooter { | |
12717 | public: | |
12718 | AutoGCRooter(JSContext *cx, ptrdiff_t tag) | |
12719 | : down(cx->autoGCRooters), tag(tag), context(cx) | |
12720 | { | |
12721 | ((void) 0); | |
12722 | ((void) 0); | |
12723 | cx->autoGCRooters = this; | |
12724 | } | |
12725 | ~AutoGCRooter() { | |
12726 | ((void) 0); | |
12727 | ((void) 0); | |
12728 | context->autoGCRooters = down; | |
12729 | } | |
12730 | inline void trace(JSTracer *trc); | |
12731 | friend __attribute__((visibility ("default"))) void MarkContext(JSTracer *trc, JSContext *acx); | |
12732 | friend void MarkRuntime(JSTracer *trc); | |
12733 | protected: | |
12734 | AutoGCRooter * const down; | |
12735 | ptrdiff_t tag; | |
12736 | JSContext * const context; | |
12737 | enum { | |
12738 | JSVAL = -1, | |
12739 | SHAPE = -2, | |
12740 | PARSER = -3, | |
12741 | SCRIPT = -4, | |
12742 | ENUMERATOR = -5, | |
12743 | IDARRAY = -6, | |
12744 | DESCRIPTORS = -7, | |
12745 | NAMESPACES = -8, | |
12746 | XML = -9, | |
12747 | OBJECT = -10, | |
12748 | ID = -11, | |
12749 | VALVECTOR = -12, | |
12750 | DESCRIPTOR = -13, | |
12751 | STRING = -14, | |
12752 | IDVECTOR = -15, | |
12753 | BINDINGS = -16, | |
12754 | SHAPEVECTOR = -17 | |
12755 | }; | |
12756 | private: | |
12757 | AutoGCRooter(AutoGCRooter &ida); | |
12758 | void operator=(AutoGCRooter &ida); | |
12759 | }; | |
12760 | class AutoValueRooter : private AutoGCRooter | |
12761 | { | |
12762 | public: | |
12763 | explicit AutoValueRooter(JSContext *cx | |
12764 | ) | |
12765 | : AutoGCRooter(cx, JSVAL), val(js::NullValue()) | |
12766 | { | |
12767 | do { } while (0); | |
12768 | } | |
12769 | AutoValueRooter(JSContext *cx, const Value &v | |
12770 | ) | |
12771 | : AutoGCRooter(cx, JSVAL), val(v) | |
12772 | { | |
12773 | do { } while (0); | |
12774 | } | |
12775 | AutoValueRooter(JSContext *cx, jsval v | |
12776 | ) | |
12777 | : AutoGCRooter(cx, JSVAL), val(js::Valueify(v)) | |
12778 | { | |
12779 | do { } while (0); | |
12780 | } | |
12781 | void set(Value v) { | |
12782 | ((void) 0); | |
12783 | val = v; | |
12784 | } | |
12785 | void set(jsval v) { | |
12786 | ((void) 0); | |
12787 | val = js::Valueify(v); | |
12788 | } | |
12789 | const Value &value() const { | |
12790 | ((void) 0); | |
12791 | return val; | |
12792 | } | |
12793 | Value *addr() { | |
12794 | ((void) 0); | |
12795 | return &val; | |
12796 | } | |
12797 | const jsval &jsval_value() const { | |
12798 | ((void) 0); | |
12799 | return Jsvalify(val); | |
12800 | } | |
12801 | jsval *jsval_addr() { | |
12802 | ((void) 0); | |
12803 | return Jsvalify(&val); | |
12804 | } | |
12805 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12806 | friend void MarkRuntime(JSTracer *trc); | |
12807 | private: | |
12808 | Value val; | |
12809 | ||
12810 | }; | |
12811 | class AutoObjectRooter : private AutoGCRooter { | |
12812 | public: | |
12813 | AutoObjectRooter(JSContext *cx, JSObject *obj = __null | |
12814 | ) | |
12815 | : AutoGCRooter(cx, OBJECT), obj(obj) | |
12816 | { | |
12817 | do { } while (0); | |
12818 | } | |
12819 | void setObject(JSObject *obj) { | |
12820 | this->obj = obj; | |
12821 | } | |
12822 | JSObject * object() const { | |
12823 | return obj; | |
12824 | } | |
12825 | JSObject ** addr() { | |
12826 | return &obj; | |
12827 | } | |
12828 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12829 | friend void MarkRuntime(JSTracer *trc); | |
12830 | private: | |
12831 | JSObject *obj; | |
12832 | ||
12833 | }; | |
12834 | class AutoStringRooter : private AutoGCRooter { | |
12835 | public: | |
12836 | AutoStringRooter(JSContext *cx, JSString *str = __null | |
12837 | ) | |
12838 | : AutoGCRooter(cx, STRING), str(str) | |
12839 | { | |
12840 | do { } while (0); | |
12841 | } | |
12842 | void setString(JSString *str) { | |
12843 | this->str = str; | |
12844 | } | |
12845 | JSString * string() const { | |
12846 | return str; | |
12847 | } | |
12848 | JSString ** addr() { | |
12849 | return &str; | |
12850 | } | |
12851 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12852 | private: | |
12853 | JSString *str; | |
12854 | ||
12855 | }; | |
12856 | class AutoArrayRooter : private AutoGCRooter { | |
12857 | public: | |
12858 | AutoArrayRooter(JSContext *cx, size_t len, Value *vec | |
12859 | ) | |
12860 | : AutoGCRooter(cx, len), array(vec) | |
12861 | { | |
12862 | do { } while (0); | |
12863 | ((void) 0); | |
12864 | } | |
12865 | AutoArrayRooter(JSContext *cx, size_t len, jsval *vec | |
12866 | ) | |
12867 | : AutoGCRooter(cx, len), array(Valueify(vec)) | |
12868 | { | |
12869 | do { } while (0); | |
12870 | ((void) 0); | |
12871 | } | |
12872 | void changeLength(size_t newLength) { | |
12873 | tag = ptrdiff_t(newLength); | |
12874 | ((void) 0); | |
12875 | } | |
12876 | void changeArray(Value *newArray, size_t newLength) { | |
12877 | changeLength(newLength); | |
12878 | array = newArray; | |
12879 | } | |
12880 | Value *array; | |
12881 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12882 | private: | |
12883 | ||
12884 | }; | |
12885 | class AutoShapeRooter : private AutoGCRooter { | |
12886 | public: | |
12887 | AutoShapeRooter(JSContext *cx, const js::Shape *shape | |
12888 | ) | |
12889 | : AutoGCRooter(cx, SHAPE), shape(shape) | |
12890 | { | |
12891 | do { } while (0); | |
12892 | } | |
12893 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12894 | friend void MarkRuntime(JSTracer *trc); | |
12895 | private: | |
12896 | const js::Shape * const shape; | |
12897 | ||
12898 | }; | |
12899 | class AutoScriptRooter : private AutoGCRooter { | |
12900 | public: | |
12901 | AutoScriptRooter(JSContext *cx, JSScript *script | |
12902 | ) | |
12903 | : AutoGCRooter(cx, SCRIPT), script(script) | |
12904 | { | |
12905 | do { } while (0); | |
12906 | } | |
12907 | void setScript(JSScript *script) { | |
12908 | this->script = script; | |
12909 | } | |
12910 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12911 | private: | |
12912 | JSScript *script; | |
12913 | ||
12914 | }; | |
12915 | class AutoIdRooter : private AutoGCRooter | |
12916 | { | |
12917 | public: | |
12918 | explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0) | |
12919 | ) | |
12920 | : AutoGCRooter(cx, ID), id_(id) | |
12921 | { | |
12922 | do { } while (0); | |
12923 | } | |
12924 | jsid id() { | |
12925 | return id_; | |
12926 | } | |
12927 | jsid * addr() { | |
12928 | return &id_; | |
12929 | } | |
12930 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12931 | friend void MarkRuntime(JSTracer *trc); | |
12932 | private: | |
12933 | jsid id_; | |
12934 | ||
12935 | }; | |
12936 | class AutoIdArray : private AutoGCRooter { | |
12937 | public: | |
12938 | AutoIdArray(JSContext *cx, JSIdArray *ida ) | |
12939 | : AutoGCRooter(cx, IDARRAY), idArray(ida) | |
12940 | { | |
12941 | do { } while (0); | |
12942 | } | |
12943 | ~AutoIdArray() { | |
12944 | if (idArray) | |
12945 | JS_DestroyIdArray(context, idArray); | |
12946 | } | |
12947 | bool operator!() { | |
12948 | return idArray == __null; | |
12949 | } | |
12950 | jsid operator[](size_t i) const { | |
12951 | ((void) 0); | |
12952 | ((void) 0); | |
12953 | return idArray->vector[i]; | |
12954 | } | |
12955 | size_t length() const { | |
12956 | return idArray->length; | |
12957 | } | |
12958 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12959 | JSIdArray *steal() { | |
12960 | JSIdArray *copy = idArray; | |
12961 | idArray = __null; | |
12962 | return copy; | |
12963 | } | |
12964 | protected: | |
12965 | inline void trace(JSTracer *trc); | |
12966 | private: | |
12967 | JSIdArray * idArray; | |
12968 | ||
12969 | AutoIdArray(AutoIdArray &ida); | |
12970 | void operator=(AutoIdArray &ida); | |
12971 | }; | |
12972 | class AutoEnumStateRooter : private AutoGCRooter | |
12973 | { | |
12974 | public: | |
12975 | AutoEnumStateRooter(JSContext *cx, JSObject *obj | |
12976 | ) | |
12977 | : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue() | |
12978 | { | |
12979 | do { } while (0); | |
12980 | ((void) 0); | |
12981 | } | |
12982 | ~AutoEnumStateRooter() { | |
12983 | if (!stateValue.isNull()) { | |
12984 | obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0); | |
12985 | ((void) 0); | |
12986 | } | |
12987 | } | |
12988 | friend void AutoGCRooter::trace(JSTracer *trc); | |
12989 | const Value &state() const { return stateValue; } | |
12990 | Value *addr() { return &stateValue; } | |
12991 | protected: | |
12992 | void trace(JSTracer *trc); | |
12993 | JSObject * const obj; | |
12994 | private: | |
12995 | Value stateValue; | |
12996 | ||
12997 | }; | |
12998 | class AutoXMLRooter : private AutoGCRooter { | |
12999 | public: | |
13000 | AutoXMLRooter(JSContext *cx, JSXML *xml | |
13001 | ) | |
13002 | : AutoGCRooter(cx, XML), xml(xml) | |
13003 | { | |
13004 | do { } while (0); | |
13005 | ((void) 0); | |
13006 | } | |
13007 | friend void AutoGCRooter::trace(JSTracer *trc); | |
13008 | friend void MarkRuntime(JSTracer *trc); | |
13009 | private: | |
13010 | JSXML * const xml; | |
13011 | ||
13012 | }; | |
13013 | class AutoBindingsRooter : private AutoGCRooter { | |
13014 | public: | |
13015 | AutoBindingsRooter(JSContext *cx, Bindings &bindings | |
13016 | ) | |
13017 | : AutoGCRooter(cx, BINDINGS), bindings(bindings) | |
13018 | { | |
13019 | do { } while (0); | |
13020 | } | |
13021 | friend void AutoGCRooter::trace(JSTracer *trc); | |
13022 | private: | |
13023 | Bindings &bindings; | |
13024 | ||
13025 | }; | |
13026 | class AutoLockGC { | |
13027 | public: | |
13028 | explicit AutoLockGC(JSRuntime *rt | |
13029 | ) | |
13030 | : rt(rt) | |
13031 | { | |
13032 | do { } while (0); | |
13033 | PR_Lock((rt)->gcLock); | |
13034 | } | |
13035 | ~AutoLockGC() { PR_Unlock((rt)->gcLock); } | |
13036 | private: | |
13037 | JSRuntime *rt; | |
13038 | ||
13039 | }; | |
13040 | class AutoUnlockGC { | |
13041 | private: | |
13042 | JSRuntime *rt; | |
13043 | ||
13044 | public: | |
13045 | explicit AutoUnlockGC(JSRuntime *rt | |
13046 | ) | |
13047 | : rt(rt) | |
13048 | { | |
13049 | do { } while (0); | |
13050 | PR_Unlock((rt)->gcLock); | |
13051 | } | |
13052 | ~AutoUnlockGC() { PR_Lock((rt)->gcLock); } | |
13053 | }; | |
13054 | class AutoLockAtomsCompartment { | |
13055 | private: | |
13056 | JSContext *cx; | |
13057 | ||
13058 | public: | |
13059 | AutoLockAtomsCompartment(JSContext *cx | |
13060 | ) | |
13061 | : cx(cx) | |
13062 | { | |
13063 | do { } while (0); | |
13064 | js_Lock(cx, &cx->runtime->atomState.lock); | |
13065 | cx->runtime->atomsCompartmentIsLocked = true; | |
13066 | } | |
13067 | ~AutoLockAtomsCompartment() { | |
13068 | cx->runtime->atomsCompartmentIsLocked = false; | |
13069 | js_Unlock(cx, &cx->runtime->atomState.lock); | |
13070 | } | |
13071 | }; | |
13072 | class AutoUnlockAtomsCompartment { | |
13073 | JSContext *cx; | |
13074 | ||
13075 | public: | |
13076 | AutoUnlockAtomsCompartment(JSContext *cx | |
13077 | ) | |
13078 | : cx(cx) | |
13079 | { | |
13080 | do { } while (0); | |
13081 | cx->runtime->atomsCompartmentIsLocked = false; | |
13082 | js_Unlock(cx, &cx->runtime->atomState.lock); | |
13083 | } | |
13084 | ~AutoUnlockAtomsCompartment() { | |
13085 | js_Lock(cx, &cx->runtime->atomState.lock); | |
13086 | cx->runtime->atomsCompartmentIsLocked = true; | |
13087 | } | |
13088 | }; | |
13089 | class AutoKeepAtoms { | |
13090 | JSRuntime *rt; | |
13091 | ||
13092 | public: | |
13093 | explicit AutoKeepAtoms(JSRuntime *rt | |
13094 | ) | |
13095 | : rt(rt) | |
13096 | { | |
13097 | do { } while (0); | |
13098 | PR_AtomicIncrement((PRInt32 *)(&(rt)->gcKeepAtoms));; | |
13099 | } | |
13100 | ~AutoKeepAtoms() { PR_AtomicDecrement((PRInt32 *)(&(rt)->gcKeepAtoms));; } | |
13101 | }; | |
13102 | class AutoArenaAllocator { | |
13103 | JSArenaPool *pool; | |
13104 | void *mark; | |
13105 | ||
13106 | public: | |
13107 | explicit AutoArenaAllocator(JSArenaPool *pool | |
13108 | ) | |
13109 | : pool(pool), mark(((void *) (pool)->current->avail)) | |
13110 | { | |
13111 | do { } while (0); | |
13112 | } | |
13113 | ~AutoArenaAllocator() { do { char *_m = (char *)(mark); JSArena *_a = (pool)->current; if (_a != &(pool)->first && (((jsuword)(_m) - (jsuword)((_a)->base)) <= ((jsuword)((_a)->avail) - (jsuword)((_a)->base)))) { _a->avail = (jsuword)(((jsuword)(_m) + (pool)->mask) & ~(pool)->mask); ((void) 0); ; ; } else { JS_ArenaRelease(pool, _m); } ; } while (0); } | |
13114 | template <typename T> | |
13115 | T *alloc(size_t elems) { | |
13116 | void *ptr; | |
13117 | do { JSArena *_a = (pool)->current; size_t _nb = (((jsuword)(elems * sizeof(T)) + (pool)->mask) & ~(pool)->mask); jsuword _p = _a->avail; if ((_nb > _a->limit) || _p > _a->limit - _nb) _p = (jsuword)JS_ArenaAllocate(pool, _nb); else _a->avail = _p + _nb; ptr = (void *) _p; do { } while (0) ; } while (0); | |
13118 | return static_cast<T *>(ptr); | |
13119 | } | |
13120 | }; | |
13121 | class AutoReleasePtr { | |
13122 | JSContext *cx; | |
13123 | void *ptr; | |
13124 | ||
13125 | AutoReleasePtr operator=(const AutoReleasePtr &other); | |
13126 | public: | |
13127 | explicit AutoReleasePtr(JSContext *cx, void *ptr | |
13128 | ) | |
13129 | : cx(cx), ptr(ptr) | |
13130 | { | |
13131 | do { } while (0); | |
13132 | } | |
13133 | ~AutoReleasePtr() { cx->free(ptr); } | |
13134 | }; | |
13135 | class AutoReleaseNullablePtr { | |
13136 | JSContext *cx; | |
13137 | void *ptr; | |
13138 | ||
13139 | AutoReleaseNullablePtr operator=(const AutoReleaseNullablePtr &other); | |
13140 | public: | |
13141 | explicit AutoReleaseNullablePtr(JSContext *cx, void *ptr | |
13142 | ) | |
13143 | : cx(cx), ptr(ptr) | |
13144 | { | |
13145 | do { } while (0); | |
13146 | } | |
13147 | void reset(void *ptr2) { | |
13148 | if (ptr) | |
13149 | cx->free(ptr); | |
13150 | ptr = ptr2; | |
13151 | } | |
13152 | ~AutoReleaseNullablePtr() { if (ptr) cx->free(ptr); } | |
13153 | }; | |
13154 | class AutoLocalNameArray { | |
13155 | public: | |
13156 | explicit AutoLocalNameArray(JSContext *cx, JSFunction *fun | |
13157 | ) | |
13158 | : context(cx), | |
13159 | mark(((void *) (&cx->tempPool)->current->avail)), | |
13160 | names(fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool)), | |
13161 | count(fun->script()->bindings.countLocalNames()) | |
13162 | { | |
13163 | do { } while (0); | |
13164 | } | |
13165 | ~AutoLocalNameArray() { | |
13166 | do { char *_m = (char *)(mark); JSArena *_a = (&context->tempPool)->current; if (_a != &(&context->tempPool)->first && (((jsuword)(_m) - (jsuword)((_a)->base)) <= ((jsuword)((_a)->avail) - (jsuword)((_a)->base)))) { _a->avail = (jsuword)(((jsuword)(_m) + (&context->tempPool)->mask) & ~(&context->tempPool)->mask); ((void) 0); ; ; } else { JS_ArenaRelease(&context->tempPool, _m); } ; } while (0); | |
13167 | } | |
13168 | operator bool() const { return !!names; } | |
13169 | uint32 length() const { return count; } | |
13170 | const jsuword &operator [](unsigned i) const { return names[i]; } | |
13171 | private: | |
13172 | JSContext *context; | |
13173 | void *mark; | |
13174 | jsuword *names; | |
13175 | uint32 count; | |
13176 | ||
13177 | }; | |
13178 | template <class RefCountable> | |
13179 | class AlreadyIncRefed | |
13180 | { | |
13181 | typedef RefCountable *****ConvertibleToBool; | |
13182 | RefCountable *obj; | |
13183 | public: | |
13184 | explicit AlreadyIncRefed(RefCountable *obj) : obj(obj) {} | |
13185 | bool null() const { return obj == __null; } | |
13186 | operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } | |
13187 | RefCountable *operator->() const { ((void) 0); return obj; } | |
13188 | RefCountable &operator*() const { ((void) 0); return *obj; } | |
13189 | RefCountable *get() const { return obj; } | |
13190 | }; | |
13191 | template <class RefCountable> | |
13192 | class NeedsIncRef | |
13193 | { | |
13194 | typedef RefCountable *****ConvertibleToBool; | |
13195 | RefCountable *obj; | |
13196 | public: | |
13197 | explicit NeedsIncRef(RefCountable *obj) : obj(obj) {} | |
13198 | bool null() const { return obj == __null; } | |
13199 | operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } | |
13200 | RefCountable *operator->() const { ((void) 0); return obj; } | |
13201 | RefCountable &operator*() const { ((void) 0); return *obj; } | |
13202 | RefCountable *get() const { return obj; } | |
13203 | }; | |
13204 | template <class RefCountable> | |
13205 | class AutoRefCount | |
13206 | { | |
13207 | typedef RefCountable *****ConvertibleToBool; | |
13208 | JSContext *const cx; | |
13209 | RefCountable *obj; | |
13210 | AutoRefCount(const AutoRefCount &); | |
13211 | void operator=(const AutoRefCount &); | |
13212 | public: | |
13213 | explicit AutoRefCount(JSContext *cx) | |
13214 | : cx(cx), obj(__null) | |
13215 | {} | |
13216 | AutoRefCount(JSContext *cx, NeedsIncRef<RefCountable> aobj) | |
13217 | : cx(cx), obj(aobj.get()) | |
13218 | { | |
13219 | if (obj) | |
13220 | obj->incref(cx); | |
13221 | } | |
13222 | AutoRefCount(JSContext *cx, AlreadyIncRefed<RefCountable> aobj) | |
13223 | : cx(cx), obj(aobj.get()) | |
13224 | {} | |
13225 | ~AutoRefCount() { | |
13226 | if (obj) | |
13227 | obj->decref(cx); | |
13228 | } | |
13229 | void reset(NeedsIncRef<RefCountable> aobj) { | |
13230 | if (obj) | |
13231 | obj->decref(cx); | |
13232 | obj = aobj.get(); | |
13233 | if (obj) | |
13234 | obj->incref(cx); | |
13235 | } | |
13236 | void reset(AlreadyIncRefed<RefCountable> aobj) { | |
13237 | if (obj) | |
13238 | obj->decref(cx); | |
13239 | obj = aobj.get(); | |
13240 | } | |
13241 | bool null() const { return obj == __null; } | |
13242 | operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } | |
13243 | RefCountable *operator->() const { ((void) 0); return obj; } | |
13244 | RefCountable &operator*() const { ((void) 0); return *obj; } | |
13245 | RefCountable *get() const { return obj; } | |
13246 | }; | |
13247 | } | |
13248 | class JSAutoResolveFlags | |
13249 | { | |
13250 | public: | |
13251 | JSAutoResolveFlags(JSContext *cx, uintN flags | |
13252 | ) | |
13253 | : mContext(cx), mSaved(cx->resolveFlags) | |
13254 | { | |
13255 | do { } while (0); | |
13256 | cx->resolveFlags = flags; | |
13257 | } | |
13258 | ~JSAutoResolveFlags() { mContext->resolveFlags = mSaved; } | |
13259 | private: | |
13260 | JSContext *mContext; | |
13261 | uintN mSaved; | |
13262 | ||
13263 | }; | |
13264 | extern JSThreadData * | |
13265 | js_CurrentThreadData(JSRuntime *rt); | |
13266 | extern JSBool | |
13267 | js_InitThreads(JSRuntime *rt); | |
13268 | extern void | |
13269 | js_FinishThreads(JSRuntime *rt); | |
13270 | extern void | |
13271 | js_PurgeThreads(JSContext *cx); | |
13272 | namespace js { | |
13273 | class ThreadDataIter : public JSThread::Map::Range | |
13274 | { | |
13275 | public: | |
13276 | ThreadDataIter(JSRuntime *rt) : JSThread::Map::Range(rt->threads.all()) {} | |
13277 | JSThreadData *threadData() const { | |
13278 | return &front().value->data; | |
13279 | } | |
13280 | }; | |
13281 | } | |
13282 | extern JSContext * | |
13283 | js_NewContext(JSRuntime *rt, size_t stackChunkSize); | |
13284 | extern void | |
13285 | js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); | |
13286 | static inline JSContext * | |
13287 | js_ContextFromLinkField(JSCList *link) | |
13288 | { | |
13289 | ((void) 0); | |
13290 | return (JSContext *) ((uint8 *) link - __builtin_offsetof (JSContext, link)); | |
13291 | } | |
13292 | extern JSContext * | |
13293 | js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); | |
13294 | extern __attribute__((visibility ("default"))) JSContext * | |
13295 | js_NextActiveContext(JSRuntime *, JSContext *); | |
13296 | extern JSBool | |
13297 | js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, | |
13298 | JSResolvingEntry **entryp); | |
13299 | extern void | |
13300 | js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, | |
13301 | JSResolvingEntry *entry, uint32 generation); | |
13302 | typedef enum JSErrNum { | |
13303 | JSMSG_NOT_AN_ERROR = 0, | |
13304 | JSMSG_NOT_DEFINED = 1, | |
13305 | JSMSG_INACTIVE = 2, | |
13306 | JSMSG_MORE_ARGS_NEEDED = 3, | |
13307 | JSMSG_BAD_CHAR = 4, | |
13308 | JSMSG_BAD_TYPE = 5, | |
13309 | JSMSG_ALLOC_OVERFLOW = 6, | |
13310 | JSMSG_MISSING_HEXDIGITS = 7, | |
13311 | JSMSG_INCOMPATIBLE_PROTO = 8, | |
13312 | JSMSG_NO_CONSTRUCTOR = 9, | |
13313 | JSMSG_CANT_ALIAS = 10, | |
13314 | JSMSG_NOT_SCRIPTED_FUNCTION = 11, | |
13315 | JSMSG_BAD_SORT_ARG = 12, | |
13316 | JSMSG_BAD_ATOMIC_NUMBER = 13, | |
13317 | JSMSG_TOO_MANY_LITERALS = 14, | |
13318 | JSMSG_CANT_WATCH = 15, | |
13319 | JSMSG_STACK_UNDERFLOW = 16, | |
13320 | JSMSG_NEED_DIET = 17, | |
13321 | JSMSG_TOO_MANY_LOCAL_ROOTS = 18, | |
13322 | JSMSG_READ_ONLY = 19, | |
13323 | JSMSG_BAD_FORMAL = 20, | |
13324 | JSMSG_CANT_DELETE = 21, | |
13325 | JSMSG_NOT_FUNCTION = 22, | |
13326 | JSMSG_NOT_CONSTRUCTOR = 23, | |
13327 | JSMSG_SCRIPT_STACK_QUOTA = 24, | |
13328 | JSMSG_TOO_DEEP = 25, | |
13329 | JSMSG_OVER_RECURSED = 26, | |
13330 | JSMSG_IN_NOT_OBJECT = 27, | |
13331 | JSMSG_BAD_NEW_RESULT = 28, | |
13332 | JSMSG_BAD_SHARP_DEF = 29, | |
13333 | JSMSG_BAD_SHARP_USE = 30, | |
13334 | JSMSG_BAD_INSTANCEOF_RHS = 31, | |
13335 | JSMSG_BAD_BYTECODE = 32, | |
13336 | JSMSG_BAD_RADIX = 33, | |
13337 | JSMSG_PAREN_BEFORE_LET = 34, | |
13338 | JSMSG_CANT_CONVERT = 35, | |
13339 | JSMSG_CYCLIC_VALUE = 36, | |
13340 | JSMSG_COMPILE_EXECED_SCRIPT = 37, | |
13341 | JSMSG_CANT_CONVERT_TO = 38, | |
13342 | JSMSG_NO_PROPERTIES = 39, | |
13343 | JSMSG_CANT_FIND_CLASS = 40, | |
13344 | JSMSG_CANT_XDR_CLASS = 41, | |
13345 | JSMSG_BYTECODE_TOO_BIG = 42, | |
13346 | JSMSG_UNKNOWN_FORMAT = 43, | |
13347 | JSMSG_TOO_MANY_CON_ARGS = 44, | |
13348 | JSMSG_TOO_MANY_FUN_ARGS = 45, | |
13349 | JSMSG_BAD_QUANTIFIER = 46, | |
13350 | JSMSG_MIN_TOO_BIG = 47, | |
13351 | JSMSG_MAX_TOO_BIG = 48, | |
13352 | JSMSG_OUT_OF_ORDER = 49, | |
13353 | JSMSG_BAD_DESTRUCT_DECL = 50, | |
13354 | JSMSG_BAD_DESTRUCT_ASS = 51, | |
13355 | JSMSG_PAREN_AFTER_LET = 52, | |
13356 | JSMSG_CURLY_AFTER_LET = 53, | |
13357 | JSMSG_MISSING_PAREN = 54, | |
13358 | JSMSG_UNTERM_CLASS = 55, | |
13359 | JSMSG_TRAILING_SLASH = 56, | |
13360 | JSMSG_BAD_CLASS_RANGE = 57, | |
13361 | JSMSG_BAD_REGEXP_FLAG = 58, | |
13362 | JSMSG_NO_INPUT = 59, | |
13363 | JSMSG_CANT_OPEN = 60, | |
13364 | JSMSG_BAD_STRING_MASK = 61, | |
13365 | JSMSG_UNMATCHED_RIGHT_PAREN = 62, | |
13366 | JSMSG_END_OF_DATA = 63, | |
13367 | JSMSG_SEEK_BEYOND_START = 64, | |
13368 | JSMSG_SEEK_BEYOND_END = 65, | |
13369 | JSMSG_END_SEEK = 66, | |
13370 | JSMSG_WHITHER_WHENCE = 67, | |
13371 | JSMSG_BAD_SCRIPT_MAGIC = 68, | |
13372 | JSMSG_PAREN_BEFORE_FORMAL = 69, | |
13373 | JSMSG_MISSING_FORMAL = 70, | |
13374 | JSMSG_PAREN_AFTER_FORMAL = 71, | |
13375 | JSMSG_CURLY_BEFORE_BODY = 72, | |
13376 | JSMSG_CURLY_AFTER_BODY = 73, | |
13377 | JSMSG_PAREN_BEFORE_COND = 74, | |
13378 | JSMSG_PAREN_AFTER_COND = 75, | |
13379 | JSMSG_DESTRUCT_DUP_ARG = 76, | |
13380 | JSMSG_NAME_AFTER_DOT = 77, | |
13381 | JSMSG_BRACKET_IN_INDEX = 78, | |
13382 | JSMSG_XML_WHOLE_PROGRAM = 79, | |
13383 | JSMSG_PAREN_BEFORE_SWITCH = 80, | |
13384 | JSMSG_PAREN_AFTER_SWITCH = 81, | |
13385 | JSMSG_CURLY_BEFORE_SWITCH = 82, | |
13386 | JSMSG_COLON_AFTER_CASE = 83, | |
13387 | JSMSG_WHILE_AFTER_DO = 84, | |
13388 | JSMSG_PAREN_AFTER_FOR = 85, | |
13389 | JSMSG_SEMI_AFTER_FOR_INIT = 86, | |
13390 | JSMSG_SEMI_AFTER_FOR_COND = 87, | |
13391 | JSMSG_PAREN_AFTER_FOR_CTRL = 88, | |
13392 | JSMSG_CURLY_BEFORE_TRY = 89, | |
13393 | JSMSG_CURLY_AFTER_TRY = 90, | |
13394 | JSMSG_PAREN_BEFORE_CATCH = 91, | |
13395 | JSMSG_CATCH_IDENTIFIER = 92, | |
13396 | JSMSG_PAREN_AFTER_CATCH = 93, | |
13397 | JSMSG_CURLY_BEFORE_CATCH = 94, | |
13398 | JSMSG_CURLY_AFTER_CATCH = 95, | |
13399 | JSMSG_CURLY_BEFORE_FINALLY = 96, | |
13400 | JSMSG_CURLY_AFTER_FINALLY = 97, | |
13401 | JSMSG_CATCH_OR_FINALLY = 98, | |
13402 | JSMSG_PAREN_BEFORE_WITH = 99, | |
13403 | JSMSG_PAREN_AFTER_WITH = 100, | |
13404 | JSMSG_CURLY_IN_COMPOUND = 101, | |
13405 | JSMSG_NO_VARIABLE_NAME = 102, | |
13406 | JSMSG_COLON_IN_COND = 103, | |
13407 | JSMSG_PAREN_AFTER_ARGS = 104, | |
13408 | JSMSG_BRACKET_AFTER_LIST = 105, | |
13409 | JSMSG_COLON_AFTER_ID = 106, | |
13410 | JSMSG_CURLY_AFTER_LIST = 107, | |
13411 | JSMSG_PAREN_IN_PAREN = 108, | |
13412 | JSMSG_SEMI_BEFORE_STMNT = 109, | |
13413 | JSMSG_NO_RETURN_VALUE = 110, | |
13414 | JSMSG_DUPLICATE_FORMAL = 111, | |
13415 | JSMSG_EQUAL_AS_ASSIGN = 112, | |
13416 | JSMSG_OPTIMIZED_CLOSURE_LEAK = 113, | |
13417 | JSMSG_TOO_MANY_DEFAULTS = 114, | |
13418 | JSMSG_TOO_MANY_CASES = 115, | |
13419 | JSMSG_BAD_SWITCH = 116, | |
13420 | JSMSG_BAD_FOR_LEFTSIDE = 117, | |
13421 | JSMSG_CATCH_AFTER_GENERAL = 118, | |
13422 | JSMSG_CATCH_WITHOUT_TRY = 119, | |
13423 | JSMSG_FINALLY_WITHOUT_TRY = 120, | |
13424 | JSMSG_LABEL_NOT_FOUND = 121, | |
13425 | JSMSG_TOUGH_BREAK = 122, | |
13426 | JSMSG_BAD_CONTINUE = 123, | |
13427 | JSMSG_BAD_RETURN_OR_YIELD = 124, | |
13428 | JSMSG_BAD_LABEL = 125, | |
13429 | JSMSG_DUPLICATE_LABEL = 126, | |
13430 | JSMSG_VAR_HIDES_ARG = 127, | |
13431 | JSMSG_BAD_VAR_INIT = 128, | |
13432 | JSMSG_BAD_LEFTSIDE_OF_ASS = 129, | |
13433 | JSMSG_BAD_OPERAND = 130, | |
13434 | JSMSG_BAD_PROP_ID = 131, | |
13435 | JSMSG_RESERVED_ID = 132, | |
13436 | JSMSG_SYNTAX_ERROR = 133, | |
13437 | JSMSG_BAD_SHARP_VAR_DEF = 134, | |
13438 | JSMSG_BAD_PROTOTYPE = 135, | |
13439 | JSMSG_MISSING_EXPONENT = 136, | |
13440 | JSMSG_OUT_OF_MEMORY = 137, | |
13441 | JSMSG_UNTERMINATED_STRING = 138, | |
13442 | JSMSG_TOO_MANY_PARENS = 139, | |
13443 | JSMSG_UNTERMINATED_COMMENT = 140, | |
13444 | JSMSG_UNTERMINATED_REGEXP = 141, | |
13445 | JSMSG_BAD_CLONE_FUNOBJ_SCOPE = 142, | |
13446 | JSMSG_SHARPVAR_TOO_BIG = 143, | |
13447 | JSMSG_ILLEGAL_CHARACTER = 144, | |
13448 | JSMSG_BAD_OCTAL = 145, | |
13449 | JSMSG_BAD_INDIRECT_CALL = 146, | |
13450 | JSMSG_UNCAUGHT_EXCEPTION = 147, | |
13451 | JSMSG_INVALID_BACKREF = 148, | |
13452 | JSMSG_BAD_BACKREF = 149, | |
13453 | JSMSG_PRECISION_RANGE = 150, | |
13454 | JSMSG_BAD_GETTER_OR_SETTER = 151, | |
13455 | JSMSG_BAD_ARRAY_LENGTH = 152, | |
13456 | JSMSG_CANT_DESCRIBE_PROPS = 153, | |
13457 | JSMSG_BAD_APPLY_ARGS = 154, | |
13458 | JSMSG_REDECLARED_VAR = 155, | |
13459 | JSMSG_UNDECLARED_VAR = 156, | |
13460 | JSMSG_ANON_NO_RETURN_VALUE = 157, | |
13461 | JSMSG_DEPRECATED_USAGE = 158, | |
13462 | JSMSG_BAD_URI = 159, | |
13463 | JSMSG_GETTER_ONLY = 160, | |
13464 | JSMSG_IDSTART_AFTER_NUMBER = 161, | |
13465 | JSMSG_UNDEFINED_PROP = 162, | |
13466 | JSMSG_USELESS_EXPR = 163, | |
13467 | JSMSG_REDECLARED_PARAM = 164, | |
13468 | JSMSG_NEWREGEXP_FLAGGED = 165, | |
13469 | JSMSG_RESERVED_SLOT_RANGE = 166, | |
13470 | JSMSG_CANT_DECODE_PRINCIPALS = 167, | |
13471 | JSMSG_CANT_SEAL_OBJECT = 168, | |
13472 | JSMSG_TOO_MANY_CATCH_VARS = 169, | |
13473 | JSMSG_BAD_XML_MARKUP = 170, | |
13474 | JSMSG_BAD_XML_CHARACTER = 171, | |
13475 | JSMSG_BAD_DEFAULT_XML_NAMESPACE = 172, | |
13476 | JSMSG_BAD_XML_NAME_SYNTAX = 173, | |
13477 | JSMSG_BRACKET_AFTER_ATTR_EXPR = 174, | |
13478 | JSMSG_NESTING_GENERATOR = 175, | |
13479 | JSMSG_CURLY_IN_XML_EXPR = 176, | |
13480 | JSMSG_BAD_XML_NAMESPACE = 177, | |
13481 | JSMSG_BAD_XML_ATTR_NAME = 178, | |
13482 | JSMSG_BAD_XML_NAME = 179, | |
13483 | JSMSG_BAD_XML_CONVERSION = 180, | |
13484 | JSMSG_BAD_XMLLIST_CONVERSION = 181, | |
13485 | JSMSG_BAD_GENERATOR_SEND = 182, | |
13486 | JSMSG_NO_ASSIGN_IN_XML_ATTR = 183, | |
13487 | JSMSG_BAD_XML_ATTR_VALUE = 184, | |
13488 | JSMSG_XML_TAG_NAME_MISMATCH = 185, | |
13489 | JSMSG_BAD_XML_TAG_SYNTAX = 186, | |
13490 | JSMSG_BAD_XML_LIST_SYNTAX = 187, | |
13491 | JSMSG_INCOMPATIBLE_METHOD = 188, | |
13492 | JSMSG_CANT_SET_XML_ATTRS = 189, | |
13493 | JSMSG_END_OF_XML_SOURCE = 190, | |
13494 | JSMSG_END_OF_XML_ENTITY = 191, | |
13495 | JSMSG_BAD_XML_QNAME = 192, | |
13496 | JSMSG_BAD_FOR_EACH_LOOP = 193, | |
13497 | JSMSG_BAD_XMLLIST_PUT = 194, | |
13498 | JSMSG_UNKNOWN_XML_ENTITY = 195, | |
13499 | JSMSG_BAD_XML_NCR = 196, | |
13500 | JSMSG_UNDEFINED_XML_NAME = 197, | |
13501 | JSMSG_DUPLICATE_XML_ATTR = 198, | |
13502 | JSMSG_TOO_MANY_LOCALS = 199, | |
13503 | JSMSG_ARRAY_INIT_TOO_BIG = 200, | |
13504 | JSMSG_REGEXP_TOO_COMPLEX = 201, | |
13505 | JSMSG_BUFFER_TOO_SMALL = 202, | |
13506 | JSMSG_BAD_SURROGATE_CHAR = 203, | |
13507 | JSMSG_UTF8_CHAR_TOO_LARGE = 204, | |
13508 | JSMSG_MALFORMED_UTF8_CHAR = 205, | |
13509 | JSMSG_USER_DEFINED_ERROR = 206, | |
13510 | JSMSG_WRONG_CONSTRUCTOR = 207, | |
13511 | JSMSG_BAD_GENERATOR_RETURN = 208, | |
13512 | JSMSG_BAD_ANON_GENERATOR_RETURN = 209, | |
13513 | JSMSG_NAME_AFTER_FOR_PAREN = 210, | |
13514 | JSMSG_IN_AFTER_FOR_NAME = 211, | |
13515 | JSMSG_BAD_TRAP_RETURN_VALUE = 212, | |
13516 | JSMSG_KEYWORD_NOT_NS = 213, | |
13517 | JSMSG_BAD_GENERATOR_YIELD = 214, | |
13518 | JSMSG_BAD_GENERATOR_SYNTAX = 215, | |
13519 | JSMSG_ARRAY_COMP_LEFTSIDE = 216, | |
13520 | JSMSG_NON_XML_FILTER = 217, | |
13521 | JSMSG_EMPTY_ARRAY_REDUCE = 218, | |
13522 | JSMSG_NON_LIST_XML_METHOD = 219, | |
13523 | JSMSG_BAD_DELETE_OPERAND = 220, | |
13524 | JSMSG_BAD_INCOP_OPERAND = 221, | |
13525 | JSMSG_UNEXPECTED_TYPE = 222, | |
13526 | JSMSG_LET_DECL_NOT_IN_BLOCK = 223, | |
13527 | JSMSG_BAD_OBJECT_INIT = 224, | |
13528 | JSMSG_CANT_SET_ARRAY_ATTRS = 225, | |
13529 | JSMSG_EVAL_ARITY = 226, | |
13530 | JSMSG_MISSING_FUN_ARG = 227, | |
13531 | JSMSG_JSON_BAD_PARSE = 228, | |
13532 | JSMSG_JSON_BAD_STRINGIFY = 229, | |
13533 | JSMSG_XDR_CLOSURE_WRAPPER = 230, | |
13534 | JSMSG_NOT_NONNULL_OBJECT = 231, | |
13535 | JSMSG_DEPRECATED_OCTAL = 232, | |
13536 | JSMSG_STRICT_CODE_WITH = 233, | |
13537 | JSMSG_DUPLICATE_PROPERTY = 234, | |
13538 | JSMSG_DEPRECATED_DELETE_OPERAND = 235, | |
13539 | JSMSG_DEPRECATED_ASSIGN = 236, | |
13540 | JSMSG_BAD_BINDING = 237, | |
13541 | JSMSG_INVALID_DESCRIPTOR = 238, | |
13542 | JSMSG_OBJECT_NOT_EXTENSIBLE = 239, | |
13543 | JSMSG_CANT_REDEFINE_PROP = 240, | |
13544 | JSMSG_CANT_APPEND_TO_ARRAY = 241, | |
13545 | JSMSG_CANT_DEFINE_ARRAY_LENGTH = 242, | |
13546 | JSMSG_CANT_DEFINE_ARRAY_INDEX = 243, | |
13547 | JSMSG_TYPED_ARRAY_BAD_INDEX = 244, | |
13548 | JSMSG_TYPED_ARRAY_NEGATIVE_ARG = 245, | |
13549 | JSMSG_TYPED_ARRAY_BAD_ARGS = 246, | |
13550 | JSMSG_CSP_BLOCKED_FUNCTION = 247, | |
13551 | JSMSG_BAD_GET_SET_FIELD = 248, | |
13552 | JSMSG_BAD_PROXY_FIX = 249, | |
13553 | JSMSG_INVALID_EVAL_SCOPE_ARG = 250, | |
13554 | JSMSG_ACCESSOR_WRONG_ARGS = 251, | |
13555 | JSMSG_THROW_TYPE_ERROR = 252, | |
13556 | JSMSG_BAD_TOISOSTRING_PROP = 253, | |
13557 | JSMSG_BAD_PARSE_NODE = 254, | |
13558 | JSMSG_NOT_EXPECTED_TYPE = 255, | |
13559 | JSMSG_CALLER_IS_STRICT = 256, | |
13560 | JSMSG_NEED_DEBUG_MODE = 257, | |
13561 | JSMSG_STRICT_CODE_LET_EXPR_STMT = 258, | |
13562 | JSMSG_CANT_CHANGE_EXTENSIBILITY = 259, | |
13563 | JSMSG_SC_BAD_SERIALIZED_DATA = 260, | |
13564 | JSMSG_SC_UNSUPPORTED_TYPE = 261, | |
13565 | JSMSG_SC_RECURSION = 262, | |
13566 | JSMSG_CANT_WRAP_XML_OBJECT = 263, | |
13567 | JSMSG_BAD_CLONE_VERSION = 264, | |
13568 | JSMSG_CANT_CLONE_OBJECT = 265, | |
13569 | JSMSG_NON_NATIVE_SCOPE = 266, | |
13570 | JSMSG_STRICT_FUNCTION_STATEMENT = 267, | |
13571 | JSMSG_INVALID_FOR_IN_INIT = 268, | |
13572 | JSMSG_CLEARED_SCOPE = 269, | |
13573 | JSErr_Limit | |
13574 | } JSErrNum; | |
13575 | extern __attribute__((visibility ("default"))) const JSErrorFormatString * | |
13576 | js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); | |
13577 | extern JSBool | |
13578 | js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap); | |
13579 | extern JSBool | |
13580 | js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback, | |
13581 | void *userRef, const uintN errorNumber, | |
13582 | JSBool charArgs, va_list ap); | |
13583 | extern JSBool | |
13584 | js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, | |
13585 | void *userRef, const uintN errorNumber, | |
13586 | char **message, JSErrorReport *reportp, | |
13587 | bool charArgs, va_list ap); | |
13588 | extern void | |
13589 | js_ReportOutOfMemory(JSContext *cx); | |
13590 | void | |
13591 | js_ReportOutOfScriptQuota(JSContext *cx); | |
13592 | extern __attribute__((visibility ("default"))) void | |
13593 | js_ReportOverRecursed(JSContext *cx); | |
13594 | extern __attribute__((visibility ("default"))) void | |
13595 | js_ReportAllocationOverflow(JSContext *cx); | |
13596 | extern __attribute__((visibility ("default"))) void | |
13597 | js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report); | |
13598 | extern void | |
13599 | js_ReportIsNotDefined(JSContext *cx, const char *name); | |
13600 | extern JSBool | |
13601 | js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, const js::Value &v, | |
13602 | JSString *fallback); | |
13603 | extern void | |
13604 | js_ReportMissingArg(JSContext *cx, const js::Value &v, uintN arg); | |
13605 | extern JSBool | |
13606 | js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber, | |
13607 | intN spindex, const js::Value &v, JSString *fallback, | |
13608 | const char *arg1, const char *arg2); | |
13609 | extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; | |
13610 | __attribute__((always_inline)) inline void | |
13611 | JSThreadData::triggerOperationCallback(JSRuntime *rt) | |
13612 | { | |
13613 | if (interruptFlags) | |
13614 | return; | |
13615 | PR_AtomicSet((PRInt32 *)(&interruptFlags), (PRInt32)(1)); | |
13616 | if (requestDepth != 0) | |
13617 | PR_AtomicIncrement((PRInt32 *)(&rt->interruptCounter)); | |
13618 | } | |
13619 | extern JSBool | |
13620 | js_InvokeOperationCallback(JSContext *cx); | |
13621 | extern JSBool | |
13622 | js_HandleExecutionInterrupt(JSContext *cx); | |
13623 | namespace js { | |
13624 | __attribute__((visibility ("default"))) void | |
13625 | TriggerOperationCallback(JSContext *cx); | |
13626 | void | |
13627 | TriggerAllOperationCallbacks(JSRuntime *rt); | |
13628 | } | |
13629 | extern JSStackFrame * | |
13630 | js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); | |
13631 | extern jsbytecode* | |
13632 | js_GetCurrentBytecodePC(JSContext* cx); | |
13633 | extern | |
13634 | bool | |
13635 | js_CurrentPCIsInImacro(JSContext *cx); | |
13636 | namespace js { | |
13637 | class RegExpStatics; | |
13638 | extern __attribute__((visibility ("default"))) void | |
13639 | LeaveTrace(JSContext *cx); | |
13640 | } | |
13641 | static inline JSStackFrame * | |
13642 | js_GetTopStackFrame(JSContext *cx) | |
13643 | { | |
13644 | js::LeaveTrace(cx); | |
13645 | return cx->maybefp(); | |
13646 | } | |
13647 | static inline JSBool | |
13648 | js_IsPropertyCacheDisabled(JSContext *cx) | |
13649 | { | |
13650 | return cx->runtime->shapeGen >= js::SHAPE_OVERFLOW_BIT; | |
13651 | } | |
13652 | static inline uint32 | |
13653 | js_RegenerateShapeForGC(JSRuntime *rt) | |
13654 | { | |
13655 | ((void) 0); | |
13656 | ((void) 0); | |
13657 | uint32 shape = rt->shapeGen; | |
13658 | shape = (shape + 1) | (shape & js::SHAPE_OVERFLOW_BIT); | |
13659 | rt->shapeGen = shape; | |
13660 | return shape; | |
13661 | } | |
13662 | namespace js { | |
13663 | inline void * | |
13664 | ContextAllocPolicy::malloc(size_t bytes) | |
13665 | { | |
13666 | return cx->malloc(bytes); | |
13667 | } | |
13668 | inline void | |
13669 | ContextAllocPolicy::free(void *p) | |
13670 | { | |
13671 | cx->free(p); | |
13672 | } | |
13673 | inline void * | |
13674 | ContextAllocPolicy::realloc(void *p, size_t bytes) | |
13675 | { | |
13676 | return cx->realloc(p, bytes); | |
13677 | } | |
13678 | inline void | |
13679 | ContextAllocPolicy::reportAllocOverflow() const | |
13680 | { | |
13681 | js_ReportAllocationOverflow(cx); | |
13682 | } | |
13683 | template<class T> | |
13684 | class AutoVectorRooter : protected AutoGCRooter | |
13685 | { | |
13686 | public: | |
13687 | explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag | |
13688 | ) | |
13689 | : AutoGCRooter(cx, tag), vector(cx) | |
13690 | { | |
13691 | do { } while (0); | |
13692 | } | |
13693 | size_t length() const { return vector.length(); } | |
13694 | bool append(const T &v) { return vector.append(v); } | |
13695 | void popBack() { vector.popBack(); } | |
13696 | bool growBy(size_t inc) { | |
13697 | size_t oldLength = vector.length(); | |
13698 | if (!vector.growByUninitialized(inc)) | |
13699 | return false; | |
13700 | MakeRangeGCSafe(vector.begin() + oldLength, vector.end()); | |
13701 | return true; | |
13702 | } | |
13703 | bool resize(size_t newLength) { | |
13704 | size_t oldLength = vector.length(); | |
13705 | if (newLength <= oldLength) { | |
13706 | vector.shrinkBy(oldLength - newLength); | |
13707 | return true; | |
13708 | } | |
13709 | if (!vector.growByUninitialized(newLength - oldLength)) | |
13710 | return false; | |
13711 | MakeRangeGCSafe(vector.begin() + oldLength, vector.end()); | |
13712 | return true; | |
13713 | } | |
13714 | bool reserve(size_t newLength) { | |
13715 | return vector.reserve(newLength); | |
13716 | } | |
13717 | T &operator[](size_t i) { return vector[i]; } | |
13718 | const T &operator[](size_t i) const { return vector[i]; } | |
13719 | const T *begin() const { return vector.begin(); } | |
13720 | T *begin() { return vector.begin(); } | |
13721 | const T *end() const { return vector.end(); } | |
13722 | T *end() { return vector.end(); } | |
13723 | const T &back() const { return vector.back(); } | |
13724 | friend void AutoGCRooter::trace(JSTracer *trc); | |
13725 | private: | |
13726 | Vector<T, 8> vector; | |
13727 | ||
13728 | }; | |
13729 | class AutoValueVector : public AutoVectorRooter<Value> | |
13730 | { | |
13731 | public: | |
13732 | explicit AutoValueVector(JSContext *cx | |
13733 | ) | |
13734 | : AutoVectorRooter<Value>(cx, VALVECTOR) | |
13735 | { | |
13736 | do { } while (0); | |
13737 | } | |
13738 | const jsval *jsval_begin() const { return Jsvalify(begin()); } | |
13739 | jsval *jsval_begin() { return Jsvalify(begin()); } | |
13740 | const jsval *jsval_end() const { return Jsvalify(end()); } | |
13741 | jsval *jsval_end() { return Jsvalify(end()); } | |
13742 | ||
13743 | }; | |
13744 | class AutoIdVector : public AutoVectorRooter<jsid> | |
13745 | { | |
13746 | public: | |
13747 | explicit AutoIdVector(JSContext *cx | |
13748 | ) | |
13749 | : AutoVectorRooter<jsid>(cx, IDVECTOR) | |
13750 | { | |
13751 | do { } while (0); | |
13752 | } | |
13753 | ||
13754 | }; | |
13755 | class AutoShapeVector : public AutoVectorRooter<const Shape *> | |
13756 | { | |
13757 | public: | |
13758 | explicit AutoShapeVector(JSContext *cx | |
13759 | ) | |
13760 | : AutoVectorRooter<const Shape *>(cx, SHAPEVECTOR) | |
13761 | { | |
13762 | do { } while (0); | |
13763 | } | |
13764 | ||
13765 | }; | |
13766 | JSIdArray * | |
13767 | NewIdArray(JSContext *cx, jsint length); | |
13768 | } | |
13769 | typedef union jsdpun { | |
13770 | struct { | |
13771 | uint32 hi, lo; | |
13772 | } s; | |
13773 | uint64 u64; | |
13774 | jsdouble d; | |
13775 | } jsdpun; | |
13776 | static inline int | |
13777 | JSDOUBLE_IS_NaN(jsdouble d) | |
13778 | { | |
13779 | return (sizeof (d) == sizeof (float) ? __isnanf (d) : sizeof (d) == sizeof (double) ? __isnan (d) : __isnanl (d)); | |
13780 | } | |
13781 | static inline int | |
13782 | JSDOUBLE_IS_FINITE(jsdouble d) | |
13783 | { | |
13784 | return finite(d); | |
13785 | } | |
13786 | static inline int | |
13787 | JSDOUBLE_IS_INFINITE(jsdouble d) | |
13788 | { | |
13789 | return (sizeof (d) == sizeof (float) ? __isinff (d) : sizeof (d) == sizeof (double) ? __isinf (d) : __isinfl (d)); | |
13790 | } | |
13791 | static inline | |
13792 | bool | |
13793 | JSDOUBLE_IS_NEG(jsdouble d) | |
13794 | { | |
13795 | return (sizeof (d) == sizeof (float) ? __signbitf (d) : sizeof (d) == sizeof (double) ? __signbit (d) : __signbitl (d)); | |
13796 | } | |
13797 | static inline uint32 | |
13798 | JS_HASH_DOUBLE(jsdouble d) | |
13799 | { | |
13800 | jsdpun u; | |
13801 | u.d = d; | |
13802 | return u.s.lo ^ u.s.hi; | |
13803 | } | |
13804 | extern jsdouble js_NaN; | |
13805 | extern jsdouble js_PositiveInfinity; | |
13806 | extern jsdouble js_NegativeInfinity; | |
13807 | extern JSBool | |
13808 | js_InitRuntimeNumberState(JSContext *cx); | |
13809 | extern void | |
13810 | js_FinishRuntimeNumberState(JSContext *cx); | |
13811 | extern js::Class js_NumberClass; | |
13812 | inline | |
13813 | bool | |
13814 | JSObject::isNumber() const | |
13815 | { | |
13816 | return getClass() == &js_NumberClass; | |
13817 | } | |
13818 | extern JSObject * | |
13819 | js_InitNumberClass(JSContext *cx, JSObject *obj); | |
13820 | extern const char js_Infinity_str[]; | |
13821 | extern const char js_NaN_str[]; | |
13822 | extern const char js_isNaN_str[]; | |
13823 | extern const char js_isFinite_str[]; | |
13824 | extern const char js_parseFloat_str[]; | |
13825 | extern const char js_parseInt_str[]; | |
13826 | extern JSString * | |
13827 | js_IntToString(JSContext *cx, jsint i); | |
13828 | extern JSString * | |
13829 | js_NumberToString(JSContext *cx, jsdouble d); | |
13830 | namespace js { | |
13831 | extern bool | |
13832 | NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb); | |
13833 | extern JSFlatString * | |
13834 | NumberToString(JSContext *cx, jsdouble d); | |
13835 | struct ToCStringBuf | |
13836 | { | |
13837 | static const size_t sbufSize = 34; | |
13838 | char sbuf[sbufSize]; | |
13839 | char *dbuf; | |
13840 | ToCStringBuf(); | |
13841 | ~ToCStringBuf(); | |
13842 | }; | |
13843 | extern char * | |
13844 | NumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base = 10); | |
13845 | const double DOUBLE_INTEGRAL_PRECISION_LIMIT = uint64(1) << 53; | |
13846 | extern | |
13847 | bool | |
13848 | GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base, | |
13849 | const jschar **endp, jsdouble *dp); | |
13850 | __attribute__((always_inline)) inline | |
13851 | bool | |
13852 | ValueToNumber(JSContext *cx, const js::Value &v, double *out) | |
13853 | { | |
13854 | if (v.isNumber()) { | |
13855 | *out = v.toNumber(); | |
13856 | return true; | |
13857 | } | |
13858 | extern bool ValueToNumberSlow(JSContext *, js::Value, double *); | |
13859 | return ValueToNumberSlow(cx, v, out); | |
13860 | } | |
13861 | __attribute__((always_inline)) inline | |
13862 | bool | |
13863 | ValueToNumber(JSContext *cx, js::Value *vp) | |
13864 | { | |
13865 | if (vp->isNumber()) | |
13866 | return true; | |
13867 | double d; | |
13868 | extern bool ValueToNumberSlow(JSContext *, js::Value, double *); | |
13869 | if (!ValueToNumberSlow(cx, *vp, &d)) | |
13870 | return false; | |
13871 | vp->setNumber(d); | |
13872 | return true; | |
13873 | } | |
13874 | __attribute__((always_inline)) inline | |
13875 | bool | |
13876 | ValueToECMAInt32(JSContext *cx, const js::Value &v, int32_t *out) | |
13877 | { | |
13878 | if (v.isInt32()) { | |
13879 | *out = v.toInt32(); | |
13880 | return true; | |
13881 | } | |
13882 | extern bool ValueToECMAInt32Slow(JSContext *, const js::Value &, int32_t *); | |
13883 | return ValueToECMAInt32Slow(cx, v, out); | |
13884 | } | |
13885 | __attribute__((always_inline)) inline | |
13886 | bool | |
13887 | ValueToECMAUint32(JSContext *cx, const js::Value &v, uint32_t *out) | |
13888 | { | |
13889 | if (v.isInt32()) { | |
13890 | *out = (uint32_t)v.toInt32(); | |
13891 | return true; | |
13892 | } | |
13893 | extern bool ValueToECMAUint32Slow(JSContext *, const js::Value &, uint32_t *); | |
13894 | return ValueToECMAUint32Slow(cx, v, out); | |
13895 | } | |
13896 | __attribute__((always_inline)) inline | |
13897 | bool | |
13898 | ValueToInt32(JSContext *cx, const js::Value &v, int32_t *out) | |
13899 | { | |
13900 | if (v.isInt32()) { | |
13901 | *out = v.toInt32(); | |
13902 | return true; | |
13903 | } | |
13904 | extern bool ValueToInt32Slow(JSContext *, const js::Value &, int32_t *); | |
13905 | return ValueToInt32Slow(cx, v, out); | |
13906 | } | |
13907 | __attribute__((always_inline)) inline | |
13908 | bool | |
13909 | ValueToUint16(JSContext *cx, const js::Value &v, uint16_t *out) | |
13910 | { | |
13911 | if (v.isInt32()) { | |
13912 | *out = (uint16_t)v.toInt32(); | |
13913 | return true; | |
13914 | } | |
13915 | extern bool ValueToUint16Slow(JSContext *, const js::Value &, uint16_t *); | |
13916 | return ValueToUint16Slow(cx, v, out); | |
13917 | } | |
13918 | } | |
13919 | static inline int32 | |
13920 | js_DoubleToECMAInt32(jsdouble d) | |
13921 | { | |
13922 | int32 i; | |
13923 | jsdouble two32, two31; | |
13924 | if (!JSDOUBLE_IS_FINITE(d)) | |
13925 | return 0; | |
13926 | i = (int32) d; | |
13927 | if ((jsdouble) i == d) | |
13928 | return i; | |
13929 | two32 = 4294967296.0; | |
13930 | two31 = 2147483648.0; | |
13931 | d = fmod(d, two32); | |
13932 | d = (d >= 0) ? floor(d) : ceil(d) + two32; | |
13933 | return (int32) (d >= two31 ? d - two32 : d); | |
13934 | } | |
13935 | uint32 | |
13936 | js_DoubleToECMAUint32(jsdouble d); | |
13937 | static inline jsdouble | |
13938 | js_DoubleToInteger(jsdouble d) | |
13939 | { | |
13940 | if (d == 0) | |
13941 | return d; | |
13942 | if (!JSDOUBLE_IS_FINITE(d)) { | |
13943 | if (JSDOUBLE_IS_NaN(d)) | |
13944 | return 0; | |
13945 | return d; | |
13946 | } | |
13947 | JSBool neg = (d < 0); | |
13948 | d = floor(neg ? -d : d); | |
13949 | return neg ? -d : d; | |
13950 | } | |
13951 | extern JSBool | |
13952 | js_strtod(JSContext *cx, const jschar *s, const jschar *send, | |
13953 | const jschar **ep, jsdouble *dp); | |
13954 | extern JSBool | |
13955 | js_num_valueOf(JSContext *cx, uintN argc, js::Value *vp); | |
13956 | namespace js { | |
13957 | static __attribute__((always_inline)) inline | |
13958 | bool | |
13959 | ValueFitsInInt32(const Value &v, int32_t *pi) | |
13960 | { | |
13961 | if (v.isInt32()) { | |
13962 | *pi = v.toInt32(); | |
13963 | return true; | |
13964 | } | |
13965 | return v.isDouble() && JSDOUBLE_IS_INT32(v.toDouble(), pi); | |
13966 | } | |
13967 | template<typename T> struct NumberTraits { }; | |
13968 | template<> struct NumberTraits<int32> { | |
13969 | static __attribute__((always_inline)) inline int32 NaN() { return 0; } | |
13970 | static __attribute__((always_inline)) inline int32 toSelfType(int32 i) { return i; } | |
13971 | static __attribute__((always_inline)) inline int32 toSelfType(jsdouble d) { return js_DoubleToECMAUint32(d); } | |
13972 | }; | |
13973 | template<> struct NumberTraits<jsdouble> { | |
13974 | static __attribute__((always_inline)) inline jsdouble NaN() { return js_NaN; } | |
13975 | static __attribute__((always_inline)) inline jsdouble toSelfType(int32 i) { return i; } | |
13976 | static __attribute__((always_inline)) inline jsdouble toSelfType(jsdouble d) { return d; } | |
13977 | }; | |
13978 | template<typename T> | |
13979 | static __attribute__((always_inline)) inline | |
13980 | bool | |
13981 | StringToNumberType(JSContext *cx, JSString *str, T *result) | |
13982 | { | |
13983 | size_t length = str->length(); | |
13984 | const jschar *chars = str->getChars(__null); | |
13985 | if (!chars) | |
13986 | return false; | |
13987 | if (length == 1) { | |
13988 | jschar c = chars[0]; | |
13989 | if ('0' <= c && c <= '9') { | |
13990 | *result = NumberTraits<T>::toSelfType(T(c - '0')); | |
13991 | return true; | |
13992 | } | |
13993 | if (JS_ISSPACE(c)) { | |
13994 | *result = NumberTraits<T>::toSelfType(T(0)); | |
13995 | return true; | |
13996 | } | |
13997 | *result = NumberTraits<T>::NaN(); | |
13998 | return true; | |
13999 | } | |
14000 | const jschar *bp = chars; | |
14001 | const jschar *end = chars + length; | |
14002 | bp = js_SkipWhiteSpace(bp, end); | |
14003 | if (end - bp >= 2 && bp[0] == '0' && (bp[1] == 'x' || bp[1] == 'X')) { | |
14004 | const jschar *endptr; | |
14005 | double d; | |
14006 | if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) || | |
14007 | js_SkipWhiteSpace(endptr, end) != end) { | |
14008 | *result = NumberTraits<T>::NaN(); | |
14009 | return true; | |
14010 | } | |
14011 | *result = NumberTraits<T>::toSelfType(d); | |
14012 | return true; | |
14013 | } | |
14014 | const jschar *ep; | |
14015 | double d; | |
14016 | if (!js_strtod(cx, bp, end, &ep, &d) || js_SkipWhiteSpace(ep, end) != end) { | |
14017 | *result = NumberTraits<T>::NaN(); | |
14018 | return true; | |
14019 | } | |
14020 | *result = NumberTraits<T>::toSelfType(d); | |
14021 | return true; | |
14022 | } | |
14023 | } | |
14024 | extern const char js_false_str[]; | |
14025 | extern const char js_true_str[]; | |
14026 | extern const char js_null_str[]; | |
14027 | extern const char js_break_str[]; | |
14028 | extern const char js_case_str[]; | |
14029 | extern const char js_catch_str[]; | |
14030 | extern const char js_continue_str[]; | |
14031 | extern const char js_debugger_str[]; | |
14032 | extern const char js_default_str[]; | |
14033 | extern const char js_delete_str[]; | |
14034 | extern const char js_do_str[]; | |
14035 | extern const char js_else_str[]; | |
14036 | extern const char js_finally_str[]; | |
14037 | extern const char js_for_str[]; | |
14038 | extern const char js_function_str[]; | |
14039 | extern const char js_if_str[]; | |
14040 | extern const char js_in_str[]; | |
14041 | extern const char js_instanceof_str[]; | |
14042 | extern const char js_new_str[]; | |
14043 | extern const char js_return_str[]; | |
14044 | extern const char js_switch_str[]; | |
14045 | extern const char js_this_str[]; | |
14046 | extern const char js_throw_str[]; | |
14047 | extern const char js_try_str[]; | |
14048 | extern const char js_typeof_str[]; | |
14049 | extern const char js_var_str[]; | |
14050 | extern const char js_void_str[]; | |
14051 | extern const char js_while_str[]; | |
14052 | extern const char js_with_str[]; | |
14053 | extern const char js_class_str[]; | |
14054 | extern const char js_enum_str[]; | |
14055 | extern const char js_export_str[]; | |
14056 | extern const char js_extends_str[]; | |
14057 | extern const char js_import_str[]; | |
14058 | extern const char js_super_str[]; | |
14059 | extern const char js_const_str[]; | |
14060 | extern const char js_let_str[]; | |
14061 | extern const char js_yield_str[]; | |
14062 | extern const char js_implements_str[]; | |
14063 | extern const char js_interface_str[]; | |
14064 | extern const char js_package_str[]; | |
14065 | extern const char js_private_str[]; | |
14066 | extern const char js_protected_str[]; | |
14067 | extern const char js_public_str[]; | |
14068 | extern const char js_static_str[]; | |
14069 | namespace js { | |
14070 | enum TokenKind { | |
14071 | TOK_ERROR = -1, | |
14072 | TOK_EOF = 0, | |
14073 | TOK_EOL = 1, | |
14074 | TOK_SEMI = 2, | |
14075 | TOK_COMMA = 3, | |
14076 | TOK_ASSIGN = 4, | |
14077 | TOK_HOOK = 5, TOK_COLON = 6, | |
14078 | TOK_OR = 7, | |
14079 | TOK_AND = 8, | |
14080 | TOK_BITOR = 9, | |
14081 | TOK_BITXOR = 10, | |
14082 | TOK_BITAND = 11, | |
14083 | TOK_EQOP = 12, | |
14084 | TOK_RELOP = 13, | |
14085 | TOK_SHOP = 14, | |
14086 | TOK_PLUS = 15, | |
14087 | TOK_MINUS = 16, | |
14088 | TOK_STAR = 17, TOK_DIVOP = 18, | |
14089 | TOK_UNARYOP = 19, | |
14090 | TOK_INC = 20, TOK_DEC = 21, | |
14091 | TOK_DOT = 22, | |
14092 | TOK_LB = 23, TOK_RB = 24, | |
14093 | TOK_LC = 25, TOK_RC = 26, | |
14094 | TOK_LP = 27, TOK_RP = 28, | |
14095 | TOK_NAME = 29, | |
14096 | TOK_NUMBER = 30, | |
14097 | TOK_STRING = 31, | |
14098 | TOK_REGEXP = 32, | |
14099 | TOK_PRIMARY = 33, | |
14100 | TOK_FUNCTION = 34, | |
14101 | TOK_IF = 35, | |
14102 | TOK_ELSE = 36, | |
14103 | TOK_SWITCH = 37, | |
14104 | TOK_CASE = 38, | |
14105 | TOK_DEFAULT = 39, | |
14106 | TOK_WHILE = 40, | |
14107 | TOK_DO = 41, | |
14108 | TOK_FOR = 42, | |
14109 | TOK_BREAK = 43, | |
14110 | TOK_CONTINUE = 44, | |
14111 | TOK_IN = 45, | |
14112 | TOK_VAR = 46, | |
14113 | TOK_WITH = 47, | |
14114 | TOK_RETURN = 48, | |
14115 | TOK_NEW = 49, | |
14116 | TOK_DELETE = 50, | |
14117 | TOK_DEFSHARP = 51, | |
14118 | TOK_USESHARP = 52, | |
14119 | TOK_TRY = 53, | |
14120 | TOK_CATCH = 54, | |
14121 | TOK_FINALLY = 55, | |
14122 | TOK_THROW = 56, | |
14123 | TOK_INSTANCEOF = 57, | |
14124 | TOK_DEBUGGER = 58, | |
14125 | TOK_XMLSTAGO = 59, | |
14126 | TOK_XMLETAGO = 60, | |
14127 | TOK_XMLPTAGC = 61, | |
14128 | TOK_XMLTAGC = 62, | |
14129 | TOK_XMLNAME = 63, | |
14130 | TOK_XMLATTR = 64, | |
14131 | TOK_XMLSPACE = 65, | |
14132 | TOK_XMLTEXT = 66, | |
14133 | TOK_XMLCOMMENT = 67, | |
14134 | TOK_XMLCDATA = 68, | |
14135 | TOK_XMLPI = 69, | |
14136 | TOK_AT = 70, | |
14137 | TOK_DBLCOLON = 71, | |
14138 | TOK_ANYNAME = 72, | |
14139 | TOK_DBLDOT = 73, | |
14140 | TOK_FILTER = 74, | |
14141 | TOK_XMLELEM = 75, | |
14142 | TOK_XMLLIST = 76, | |
14143 | TOK_YIELD = 77, | |
14144 | TOK_ARRAYCOMP = 78, | |
14145 | TOK_ARRAYPUSH = 79, | |
14146 | TOK_LEXICALSCOPE = 80, | |
14147 | TOK_LET = 81, | |
14148 | TOK_SEQ = 82, | |
14149 | TOK_FORHEAD = 83, | |
14150 | TOK_ARGSBODY = 84, | |
14151 | TOK_UPVARS = 85, | |
14152 | TOK_RESERVED, | |
14153 | TOK_STRICT_RESERVED, | |
14154 | TOK_LIMIT | |
14155 | }; | |
14156 | static inline | |
14157 | bool | |
14158 | TokenKindIsXML(TokenKind tt) | |
14159 | { | |
14160 | return tt == TOK_AT || tt == TOK_DBLCOLON || tt == TOK_ANYNAME; | |
14161 | } | |
14162 | static inline | |
14163 | bool | |
14164 | TreeTypeIsXML(TokenKind tt) | |
14165 | { | |
14166 | return tt == TOK_XMLCOMMENT || tt == TOK_XMLCDATA || tt == TOK_XMLPI || | |
14167 | tt == TOK_XMLELEM || tt == TOK_XMLLIST; | |
14168 | } | |
14169 | static inline | |
14170 | bool | |
14171 | TokenKindIsDecl(TokenKind tt) | |
14172 | { | |
14173 | return tt == TOK_VAR || tt == TOK_LET; | |
14174 | } | |
14175 | struct TokenPtr { | |
14176 | uint32 index; | |
14177 | uint32 lineno; | |
14178 | bool operator==(const TokenPtr& bptr) { | |
14179 | return index == bptr.index && lineno == bptr.lineno; | |
14180 | } | |
14181 | bool operator!=(const TokenPtr& bptr) { | |
14182 | return index != bptr.index || lineno != bptr.lineno; | |
14183 | } | |
14184 | bool operator <(const TokenPtr& bptr) { | |
14185 | return lineno < bptr.lineno || | |
14186 | (lineno == bptr.lineno && index < bptr.index); | |
14187 | } | |
14188 | bool operator <=(const TokenPtr& bptr) { | |
14189 | return lineno < bptr.lineno || | |
14190 | (lineno == bptr.lineno && index <= bptr.index); | |
14191 | } | |
14192 | bool operator >(const TokenPtr& bptr) { | |
14193 | return !(*this <= bptr); | |
14194 | } | |
14195 | bool operator >=(const TokenPtr& bptr) { | |
14196 | return !(*this < bptr); | |
14197 | } | |
14198 | }; | |
14199 | struct TokenPos { | |
14200 | TokenPtr begin; | |
14201 | TokenPtr end; | |
14202 | bool operator==(const TokenPos& bpos) { | |
14203 | return begin == bpos.begin && end == bpos.end; | |
14204 | } | |
14205 | bool operator!=(const TokenPos& bpos) { | |
14206 | return begin != bpos.begin || end != bpos.end; | |
14207 | } | |
14208 | bool operator <(const TokenPos& bpos) { | |
14209 | return begin < bpos.begin; | |
14210 | } | |
14211 | bool operator <=(const TokenPos& bpos) { | |
14212 | return begin <= bpos.begin; | |
14213 | } | |
14214 | bool operator >(const TokenPos& bpos) { | |
14215 | return !(*this <= bpos); | |
14216 | } | |
14217 | bool operator >=(const TokenPos& bpos) { | |
14218 | return !(*this < bpos); | |
14219 | } | |
14220 | }; | |
14221 | struct Token { | |
14222 | TokenKind type; | |
14223 | TokenPos pos; | |
14224 | jschar *ptr; | |
14225 | union { | |
14226 | struct { | |
14227 | JSOp op; | |
14228 | JSAtom *atom; | |
14229 | } s; | |
14230 | uintN reflags; | |
14231 | struct { | |
14232 | JSAtom *atom2; | |
14233 | JSAtom *atom; | |
14234 | } p; | |
14235 | jsdouble dval; | |
14236 | } u; | |
14237 | }; | |
14238 | enum TokenStreamFlags | |
14239 | { | |
14240 | TSF_ERROR = 0x01, | |
14241 | TSF_EOF = 0x02, | |
14242 | TSF_NEWLINES = 0x04, | |
14243 | TSF_OPERAND = 0x08, | |
14244 | TSF_UNEXPECTED_EOF = 0x10, | |
14245 | TSF_KEYWORD_IS_NAME = 0x20, | |
14246 | TSF_STRICT_MODE_CODE = 0x40, | |
14247 | TSF_DIRTYLINE = 0x80, | |
14248 | TSF_OWNFILENAME = 0x100, | |
14249 | TSF_XMLTAGMODE = 0x200, | |
14250 | TSF_XMLTEXTMODE = 0x400, | |
14251 | TSF_XMLONLYMODE = 0x800, | |
14252 | TSF_OCTAL_CHAR = 0x1000, | |
14253 | TSF_IN_HTML_COMMENT = 0x2000 | |
14254 | }; | |
14255 | class TokenStream | |
14256 | { | |
14257 | static const size_t ntokens = 4; | |
14258 | static const uintN ntokensMask = ntokens - 1; | |
14259 | public: | |
14260 | typedef Vector<jschar, 32> CharBuffer; | |
14261 | TokenStream(JSContext *); | |
14262 | bool init(const jschar *base, size_t length, const char *filename, uintN lineno, | |
14263 | JSVersion version); | |
14264 | void close(); | |
14265 | ~TokenStream() {} | |
14266 | JSContext *getContext() const { return cx; } | |
14267 | bool onCurrentLine(const TokenPos &pos) const { return lineno == pos.end.lineno; } | |
14268 | const Token ¤tToken() const { return tokens[cursor]; } | |
14269 | const CharBuffer &getTokenbuf() const { return tokenbuf; } | |
14270 | const char *getFilename() const { return filename; } | |
14271 | uintN getLineno() const { return lineno; } | |
14272 | JSVersion versionNumber() const { return VersionNumber(version); } | |
14273 | JSVersion versionWithFlags() const { return version; } | |
14274 | bool hasAnonFunFix() const { return VersionHasAnonFunFix(version); } | |
14275 | bool hasXML() const { return xml || VersionShouldParseXML(versionNumber()); } | |
14276 | void setXML(bool enabled) { xml = enabled; } | |
14277 | void setStrictMode(bool enabled = true) { setFlag(enabled, TSF_STRICT_MODE_CODE); } | |
14278 | void setXMLTagMode(bool enabled = true) { setFlag(enabled, TSF_XMLTAGMODE); } | |
14279 | void setXMLOnlyMode(bool enabled = true) { setFlag(enabled, TSF_XMLONLYMODE); } | |
14280 | void setUnexpectedEOF(bool enabled = true) { setFlag(enabled, TSF_UNEXPECTED_EOF); } | |
14281 | void setOctalCharacterEscape(bool enabled = true) { setFlag(enabled, TSF_OCTAL_CHAR); } | |
14282 | bool isStrictMode() { return !!(flags & TSF_STRICT_MODE_CODE); } | |
14283 | bool isXMLTagMode() { return !!(flags & TSF_XMLTAGMODE); } | |
14284 | bool isXMLOnlyMode() { return !!(flags & TSF_XMLONLYMODE); } | |
14285 | bool isUnexpectedEOF() { return !!(flags & TSF_UNEXPECTED_EOF); } | |
14286 | bool isEOF() const { return !!(flags & TSF_EOF); } | |
14287 | bool isError() const { return !!(flags & TSF_ERROR); } | |
14288 | bool hasOctalCharacterEscape() const { return flags & TSF_OCTAL_CHAR; } | |
14289 | bool reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN errorNumber, va_list ap); | |
14290 | void mungeCurrentToken(TokenKind newKind) { tokens[cursor].type = newKind; } | |
14291 | void mungeCurrentToken(JSOp newOp) { tokens[cursor].u.s.op = newOp; } | |
14292 | void mungeCurrentToken(TokenKind newKind, JSOp newOp) { | |
14293 | mungeCurrentToken(newKind); | |
14294 | mungeCurrentToken(newOp); | |
14295 | } | |
14296 | private: | |
14297 | static JSAtom *atomize(JSContext *cx, CharBuffer &cb); | |
14298 | class Flagger { | |
14299 | TokenStream * const parent; | |
14300 | uintN flags; | |
14301 | public: | |
14302 | Flagger(TokenStream *parent, uintN withFlags) : parent(parent), flags(withFlags) { | |
14303 | parent->flags |= flags; | |
14304 | } | |
14305 | ~Flagger() { parent->flags &= ~flags; } | |
14306 | }; | |
14307 | friend class Flagger; | |
14308 | void setFlag(bool enabled, TokenStreamFlags flag) { | |
14309 | if (enabled) | |
14310 | flags |= flag; | |
14311 | else | |
14312 | flags &= ~flag; | |
14313 | } | |
14314 | public: | |
14315 | TokenKind getToken() { | |
14316 | while (lookahead != 0) { | |
14317 | ((void) 0); | |
14318 | lookahead--; | |
14319 | cursor = (cursor + 1) & ntokensMask; | |
14320 | TokenKind tt = currentToken().type; | |
14321 | ((void) 0); | |
14322 | if (tt != TOK_EOL) | |
14323 | return tt; | |
14324 | } | |
14325 | if (flags & TSF_ERROR) | |
14326 | return TOK_ERROR; | |
14327 | return getTokenInternal(); | |
14328 | } | |
14329 | TokenKind getToken(uintN withFlags) { | |
14330 | Flagger flagger(this, withFlags); | |
14331 | return getToken(); | |
14332 | } | |
14333 | void ungetToken() { | |
14334 | ((void) 0); | |
14335 | lookahead++; | |
14336 | cursor = (cursor - 1) & ntokensMask; | |
14337 | } | |
14338 | TokenKind peekToken(uintN withFlags = 0) { | |
14339 | Flagger flagger(this, withFlags); | |
14340 | if (lookahead != 0) { | |
14341 | ((void) 0); | |
14342 | return tokens[(cursor + lookahead) & ntokensMask].type; | |
14343 | } | |
14344 | TokenKind tt = getToken(); | |
14345 | ungetToken(); | |
14346 | return tt; | |
14347 | } | |
14348 | TokenKind peekTokenSameLine(uintN withFlags = 0) { | |
14349 | Flagger flagger(this, withFlags); | |
14350 | if (!onCurrentLine(currentToken().pos)) | |
14351 | return TOK_EOL; | |
14352 | TokenKind tt = peekToken(TSF_NEWLINES); | |
14353 | return tt; | |
14354 | } | |
14355 | JSBool matchToken(TokenKind tt, uintN withFlags = 0) { | |
14356 | Flagger flagger(this, withFlags); | |
14357 | if (getToken() == tt) | |
14358 | return (JSIntn)1; | |
14359 | ungetToken(); | |
14360 | return (JSIntn)0; | |
14361 | } | |
14362 | private: | |
14363 | typedef struct TokenBuf { | |
14364 | jschar *base; | |
14365 | jschar *limit; | |
14366 | jschar *ptr; | |
14367 | } TokenBuf; | |
14368 | TokenKind getTokenInternal(); | |
14369 | int32 getChar(); | |
14370 | int32 getCharIgnoreEOL(); | |
14371 | void ungetChar(int32 c); | |
14372 | void ungetCharIgnoreEOL(int32 c); | |
14373 | Token *newToken(ptrdiff_t adjust); | |
14374 | bool peekUnicodeEscape(int32 *c); | |
14375 | bool matchUnicodeEscapeIdStart(int32 *c); | |
14376 | bool matchUnicodeEscapeIdent(int32 *c); | |
14377 | JSBool peekChars(intN n, jschar *cp); | |
14378 | JSBool getXMLEntity(); | |
14379 | jschar *findEOL(); | |
14380 | JSBool matchChar(int32 expect) { | |
14381 | int32 c = getChar(); | |
14382 | if (c == expect) | |
14383 | return (JSIntn)1; | |
14384 | ungetChar(c); | |
14385 | return (JSIntn)0; | |
14386 | } | |
14387 | int32 peekChar() { | |
14388 | int32 c = getChar(); | |
14389 | ungetChar(c); | |
14390 | return c; | |
14391 | } | |
14392 | void skipChars(intN n) { | |
14393 | while (--n >= 0) | |
14394 | getChar(); | |
14395 | } | |
14396 | JSContext * const cx; | |
14397 | Token tokens[ntokens]; | |
14398 | uintN cursor; | |
14399 | uintN lookahead; | |
14400 | uintN lineno; | |
14401 | uintN flags; | |
14402 | jschar *linebase; | |
14403 | jschar *prevLinebase; | |
14404 | TokenBuf userbuf; | |
14405 | const char *filename; | |
14406 | JSSourceHandler listener; | |
14407 | void *listenerData; | |
14408 | void *listenerTSData; | |
14409 | CharBuffer tokenbuf; | |
14410 | bool maybeEOL[256]; | |
14411 | bool maybeStrSpecial[256]; | |
14412 | JSVersion version; | |
14413 | bool xml; | |
14414 | }; | |
14415 | } | |
14416 | extern void | |
14417 | js_CloseTokenStream(JSContext *cx, js::TokenStream *ts); | |
14418 | extern __attribute__((visibility ("default"))) int | |
14419 | js_fgets(char *buf, int size, FILE *file); | |
14420 | namespace js { | |
14421 | struct KeywordInfo { | |
14422 | const char *chars; | |
14423 | TokenKind tokentype; | |
14424 | JSOp op; | |
14425 | JSVersion version; | |
14426 | }; | |
14427 | extern const KeywordInfo * | |
14428 | FindKeyword(const jschar *s, size_t length); | |
14429 | } | |
14430 | typedef void (*JSMapKeywordFun)(const char *); | |
14431 | extern JSBool | |
14432 | js_IsIdentifier(JSLinearString *str); | |
14433 | namespace js { | |
14434 | bool | |
14435 | ReportCompileErrorNumber(JSContext *cx, TokenStream *ts, JSParseNode *pn, uintN flags, | |
14436 | uintN errorNumber, ...); | |
14437 | bool | |
14438 | ReportStrictModeError(JSContext *cx, TokenStream *ts, JSTreeContext *tc, JSParseNode *pn, | |
14439 | uintN errorNumber, ...); | |
14440 | } | |
14441 | extern "C" { | |
14442 | typedef enum JSParseNodeArity { | |
14443 | PN_NULLARY, | |
14444 | PN_UNARY, | |
14445 | PN_BINARY, | |
14446 | PN_TERNARY, | |
14447 | PN_FUNC, | |
14448 | PN_LIST, | |
14449 | PN_NAME, | |
14450 | PN_NAMESET | |
14451 | } JSParseNodeArity; | |
14452 | struct JSDefinition; | |
14453 | namespace js { | |
14454 | struct GlobalScope { | |
14455 | GlobalScope(JSContext *cx, JSObject *globalObj, JSCodeGenerator *cg) | |
14456 | : globalObj(globalObj), cg(cg), defs(ContextAllocPolicy(cx)) | |
14457 | { } | |
14458 | struct GlobalDef { | |
14459 | JSAtom *atom; | |
14460 | JSFunctionBox *funbox; | |
14461 | uint32 knownSlot; | |
14462 | GlobalDef() { } | |
14463 | GlobalDef(uint32 knownSlot) | |
14464 | : atom(__null), knownSlot(knownSlot) | |
14465 | { } | |
14466 | GlobalDef(JSAtom *atom, JSFunctionBox *box) : | |
14467 | atom(atom), funbox(box) | |
14468 | { } | |
14469 | }; | |
14470 | JSObject *globalObj; | |
14471 | JSCodeGenerator *cg; | |
14472 | Vector<GlobalDef, 16, ContextAllocPolicy> defs; | |
14473 | JSAtomList names; | |
14474 | }; | |
14475 | } | |
14476 | struct JSParseNode { | |
14477 | uint32 pn_type:16, | |
14478 | pn_op:8, | |
14479 | pn_arity:5, | |
14480 | pn_parens:1, | |
14481 | pn_used:1, | |
14482 | pn_defn:1; | |
14483 | js::TokenPos pn_pos; | |
14484 | int32 pn_offset; | |
14485 | JSParseNode *pn_next; | |
14486 | JSParseNode *pn_link; | |
14487 | union { | |
14488 | struct { | |
14489 | JSParseNode *head; | |
14490 | JSParseNode **tail; | |
14491 | uint32 count; | |
14492 | uint32 xflags:12, | |
14493 | blockid:20; | |
14494 | } list; | |
14495 | struct { | |
14496 | JSParseNode *kid1; | |
14497 | JSParseNode *kid2; | |
14498 | JSParseNode *kid3; | |
14499 | } ternary; | |
14500 | struct { | |
14501 | JSParseNode *left; | |
14502 | JSParseNode *right; | |
14503 | js::Value *pval; | |
14504 | uintN iflags; | |
14505 | } binary; | |
14506 | struct { | |
14507 | JSParseNode *kid; | |
14508 | jsint num; | |
14509 | JSBool hidden; | |
14510 | } unary; | |
14511 | struct { | |
14512 | union { | |
14513 | JSAtom *atom; | |
14514 | JSFunctionBox *funbox; | |
14515 | JSObjectBox *objbox; | |
14516 | }; | |
14517 | union { | |
14518 | JSParseNode *expr; | |
14519 | JSDefinition *lexdef; | |
14520 | }; | |
14521 | js::UpvarCookie cookie; | |
14522 | uint32 dflags:12, | |
14523 | blockid:20; | |
14524 | } name; | |
14525 | struct { | |
14526 | JSAtomSet names; | |
14527 | JSParseNode *tree; | |
14528 | } nameset; | |
14529 | struct { | |
14530 | JSAtom *atom; | |
14531 | JSAtom *atom2; | |
14532 | } apair; | |
14533 | jsdouble dval; | |
14534 | } pn_u; | |
14535 | protected: | |
14536 | void inline init(js::TokenKind type, JSOp op, JSParseNodeArity arity) { | |
14537 | pn_type = type; | |
14538 | pn_op = op; | |
14539 | pn_arity = arity; | |
14540 | pn_parens = false; | |
14541 | ((void) 0); | |
14542 | ((void) 0); | |
14543 | pn_next = pn_link = __null; | |
14544 | } | |
14545 | static JSParseNode *create(JSParseNodeArity arity, JSTreeContext *tc); | |
14546 | public: | |
14547 | static JSParseNode *newBinaryOrAppend(js::TokenKind tt, JSOp op, JSParseNode *left, | |
14548 | JSParseNode *right, JSTreeContext *tc); | |
14549 | JSParseNode *expr() const { | |
14550 | ((void) 0); | |
14551 | ((void) 0); | |
14552 | return pn_u.name.expr; | |
14553 | } | |
14554 | JSDefinition *lexdef() const { | |
14555 | ((void) 0); | |
14556 | ((void) 0); | |
14557 | return pn_u.name.lexdef; | |
14558 | } | |
14559 | JSParseNode *maybeExpr() { return pn_used ? __null : expr(); } | |
14560 | JSDefinition *maybeLexDef() { return pn_used ? lexdef() : __null; } | |
14561 | uintN frameLevel() const { | |
14562 | ((void) 0); | |
14563 | return pn_u.name.cookie.level(); | |
14564 | } | |
14565 | uintN frameSlot() const { | |
14566 | ((void) 0); | |
14567 | return pn_u.name.cookie.slot(); | |
14568 | } | |
14569 | inline bool test(uintN flag) const; | |
14570 | bool isLet() const { return test(0x01); } | |
14571 | bool isConst() const { return test(0x02); } | |
14572 | bool isInitialized() const { return test(0x04); } | |
14573 | bool isBlockChild() const { return test(0x20); } | |
14574 | bool isPlaceholder() const { return test(0x80); } | |
14575 | bool isDeoptimized() const { return test(0x400); } | |
14576 | bool isAssigned() const { return test(0x08); } | |
14577 | bool isFunArg() const { return test(0x100); } | |
14578 | bool isClosed() const { return test(0x800); } | |
14579 | bool isTopLevel() const { return test(0x10); } | |
14580 | void setFunArg(); | |
14581 | void become(JSParseNode *pn2); | |
14582 | void clear(); | |
14583 | bool isLiteral() const { | |
14584 | return ((js::TokenKind)(this)->pn_type) == js::TOK_NUMBER || | |
14585 | ((js::TokenKind)(this)->pn_type) == js::TOK_STRING || | |
14586 | (((js::TokenKind)(this)->pn_type) == js::TOK_PRIMARY && ((JSOp)(this)->pn_op) != JSOP_THIS); | |
14587 | } | |
14588 | bool isStringExprStatement() const { | |
14589 | if (((js::TokenKind)(this)->pn_type) == js::TOK_SEMI) { | |
14590 | ((void) 0); | |
14591 | JSParseNode *kid = pn_u.unary.kid; | |
14592 | return kid && ((js::TokenKind)(kid)->pn_type) == js::TOK_STRING && !kid->pn_parens; | |
14593 | } | |
14594 | return false; | |
14595 | } | |
14596 | bool isEscapeFreeStringLiteral() const { | |
14597 | ((void) 0); | |
14598 | JSString *str = (pn_u.name.atom); | |
14599 | return (pn_pos.begin.lineno == pn_pos.end.lineno && | |
14600 | pn_pos.begin.index + str->length() + 2 == pn_pos.end.index); | |
14601 | } | |
14602 | bool isDirectivePrologueMember() const { return pn_u.unary.hidden; } | |
14603 | bool isGeneratorExpr() const { | |
14604 | if (((js::TokenKind)(this)->pn_type) == js::TOK_LP) { | |
14605 | JSParseNode *callee = this->pn_u.list.head; | |
14606 | if (((js::TokenKind)(callee)->pn_type) == js::TOK_FUNCTION) { | |
14607 | JSParseNode *body = (((js::TokenKind)(callee->pn_u.name.expr)->pn_type) == js::TOK_UPVARS) | |
14608 | ? callee->pn_u.name.expr->pn_u.nameset.tree | |
14609 | : callee->pn_u.name.expr; | |
14610 | if (((js::TokenKind)(body)->pn_type) == js::TOK_LEXICALSCOPE) | |
14611 | return true; | |
14612 | } | |
14613 | } | |
14614 | return false; | |
14615 | } | |
14616 | JSParseNode *generatorExpr() const { | |
14617 | ((void) 0); | |
14618 | JSParseNode *callee = this->pn_u.list.head; | |
14619 | JSParseNode *body = ((js::TokenKind)(callee->pn_u.name.expr)->pn_type) == js::TOK_UPVARS | |
14620 | ? callee->pn_u.name.expr->pn_u.nameset.tree | |
14621 | : callee->pn_u.name.expr; | |
14622 | ((void) 0); | |
14623 | return body->pn_u.name.expr; | |
14624 | } | |
14625 | JSParseNode *last() const { | |
14626 | ((void) 0); | |
14627 | ((void) 0); | |
14628 | return (JSParseNode *)((char *)pn_u.list.tail - __builtin_offsetof (JSParseNode, pn_next)); | |
14629 | } | |
14630 | void makeEmpty() { | |
14631 | ((void) 0); | |
14632 | pn_u.list.head = __null; | |
14633 | pn_u.list.tail = &pn_u.list.head; | |
14634 | pn_u.list.count = 0; | |
14635 | pn_u.list.xflags = 0; | |
14636 | pn_u.name.blockid = 0; | |
14637 | } | |
14638 | void initList(JSParseNode *pn) { | |
14639 | ((void) 0); | |
14640 | pn_u.list.head = pn; | |
14641 | pn_u.list.tail = &pn->pn_next; | |
14642 | pn_u.list.count = 1; | |
14643 | pn_u.list.xflags = 0; | |
14644 | pn_u.name.blockid = 0; | |
14645 | } | |
14646 | void append(JSParseNode *pn) { | |
14647 | ((void) 0); | |
14648 | *pn_u.list.tail = pn; | |
14649 | pn_u.list.tail = &pn->pn_next; | |
14650 | pn_u.list.count++; | |
14651 | } | |
14652 | bool getConstantValue(JSContext *cx, bool strictChecks, js::Value *vp); | |
14653 | inline bool isConstant(); | |
14654 | }; | |
14655 | namespace js { | |
14656 | struct NullaryNode : public JSParseNode { | |
14657 | static inline NullaryNode *create(JSTreeContext *tc) { | |
14658 | return (NullaryNode *)JSParseNode::create(PN_NULLARY, tc); | |
14659 | } | |
14660 | }; | |
14661 | struct UnaryNode : public JSParseNode { | |
14662 | static inline UnaryNode *create(JSTreeContext *tc) { | |
14663 | return (UnaryNode *)JSParseNode::create(PN_UNARY, tc); | |
14664 | } | |
14665 | }; | |
14666 | struct BinaryNode : public JSParseNode { | |
14667 | static inline BinaryNode *create(JSTreeContext *tc) { | |
14668 | return (BinaryNode *)JSParseNode::create(PN_BINARY, tc); | |
14669 | } | |
14670 | }; | |
14671 | struct TernaryNode : public JSParseNode { | |
14672 | static inline TernaryNode *create(JSTreeContext *tc) { | |
14673 | return (TernaryNode *)JSParseNode::create(PN_TERNARY, tc); | |
14674 | } | |
14675 | }; | |
14676 | struct ListNode : public JSParseNode { | |
14677 | static inline ListNode *create(JSTreeContext *tc) { | |
14678 | return (ListNode *)JSParseNode::create(PN_LIST, tc); | |
14679 | } | |
14680 | }; | |
14681 | struct FunctionNode : public JSParseNode { | |
14682 | static inline FunctionNode *create(JSTreeContext *tc) { | |
14683 | return (FunctionNode *)JSParseNode::create(PN_FUNC, tc); | |
14684 | } | |
14685 | }; | |
14686 | struct NameNode : public JSParseNode { | |
14687 | static NameNode *create(JSAtom *atom, JSTreeContext *tc); | |
14688 | void inline initCommon(JSTreeContext *tc); | |
14689 | }; | |
14690 | struct NameSetNode : public JSParseNode { | |
14691 | static inline NameSetNode *create(JSTreeContext *tc) { | |
14692 | return (NameSetNode *)JSParseNode::create(PN_NAMESET, tc); | |
14693 | } | |
14694 | }; | |
14695 | struct LexicalScopeNode : public JSParseNode { | |
14696 | static inline LexicalScopeNode *create(JSTreeContext *tc) { | |
14697 | return (LexicalScopeNode *)JSParseNode::create(PN_NAME, tc); | |
14698 | } | |
14699 | }; | |
14700 | } | |
14701 | struct JSDefinition : public JSParseNode | |
14702 | { | |
14703 | JSDefinition *resolve() { | |
14704 | JSParseNode *pn = this; | |
14705 | while (!pn->pn_defn) { | |
14706 | if (pn->pn_type == js::TOK_ASSIGN) { | |
14707 | pn = pn->pn_u.binary.left; | |
14708 | continue; | |
14709 | } | |
14710 | pn = pn->lexdef(); | |
14711 | } | |
14712 | return (JSDefinition *) pn; | |
14713 | } | |
14714 | bool isFreeVar() const { | |
14715 | ((void) 0); | |
14716 | return pn_u.name.cookie.isFree() || test(0x40); | |
14717 | } | |
14718 | bool isGlobal() const { | |
14719 | ((void) 0); | |
14720 | return test(0x40); | |
14721 | } | |
14722 | enum Kind { VAR, CONST, LET, FUNCTION, ARG, UNKNOWN }; | |
14723 | bool isBindingForm() { return int(kind()) <= int(LET); } | |
14724 | static const char *kindString(Kind kind); | |
14725 | Kind kind() { | |
14726 | if (((js::TokenKind)(this)->pn_type) == js::TOK_FUNCTION) | |
14727 | return FUNCTION; | |
14728 | ((void) 0); | |
14729 | if (((JSOp)(this)->pn_op) == JSOP_NOP) | |
14730 | return UNKNOWN; | |
14731 | if (((JSOp)(this)->pn_op) == JSOP_GETARG) | |
14732 | return ARG; | |
14733 | if (isConst()) | |
14734 | return CONST; | |
14735 | if (isLet()) | |
14736 | return LET; | |
14737 | return VAR; | |
14738 | } | |
14739 | }; | |
14740 | inline | |
14741 | bool | |
14742 | JSParseNode::test(uintN flag) const | |
14743 | { | |
14744 | ((void) 0); | |
14745 | return !!(pn_u.name.dflags & flag); | |
14746 | } | |
14747 | inline void | |
14748 | JSParseNode::setFunArg() | |
14749 | { | |
14750 | ((void) 0); | |
14751 | if (pn_used) | |
14752 | pn_u.name.lexdef->pn_u.name.dflags |= 0x100; | |
14753 | pn_u.name.dflags |= 0x100; | |
14754 | } | |
14755 | struct JSObjectBox { | |
14756 | JSObjectBox *traceLink; | |
14757 | JSObjectBox *emitLink; | |
14758 | JSObject *object; | |
14759 | JSObjectBox *parent; | |
14760 | uintN index; | |
14761 | bool isFunctionBox; | |
14762 | }; | |
14763 | struct JSFunctionBox : public JSObjectBox | |
14764 | { | |
14765 | JSParseNode *node; | |
14766 | JSFunctionBox *siblings; | |
14767 | JSFunctionBox *kids; | |
14768 | JSFunctionBox *parent; | |
14769 | JSParseNode *methods; | |
14770 | js::Bindings bindings; | |
14771 | uint32 queued:1, | |
14772 | inLoop:1, | |
14773 | level:14; | |
14774 | uint32 tcflags; | |
14775 | bool joinable() const; | |
14776 | bool inAnyDynamicScope() const; | |
14777 | bool shouldUnbrand(uintN methods, uintN slowMethods) const; | |
14778 | }; | |
14779 | struct JSFunctionBoxQueue { | |
14780 | JSFunctionBox **vector; | |
14781 | size_t head, tail; | |
14782 | size_t lengthMask; | |
14783 | size_t count() { return head - tail; } | |
14784 | size_t length() { return lengthMask + 1; } | |
14785 | JSFunctionBoxQueue() | |
14786 | : vector(__null), head(0), tail(0), lengthMask(0) { } | |
14787 | bool init(uint32 count) { | |
14788 | lengthMask = (((JSUint32)1 << (JS_CeilingLog2(count))) - 1); | |
14789 | vector = js_array_new<JSFunctionBox*>(length()); | |
14790 | return !!vector; | |
14791 | } | |
14792 | ~JSFunctionBoxQueue() { js_array_delete(vector); } | |
14793 | void push(JSFunctionBox *funbox) { | |
14794 | if (!funbox->queued) { | |
14795 | ((void) 0); | |
14796 | vector[head++ & lengthMask] = funbox; | |
14797 | funbox->queued = true; | |
14798 | } | |
14799 | } | |
14800 | JSFunctionBox *pull() { | |
14801 | if (tail == head) | |
14802 | return __null; | |
14803 | ((void) 0); | |
14804 | JSFunctionBox *funbox = vector[tail++ & lengthMask]; | |
14805 | funbox->queued = false; | |
14806 | return funbox; | |
14807 | } | |
14808 | }; | |
14809 | typedef struct BindData BindData; | |
14810 | namespace js { | |
14811 | struct Parser : private js::AutoGCRooter | |
14812 | { | |
14813 | JSContext * const context; | |
14814 | JSAtomListElement *aleFreeList; | |
14815 | void *tempFreeList[6U]; | |
14816 | TokenStream tokenStream; | |
14817 | void *tempPoolMark; | |
14818 | JSPrincipals *principals; | |
14819 | JSStackFrame *const callerFrame; | |
14820 | JSObject *const callerVarObj; | |
14821 | JSParseNode *nodeList; | |
14822 | uint32 functionCount; | |
14823 | JSObjectBox *traceListHead; | |
14824 | JSTreeContext *tc; | |
14825 | js::AutoKeepAtoms keepAtoms; | |
14826 | Parser(JSContext *cx, JSPrincipals *prin = __null, JSStackFrame *cfp = __null); | |
14827 | ~Parser(); | |
14828 | friend void js::AutoGCRooter::trace(JSTracer *trc); | |
14829 | friend struct ::JSTreeContext; | |
14830 | friend struct Compiler; | |
14831 | bool init(const jschar *base, size_t length, const char *filename, uintN lineno, | |
14832 | JSVersion version); | |
14833 | void setPrincipals(JSPrincipals *prin); | |
14834 | const char *getFilename() const { return tokenStream.getFilename(); } | |
14835 | JSVersion versionWithFlags() const { return tokenStream.versionWithFlags(); } | |
14836 | JSVersion versionNumber() const { return tokenStream.versionNumber(); } | |
14837 | bool hasXML() const { return tokenStream.hasXML(); } | |
14838 | bool hasAnonFunFix() const { return tokenStream.hasAnonFunFix(); } | |
14839 | JSParseNode *parse(JSObject *chain); | |
14840 | JSParseNode *parseXMLText(JSObject *chain, bool allowList); | |
14841 | JSObjectBox *newObjectBox(JSObject *obj); | |
14842 | JSFunctionBox *newFunctionBox(JSObject *obj, JSParseNode *fn, JSTreeContext *tc); | |
14843 | JSFunction *newFunction(JSTreeContext *tc, JSAtom *atom, uintN lambda); | |
14844 | bool analyzeFunctions(JSTreeContext *tc); | |
14845 | void cleanFunctionList(JSFunctionBox **funbox); | |
14846 | bool markFunArgs(JSFunctionBox *funbox); | |
14847 | void setFunctionKinds(JSFunctionBox *funbox, uint32 *tcflags); | |
14848 | void trace(JSTracer *trc); | |
14849 | inline bool reportErrorNumber(JSParseNode *pn, uintN flags, uintN errorNumber, ...); | |
14850 | private: | |
14851 | JSParseNode *functionStmt(); | |
14852 | JSParseNode *functionExpr(); | |
14853 | JSParseNode *statements(); | |
14854 | JSParseNode *statement(); | |
14855 | JSParseNode *switchStatement(); | |
14856 | JSParseNode *forStatement(); | |
14857 | JSParseNode *tryStatement(); | |
14858 | JSParseNode *withStatement(); | |
14859 | JSParseNode *letStatement(); | |
14860 | JSParseNode *expressionStatement(); | |
14861 | JSParseNode *variables(bool inLetHead); | |
14862 | JSParseNode *expr(); | |
14863 | JSParseNode *assignExpr(); | |
14864 | JSParseNode *condExpr(); | |
14865 | JSParseNode *orExpr(); | |
14866 | JSParseNode *andExpr(); | |
14867 | JSParseNode *bitOrExpr(); | |
14868 | JSParseNode *bitXorExpr(); | |
14869 | JSParseNode *bitAndExpr(); | |
14870 | JSParseNode *eqExpr(); | |
14871 | JSParseNode *relExpr(); | |
14872 | JSParseNode *shiftExpr(); | |
14873 | JSParseNode *addExpr(); | |
14874 | JSParseNode *mulExpr(); | |
14875 | JSParseNode *unaryExpr(); | |
14876 | JSParseNode *memberExpr(JSBool allowCallSyntax); | |
14877 | JSParseNode *primaryExpr(js::TokenKind tt, JSBool afterDot); | |
14878 | JSParseNode *parenExpr(JSBool *genexp = __null); | |
14879 | bool recognizeDirectivePrologue(JSParseNode *pn, bool *isDirectivePrologueMember); | |
14880 | enum FunctionType { GETTER, SETTER, GENERAL }; | |
14881 | bool functionArguments(JSTreeContext &funtc, JSFunctionBox *funbox, JSParseNode **list); | |
14882 | JSParseNode *functionBody(); | |
14883 | JSParseNode *functionDef(JSAtom *name, FunctionType type, uintN lambda); | |
14884 | JSParseNode *condition(); | |
14885 | JSParseNode *comprehensionTail(JSParseNode *kid, uintN blockid, | |
14886 | js::TokenKind type = js::TOK_SEMI, JSOp op = JSOP_NOP); | |
14887 | JSParseNode *generatorExpr(JSParseNode *kid); | |
14888 | JSBool argumentList(JSParseNode *listNode); | |
14889 | JSParseNode *bracketedExpr(); | |
14890 | JSParseNode *letBlock(JSBool statement); | |
14891 | JSParseNode *returnOrYield(bool useAssignExpr); | |
14892 | JSParseNode *destructuringExpr(BindData *data, js::TokenKind tt); | |
14893 | JSParseNode *endBracketedExpr(); | |
14894 | JSParseNode *propertySelector(); | |
14895 | JSParseNode *qualifiedSuffix(JSParseNode *pn); | |
14896 | JSParseNode *qualifiedIdentifier(); | |
14897 | JSParseNode *attributeIdentifier(); | |
14898 | JSParseNode *xmlExpr(JSBool inTag); | |
14899 | JSParseNode *xmlAtomNode(); | |
14900 | JSParseNode *xmlNameExpr(); | |
14901 | JSParseNode *xmlTagContent(js::TokenKind tagtype, JSAtom **namep); | |
14902 | JSBool xmlElementContent(JSParseNode *pn); | |
14903 | JSParseNode *xmlElementOrList(JSBool allowList); | |
14904 | JSParseNode *xmlElementOrListRoot(JSBool allowList); | |
14905 | }; | |
14906 | inline | |
14907 | bool | |
14908 | Parser::reportErrorNumber(JSParseNode *pn, uintN flags, uintN errorNumber, ...) | |
14909 | { | |
14910 | va_list args; | |
14911 | __builtin_va_start(args,errorNumber); | |
14912 | bool result = tokenStream.reportCompileErrorNumberVA(pn, flags, errorNumber, args); | |
14913 | __builtin_va_end(args); | |
14914 | return result; | |
14915 | } | |
14916 | struct Compiler | |
14917 | { | |
14918 | Parser parser; | |
14919 | GlobalScope *globalScope; | |
14920 | Compiler(JSContext *cx, JSPrincipals *prin = __null, JSStackFrame *cfp = __null); | |
14921 | inline | |
14922 | ||
14923 | ||
14924 | bool | |
14925 | init(const jschar *base, size_t length, const char *filename, uintN lineno, JSVersion version) | |
14926 | { | |
14927 | return parser.init(base, length, filename, lineno, version); | |
14928 | } | |
14929 | static | |
14930 | ||
14931 | ||
14932 | bool | |
14933 | compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, | |
14934 | js::Bindings *bindings, const jschar *chars, size_t length, | |
14935 | const char *filename, uintN lineno, JSVersion version); | |
14936 | static JSScript * | |
14937 | compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame, | |
14938 | JSPrincipals *principals, uint32 tcflags, | |
14939 | const jschar *chars, size_t length, | |
14940 | const char *filename, uintN lineno, JSVersion version, | |
14941 | JSString *source = __null, uintN staticLevel = 0); | |
14942 | private: | |
14943 | static bool defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script); | |
14944 | }; | |
14945 | } | |
14946 | extern JSBool | |
14947 | js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, | |
14948 | bool inCond = false); | |
14949 | } | |
14950 | extern const char js_AnyName_str[]; | |
14951 | extern const char js_AttributeName_str[]; | |
14952 | extern const char js_isXMLName_str[]; | |
14953 | extern const char js_XMLList_str[]; | |
14954 | extern const char js_amp_entity_str[]; | |
14955 | extern const char js_gt_entity_str[]; | |
14956 | extern const char js_lt_entity_str[]; | |
14957 | extern const char js_quot_entity_str[]; | |
14958 | typedef JSBool | |
14959 | (* JSIdentityOp)(const void *a, const void *b); | |
14960 | struct JSXMLArray { | |
14961 | uint32 length; | |
14962 | uint32 capacity; | |
14963 | void **vector; | |
14964 | JSXMLArrayCursor *cursors; | |
14965 | void init() { | |
14966 | length = capacity = 0; | |
14967 | vector = __null; | |
14968 | cursors = __null; | |
14969 | } | |
14970 | void finish(JSContext *cx); | |
14971 | bool setCapacity(JSContext *cx, uint32 capacity); | |
14972 | void trim(); | |
14973 | }; | |
14974 | struct JSXMLArrayCursor | |
14975 | { | |
14976 | JSXMLArray *array; | |
14977 | uint32 index; | |
14978 | JSXMLArrayCursor *next; | |
14979 | JSXMLArrayCursor **prevp; | |
14980 | void *root; | |
14981 | JSXMLArrayCursor(JSXMLArray *array) | |
14982 | : array(array), index(0), next(array->cursors), prevp(&array->cursors), | |
14983 | root(__null) | |
14984 | { | |
14985 | if (next) | |
14986 | next->prevp = &next; | |
14987 | array->cursors = this; | |
14988 | } | |
14989 | ~JSXMLArrayCursor() { disconnect(); } | |
14990 | void disconnect() { | |
14991 | if (!array) | |
14992 | return; | |
14993 | if (next) | |
14994 | next->prevp = prevp; | |
14995 | *prevp = next; | |
14996 | array = __null; | |
14997 | } | |
14998 | void *getNext() { | |
14999 | if (!array || index >= array->length) | |
15000 | return __null; | |
15001 | return root = array->vector[index++]; | |
15002 | } | |
15003 | void *getCurrent() { | |
15004 | if (!array || index >= array->length) | |
15005 | return __null; | |
15006 | return root = array->vector[index]; | |
15007 | } | |
15008 | void trace(JSTracer *trc); | |
15009 | }; | |
15010 | typedef enum JSXMLClass { | |
15011 | JSXML_CLASS_LIST, | |
15012 | JSXML_CLASS_ELEMENT, | |
15013 | JSXML_CLASS_ATTRIBUTE, | |
15014 | JSXML_CLASS_PROCESSING_INSTRUCTION, | |
15015 | JSXML_CLASS_TEXT, | |
15016 | JSXML_CLASS_COMMENT, | |
15017 | JSXML_CLASS_LIMIT | |
15018 | } JSXMLClass; | |
15019 | typedef struct JSXMLListVar { | |
15020 | JSXMLArray kids; | |
15021 | JSXML *target; | |
15022 | JSObject *targetprop; | |
15023 | } JSXMLListVar; | |
15024 | typedef struct JSXMLElemVar { | |
15025 | JSXMLArray kids; | |
15026 | JSXMLArray namespaces; | |
15027 | JSXMLArray attrs; | |
15028 | } JSXMLElemVar; | |
15029 | struct JSXML : js::gc::Cell { | |
15030 | JSObject *object; | |
15031 | void *domnode; | |
15032 | JSXML *parent; | |
15033 | JSObject *name; | |
15034 | uint32 xml_class; | |
15035 | uint32 xml_flags; | |
15036 | union { | |
15037 | JSXMLListVar list; | |
15038 | JSXMLElemVar elem; | |
15039 | JSString *value; | |
15040 | } u; | |
15041 | void finalize(JSContext *cx) { | |
15042 | if ((((this)->xml_class) < JSXML_CLASS_ATTRIBUTE)) { | |
15043 | u.list.kids.finish(cx); | |
15044 | if (xml_class == JSXML_CLASS_ELEMENT) { | |
15045 | u.elem.namespaces.finish(cx); | |
15046 | u.elem.attrs.finish(cx); | |
15047 | } | |
15048 | } | |
15049 | } | |
15050 | }; | |
15051 | extern JSXML * | |
15052 | js_NewXML(JSContext *cx, JSXMLClass xml_class); | |
15053 | extern void | |
15054 | js_TraceXML(JSTracer *trc, JSXML *xml); | |
15055 | extern JSObject * | |
15056 | js_NewXMLObject(JSContext *cx, JSXMLClass xml_class); | |
15057 | extern JSObject * | |
15058 | js_GetXMLObject(JSContext *cx, JSXML *xml); | |
15059 | extern __attribute__((visibility ("default"))) js::Class js_XMLClass; | |
15060 | extern __attribute__((visibility ("default"))) js::Class js_NamespaceClass; | |
15061 | extern __attribute__((visibility ("default"))) js::Class js_QNameClass; | |
15062 | extern __attribute__((visibility ("default"))) js::Class js_AttributeNameClass; | |
15063 | extern __attribute__((visibility ("default"))) js::Class js_AnyNameClass; | |
15064 | extern js::Class js_XMLFilterClass; | |
15065 | inline | |
15066 | bool | |
15067 | JSObject::isXML() const | |
15068 | { | |
15069 | return getClass() == &js_XMLClass; | |
15070 | } | |
15071 | inline | |
15072 | bool | |
15073 | JSObject::isXMLId() const | |
15074 | { | |
15075 | js::Class *clasp = getClass(); | |
15076 | return clasp == &js_QNameClass || | |
15077 | clasp == &js_AttributeNameClass || | |
15078 | clasp == &js_AnyNameClass; | |
15079 | } | |
15080 | inline | |
15081 | bool | |
15082 | JSObject::isNamespace() const | |
15083 | { | |
15084 | return getClass() == &js_NamespaceClass; | |
15085 | } | |
15086 | inline | |
15087 | bool | |
15088 | JSObject::isQName() const | |
15089 | { | |
15090 | js::Class* clasp = getClass(); | |
15091 | return clasp == &js_QNameClass || | |
15092 | clasp == &js_AttributeNameClass || | |
15093 | clasp == &js_AnyNameClass; | |
15094 | } | |
15095 | static inline | |
15096 | bool | |
15097 | IsXML(const js::Value &v) | |
15098 | { | |
15099 | return v.isObject() && v.toObject().isXML(); | |
15100 | } | |
15101 | extern JSObject * | |
15102 | js_InitNamespaceClass(JSContext *cx, JSObject *obj); | |
15103 | extern JSObject * | |
15104 | js_InitQNameClass(JSContext *cx, JSObject *obj); | |
15105 | extern JSObject * | |
15106 | js_InitXMLClass(JSContext *cx, JSObject *obj); | |
15107 | extern JSObject * | |
15108 | js_InitXMLClasses(JSContext *cx, JSObject *obj); | |
15109 | extern JSBool | |
15110 | js_GetFunctionNamespace(JSContext *cx, js::Value *vp); | |
15111 | JSBool | |
15112 | js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp); | |
15113 | extern JSBool | |
15114 | js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp); | |
15115 | extern JSBool | |
15116 | js_SetDefaultXMLNamespace(JSContext *cx, const js::Value &v); | |
15117 | extern JSBool | |
15118 | js_IsXMLName(JSContext *cx, jsval v); | |
15119 | extern JSBool | |
15120 | js_ToAttributeName(JSContext *cx, js::Value *vp); | |
15121 | extern JSFlatString * | |
15122 | js_EscapeAttributeValue(JSContext *cx, JSString *str, JSBool quote); | |
15123 | extern JSString * | |
15124 | js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, | |
15125 | JSString *str2); | |
15126 | extern JSFlatString * | |
15127 | js_EscapeElementValue(JSContext *cx, JSString *str); | |
15128 | extern JSString * | |
15129 | js_ValueToXMLString(JSContext *cx, const js::Value &v); | |
15130 | extern JSObject * | |
15131 | js_ConstructXMLQNameObject(JSContext *cx, const js::Value & nsval, | |
15132 | const js::Value & lnval); | |
15133 | extern JSBool | |
15134 | js_GetAnyName(JSContext *cx, jsid *idp); | |
15135 | extern JSBool | |
15136 | js_FindXMLProperty(JSContext *cx, const js::Value &nameval, JSObject **objp, jsid *idp); | |
15137 | extern JSBool | |
15138 | js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); | |
15139 | extern JSBool | |
15140 | js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | |
15141 | extern JSBool | |
15142 | js_DeleteXMLListElements(JSContext *cx, JSObject *listobj); | |
15143 | extern JSBool | |
15144 | js_StepXMLListFilter(JSContext *cx, JSBool initialized); | |
15145 | extern JSObject * | |
15146 | js_ValueToXMLObject(JSContext *cx, const js::Value &v); | |
15147 | extern JSObject * | |
15148 | js_ValueToXMLListObject(JSContext *cx, const js::Value &v); | |
15149 | extern JSObject * | |
15150 | js_NewXMLSpecialObject(JSContext *cx, JSXMLClass xml_class, JSString *name, | |
15151 | JSString *value); | |
15152 | extern JSString * | |
15153 | js_MakeXMLCDATAString(JSContext *cx, JSString *str); | |
15154 | extern JSString * | |
15155 | js_MakeXMLCommentString(JSContext *cx, JSString *str); | |
15156 | extern JSString * | |
15157 | js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str); | |
15158 | extern JSBool | |
15159 | js_TestXMLEquality(JSContext *cx, const js::Value &v1, const js::Value &v2, | |
15160 | JSBool *bp); | |
15161 | extern JSBool | |
15162 | js_ConcatenateXML(JSContext *cx, JSObject *obj1, JSObject *obj2, js::Value *vp); | |
15163 | namespace JSC { | |
15164 | class ExecutableAllocator; | |
15165 | } | |
15166 | namespace js { | |
15167 | typedef HashMap<jsbytecode*, | |
15168 | size_t, | |
15169 | DefaultHasher<jsbytecode*>, | |
15170 | SystemAllocPolicy> RecordAttemptMap; | |
15171 | typedef HashMap<jsbytecode*, | |
15172 | LoopProfile*, | |
15173 | DefaultHasher<jsbytecode*>, | |
15174 | SystemAllocPolicy> LoopProfileMap; | |
15175 | class Oracle; | |
15176 | typedef HashSet<JSScript *, | |
15177 | DefaultHasher<JSScript *>, | |
15178 | SystemAllocPolicy> TracedScriptSet; | |
15179 | typedef HashMap<JSFunction *, | |
15180 | JSString *, | |
15181 | DefaultHasher<JSFunction *>, | |
15182 | SystemAllocPolicy> ToSourceCache; | |
15183 | struct TraceMonitor; | |
15184 | struct TracerState | |
15185 | { | |
15186 | JSContext* cx; | |
15187 | TraceMonitor* traceMonitor; | |
15188 | double* stackBase; | |
15189 | double* sp; | |
15190 | double* eos; | |
15191 | FrameInfo** callstackBase; | |
15192 | void* sor; | |
15193 | FrameInfo** rp; | |
15194 | void* eor; | |
15195 | VMSideExit* lastTreeExitGuard; | |
15196 | VMSideExit* lastTreeCallGuard; | |
15197 | void* rpAtLastTreeCall; | |
15198 | VMSideExit* outermostTreeExitGuard; | |
15199 | TreeFragment* outermostTree; | |
15200 | uintN* inlineCallCountp; | |
15201 | VMSideExit** innermostNestedGuardp; | |
15202 | VMSideExit* innermost; | |
15203 | uint64 startTime; | |
15204 | TracerState* prev; | |
15205 | uint32 builtinStatus; | |
15206 | double* deepBailSp; | |
15207 | uintN nativeVpLen; | |
15208 | js::Value* nativeVp; | |
15209 | TracerState(JSContext *cx, TraceMonitor *tm, TreeFragment *ti, | |
15210 | uintN &inlineCallCountp, VMSideExit** innermostNestedGuardp); | |
15211 | ~TracerState(); | |
15212 | }; | |
15213 | struct TraceNativeStorage | |
15214 | { | |
15215 | double stack_global_buf[MAX_NATIVE_STACK_SLOTS + GLOBAL_SLOTS_BUFFER_SIZE]; | |
15216 | FrameInfo *callstack_buf[MAX_CALL_STACK_ENTRIES]; | |
15217 | double *stack() { return stack_global_buf; } | |
15218 | double *global() { return stack_global_buf + MAX_NATIVE_STACK_SLOTS; } | |
15219 | FrameInfo **callstack() { return callstack_buf; } | |
15220 | }; | |
15221 | struct GlobalState { | |
15222 | JSObject* globalObj; | |
15223 | uint32 globalShape; | |
15224 | SlotList* globalSlots; | |
15225 | }; | |
15226 | struct TraceMonitor { | |
15227 | JSContext *tracecx; | |
15228 | js::TracerState *tracerState; | |
15229 | js::VMSideExit *bailExit; | |
15230 | unsigned iterationCounter; | |
15231 | TraceNativeStorage *storage; | |
15232 | VMAllocator* dataAlloc; | |
15233 | VMAllocator* traceAlloc; | |
15234 | VMAllocator* tempAlloc; | |
15235 | nanojit::CodeAlloc* codeAlloc; | |
15236 | nanojit::Assembler* assembler; | |
15237 | FrameInfoCache* frameCache; | |
15238 | uintN flushEpoch; | |
15239 | Oracle* oracle; | |
15240 | TraceRecorder* recorder; | |
15241 | LoopProfile* profile; | |
15242 | GlobalState globalStates[MONITOR_N_GLOBAL_STATES]; | |
15243 | TreeFragment *vmfragments[FRAGMENT_TABLE_SIZE]; | |
15244 | RecordAttemptMap* recordAttempts; | |
15245 | LoopProfileMap* loopProfiles; | |
15246 | uint32 maxCodeCacheBytes; | |
15247 | JSBool needFlush; | |
15248 | TypeMap* cachedTempTypeMap; | |
15249 | TracedScriptSet tracedScripts; | |
15250 | bool ontrace() const { | |
15251 | return !!tracecx; | |
15252 | } | |
15253 | void flush(); | |
15254 | void sweep(JSContext *cx); | |
15255 | void mark(JSTracer *trc); | |
15256 | bool outOfMemory() const; | |
15257 | }; | |
15258 | namespace mjit { | |
15259 | class JaegerCompartment; | |
15260 | } | |
15261 | } | |
15262 | namespace js { | |
15263 | class NativeIterCache { | |
15264 | static const size_t SIZE = size_t(1) << 8; | |
15265 | JSObject *data[SIZE]; | |
15266 | static size_t getIndex(uint32 key) { | |
15267 | return size_t(key) % SIZE; | |
15268 | } | |
15269 | public: | |
15270 | JSObject *last; | |
15271 | NativeIterCache() | |
15272 | : last(__null) { | |
15273 | PodArrayZero(data); | |
15274 | } | |
15275 | void purge() { | |
15276 | PodArrayZero(data); | |
15277 | last = __null; | |
15278 | } | |
15279 | JSObject *get(uint32 key) const { | |
15280 | return data[getIndex(key)]; | |
15281 | } | |
15282 | void set(uint32 key, JSObject *iterobj) { | |
15283 | data[getIndex(key)] = iterobj; | |
15284 | } | |
15285 | }; | |
15286 | class DtoaCache { | |
15287 | double d; | |
15288 | jsint base; | |
15289 | JSString *s; | |
15290 | public: | |
15291 | DtoaCache() : s(__null) {} | |
15292 | void purge() { s = __null; } | |
15293 | JSString *lookup(jsint base, double d) { | |
15294 | return this->s && base == this->base && d == this->d ? this->s : __null; | |
15295 | } | |
15296 | void cache(jsint base, double d, JSString *s) { | |
15297 | this->base = base; | |
15298 | this->d = d; | |
15299 | this->s = s; | |
15300 | } | |
15301 | }; | |
15302 | } | |
15303 | struct __attribute__((visibility ("default"))) JSCompartment { | |
15304 | JSRuntime *rt; | |
15305 | JSPrincipals *principals; | |
15306 | js::gc::Chunk *chunk; | |
15307 | js::gc::ArenaList arenas[js::gc::FINALIZE_LIMIT]; | |
15308 | js::gc::FreeLists freeLists; | |
15309 | size_t gcBytes; | |
15310 | size_t gcTriggerBytes; | |
15311 | size_t gcLastBytes; | |
15312 | JSScript *scriptsToGC[((JSUint32)1 << (6))]; | |
15313 | void *data; | |
15314 | bool active; | |
15315 | js::WrapperMap crossCompartmentWrappers; | |
15316 | js::PropertyTree propertyTree; | |
15317 | js::EmptyShape *emptyArgumentsShape; | |
15318 | js::EmptyShape *emptyBlockShape; | |
15319 | js::EmptyShape *emptyCallShape; | |
15320 | js::EmptyShape *emptyDeclEnvShape; | |
15321 | js::EmptyShape *emptyEnumeratorShape; | |
15322 | js::EmptyShape *emptyWithShape; | |
15323 | typedef js::HashSet<js::EmptyShape *, | |
15324 | js::DefaultHasher<js::EmptyShape *>, | |
15325 | js::SystemAllocPolicy> EmptyShapeSet; | |
15326 | EmptyShapeSet emptyShapes; | |
15327 | bool debugMode; | |
15328 | JSCList scripts; | |
15329 | JSC::ExecutableAllocator *regExpAllocator; | |
15330 | js::NativeIterCache nativeIterCache; | |
15331 | js::ToSourceCache toSourceCache; | |
15332 | JSCompartment(JSRuntime *rt); | |
15333 | ~JSCompartment(); | |
15334 | bool init(); | |
15335 | void markCrossCompartment(JSTracer *trc); | |
15336 | void mark(JSTracer *trc); | |
15337 | bool wrap(JSContext *cx, js::Value *vp); | |
15338 | bool wrap(JSContext *cx, JSString **strp); | |
15339 | bool wrap(JSContext *cx, JSObject **objp); | |
15340 | bool wrapId(JSContext *cx, jsid *idp); | |
15341 | bool wrap(JSContext *cx, js::PropertyOp *op); | |
15342 | bool wrap(JSContext *cx, js::StrictPropertyOp *op); | |
15343 | bool wrap(JSContext *cx, js::PropertyDescriptor *desc); | |
15344 | bool wrap(JSContext *cx, js::AutoIdVector &props); | |
15345 | void sweep(JSContext *cx, uint32 releaseInterval); | |
15346 | void purge(JSContext *cx); | |
15347 | void finishArenaLists(); | |
15348 | void finalizeObjectArenaLists(JSContext *cx); | |
15349 | void finalizeStringArenaLists(JSContext *cx); | |
15350 | bool arenaListsAreEmpty(); | |
15351 | void setGCLastBytes(size_t lastBytes); | |
15352 | js::DtoaCache dtoaCache; | |
15353 | private: | |
15354 | js::MathCache *mathCache; | |
15355 | js::MathCache *allocMathCache(JSContext *cx); | |
15356 | bool marked; | |
15357 | typedef js::HashMap<jsbytecode*, | |
15358 | size_t, | |
15359 | js::DefaultHasher<jsbytecode*>, | |
15360 | js::SystemAllocPolicy> BackEdgeMap; | |
15361 | BackEdgeMap backEdgeTable; | |
15362 | JSCompartment *thisForCtor() { return this; } | |
15363 | public: | |
15364 | js::MathCache *getMathCache(JSContext *cx) { | |
15365 | return mathCache ? mathCache : allocMathCache(cx); | |
15366 | } | |
15367 | bool isMarked() { return marked; } | |
15368 | void clearMark() { marked = false; } | |
15369 | size_t backEdgeCount(jsbytecode *pc) const; | |
15370 | size_t incBackEdgeCount(jsbytecode *pc); | |
15371 | }; | |
15372 | static inline | |
15373 | bool | |
15374 | JS_ON_TRACE(JSContext *cx) | |
15375 | { | |
15376 | return false; | |
15377 | } | |
15378 | static inline js::TraceRecorder * | |
15379 | TRACE_RECORDER(JSContext *cx) | |
15380 | { | |
15381 | return __null; | |
15382 | } | |
15383 | static inline js::LoopProfile * | |
15384 | TRACE_PROFILER(JSContext *cx) | |
15385 | { | |
15386 | return __null; | |
15387 | } | |
15388 | namespace js { | |
15389 | static inline MathCache * | |
15390 | GetMathCache(JSContext *cx) | |
15391 | { | |
15392 | return cx->compartment->getMathCache(cx); | |
15393 | } | |
15394 | } | |
15395 | namespace js { | |
15396 | class PreserveCompartment { | |
15397 | protected: | |
15398 | JSContext *cx; | |
15399 | private: | |
15400 | JSCompartment *oldCompartment; | |
15401 | ||
15402 | public: | |
15403 | PreserveCompartment(JSContext *cx ) : cx(cx) { | |
15404 | do { } while (0); | |
15405 | oldCompartment = cx->compartment; | |
15406 | } | |
15407 | ~PreserveCompartment() { | |
15408 | cx->compartment = oldCompartment; | |
15409 | } | |
15410 | }; | |
15411 | class SwitchToCompartment : public PreserveCompartment { | |
15412 | public: | |
15413 | SwitchToCompartment(JSContext *cx, JSCompartment *newCompartment) : PreserveCompartment(cx) { | |
15414 | cx->compartment = newCompartment; | |
15415 | } | |
15416 | SwitchToCompartment(JSContext *cx, JSObject *target) : PreserveCompartment(cx) { | |
15417 | cx->compartment = target->getCompartment(); | |
15418 | } | |
15419 | }; | |
15420 | class AssertCompartmentUnchanged { | |
15421 | protected: | |
15422 | JSContext * const cx; | |
15423 | JSCompartment * const oldCompartment; | |
15424 | ||
15425 | public: | |
15426 | AssertCompartmentUnchanged(JSContext *cx ) | |
15427 | : cx(cx), oldCompartment(cx->compartment) { | |
15428 | do { } while (0); | |
15429 | } | |
15430 | ~AssertCompartmentUnchanged() { | |
15431 | ((void) 0); | |
15432 | } | |
15433 | }; | |
15434 | } | |
15435 | extern js::Class js_RegExpClass; | |
15436 | namespace js { | |
15437 | class RegExpStatics | |
15438 | { | |
15439 | typedef Vector<int, 20, SystemAllocPolicy> MatchPairs; | |
15440 | MatchPairs matchPairs; | |
15441 | JSLinearString *matchPairsInput; | |
15442 | JSString *pendingInput; | |
15443 | uintN flags; | |
15444 | RegExpStatics *bufferLink; | |
15445 | bool copied; | |
15446 | bool createDependent(JSContext *cx, size_t start, size_t end, Value *out) const; | |
15447 | void copyTo(RegExpStatics &dst) { | |
15448 | dst.matchPairs.clear(); | |
15449 | ((void) (dst.matchPairs.append(matchPairs))); | |
15450 | dst.matchPairsInput = matchPairsInput; | |
15451 | dst.pendingInput = pendingInput; | |
15452 | dst.flags = flags; | |
15453 | } | |
15454 | void aboutToWrite() { | |
15455 | if (bufferLink && !bufferLink->copied) { | |
15456 | copyTo(*bufferLink); | |
15457 | bufferLink->copied = true; | |
15458 | } | |
15459 | } | |
15460 | bool save(JSContext *cx, RegExpStatics *buffer) { | |
15461 | ((void) 0); | |
15462 | buffer->bufferLink = bufferLink; | |
15463 | bufferLink = buffer; | |
15464 | if (!buffer->matchPairs.reserve(matchPairs.length())) { | |
15465 | js_ReportOutOfMemory(cx); | |
15466 | return false; | |
15467 | } | |
15468 | return true; | |
15469 | } | |
15470 | void restore() { | |
15471 | if (bufferLink->copied) | |
15472 | bufferLink->copyTo(*this); | |
15473 | bufferLink = bufferLink->bufferLink; | |
15474 | } | |
15475 | void checkInvariants() { | |
15476 | } | |
15477 | void checkParenNum(size_t pairNum) const { | |
15478 | ((void) 0); | |
15479 | ((void) 0); | |
15480 | } | |
15481 | bool pairIsPresent(size_t pairNum) const { | |
15482 | return get(pairNum, 0) >= 0; | |
15483 | } | |
15484 | size_t getParenLength(size_t pairNum) const { | |
15485 | checkParenNum(pairNum); | |
15486 | ((void) 0); | |
15487 | return get(pairNum, 1) - get(pairNum, 0); | |
15488 | } | |
15489 | int get(size_t pairNum, bool which) const { | |
15490 | ((void) 0); | |
15491 | return matchPairs[2 * pairNum + which]; | |
15492 | } | |
15493 | bool makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const; | |
15494 | static const uintN allFlags = 0x01 | 0x02 | 0x08 | 0x04; | |
15495 | struct InitBuffer {}; | |
15496 | explicit RegExpStatics(InitBuffer) : bufferLink(__null), copied(false) {} | |
15497 | friend class PreserveRegExpStatics; | |
15498 | public: | |
15499 | RegExpStatics() : bufferLink(__null), copied(false) { clear(); } | |
15500 | static RegExpStatics *extractFrom(JSObject *global); | |
15501 | bool updateFromMatch(JSContext *cx, JSLinearString *input, int *buf, size_t matchItemCount) { | |
15502 | aboutToWrite(); | |
15503 | pendingInput = input; | |
15504 | if (!matchPairs.resizeUninitialized(matchItemCount)) { | |
15505 | js_ReportOutOfMemory(cx); | |
15506 | return false; | |
15507 | } | |
15508 | for (size_t i = 0; i < matchItemCount; ++i) | |
15509 | matchPairs[i] = buf[i]; | |
15510 | matchPairsInput = input; | |
15511 | return true; | |
15512 | } | |
15513 | void setMultiline(bool enabled) { | |
15514 | aboutToWrite(); | |
15515 | if (enabled) | |
15516 | flags = flags | 0x04; | |
15517 | else | |
15518 | flags = flags & ~0x04; | |
15519 | } | |
15520 | void clear() { | |
15521 | aboutToWrite(); | |
15522 | flags = 0; | |
15523 | pendingInput = __null; | |
15524 | matchPairsInput = __null; | |
15525 | matchPairs.clear(); | |
15526 | } | |
15527 | void reset(JSString *newInput, bool newMultiline) { | |
15528 | aboutToWrite(); | |
15529 | clear(); | |
15530 | pendingInput = newInput; | |
15531 | setMultiline(newMultiline); | |
15532 | checkInvariants(); | |
15533 | } | |
15534 | void setPendingInput(JSString *newInput) { | |
15535 | aboutToWrite(); | |
15536 | pendingInput = newInput; | |
15537 | } | |
15538 | private: | |
15539 | size_t pairCount() const { | |
15540 | ((void) 0); | |
15541 | return matchPairs.length() / 2; | |
15542 | } | |
15543 | public: | |
15544 | size_t parenCount() const { | |
15545 | size_t pc = pairCount(); | |
15546 | ((void) 0); | |
15547 | return pc - 1; | |
15548 | } | |
15549 | JSString *getPendingInput() const { return pendingInput; } | |
15550 | uintN getFlags() const { return flags; } | |
15551 | bool multiline() const { return flags & 0x04; } | |
15552 | size_t matchStart() const { | |
15553 | int start = get(0, 0); | |
15554 | ((void) 0); | |
15555 | return size_t(start); | |
15556 | } | |
15557 | size_t matchLimit() const { | |
15558 | int limit = get(0, 1); | |
15559 | ((void) 0); | |
15560 | return size_t(limit); | |
15561 | } | |
15562 | bool matched() const { | |
15563 | ((void) 0); | |
15564 | ((void) 0); | |
15565 | return get(0, 1) - get(0, 0) > 0; | |
15566 | } | |
15567 | void mark(JSTracer *trc) const { | |
15568 | if (pendingInput) | |
15569 | do { JSString *str_ = (pendingInput); ((void) 0); do { do { } while (0); JS_CallTracer(((trc)), (str_), (1)); } while (0); } while (0); | |
15570 | if (matchPairsInput) | |
15571 | do { JSString *str_ = (matchPairsInput); ((void) 0); do { do { } while (0); JS_CallTracer(((trc)), (str_), (1)); } while (0); } while (0); | |
15572 | } | |
15573 | bool createPendingInput(JSContext *cx, Value *out) const; | |
15574 | bool createLastMatch(JSContext *cx, Value *out) const { return makeMatch(cx, 0, 0, out); } | |
15575 | bool createLastParen(JSContext *cx, Value *out) const; | |
15576 | bool createLeftContext(JSContext *cx, Value *out) const; | |
15577 | bool createRightContext(JSContext *cx, Value *out) const; | |
15578 | bool createParen(JSContext *cx, size_t pairNum, Value *out) const { | |
15579 | ((void) 0); | |
15580 | if (pairNum >= pairCount()) { | |
15581 | out->setString(cx->runtime->emptyString); | |
15582 | return true; | |
15583 | } | |
15584 | return makeMatch(cx, pairNum * 2, pairNum, out); | |
15585 | } | |
15586 | void getParen(size_t pairNum, JSSubString *out) const; | |
15587 | void getLastMatch(JSSubString *out) const; | |
15588 | void getLastParen(JSSubString *out) const; | |
15589 | void getLeftContext(JSSubString *out) const; | |
15590 | void getRightContext(JSSubString *out) const; | |
15591 | }; | |
15592 | class PreserveRegExpStatics | |
15593 | { | |
15594 | RegExpStatics *const original; | |
15595 | RegExpStatics buffer; | |
15596 | public: | |
15597 | explicit PreserveRegExpStatics(RegExpStatics *original) | |
15598 | : original(original), | |
15599 | buffer(RegExpStatics::InitBuffer()) | |
15600 | {} | |
15601 | bool init(JSContext *cx) { | |
15602 | return original->save(cx, &buffer); | |
15603 | } | |
15604 | ~PreserveRegExpStatics() { | |
15605 | original->restore(); | |
15606 | } | |
15607 | }; | |
15608 | } | |
15609 | static inline | |
15610 | bool | |
15611 | VALUE_IS_REGEXP(JSContext *cx, js::Value v) | |
15612 | { | |
15613 | return !v.isPrimitive() && v.toObject().isRegExp(); | |
15614 | } | |
15615 | inline const js::Value & | |
15616 | JSObject::getRegExpLastIndex() const | |
15617 | { | |
15618 | ((void) 0); | |
15619 | return getSlot(JSSLOT_REGEXP_LAST_INDEX); | |
15620 | } | |
15621 | inline void | |
15622 | JSObject::setRegExpLastIndex(const js::Value &v) | |
15623 | { | |
15624 | ((void) 0); | |
15625 | setSlot(JSSLOT_REGEXP_LAST_INDEX, v); | |
15626 | } | |
15627 | inline void | |
15628 | JSObject::setRegExpLastIndex(jsdouble d) | |
15629 | { | |
15630 | ((void) 0); | |
15631 | setSlot(JSSLOT_REGEXP_LAST_INDEX, js::NumberValue(d)); | |
15632 | } | |
15633 | inline void | |
15634 | JSObject::zeroRegExpLastIndex() | |
15635 | { | |
15636 | ((void) 0); | |
15637 | getSlotRef(JSSLOT_REGEXP_LAST_INDEX).setInt32(0); | |
15638 | } | |
15639 | namespace js { class AutoStringRooter; } | |
15640 | inline | |
15641 | bool | |
15642 | JSObject::isRegExp() const | |
15643 | { | |
15644 | return getClass() == &js_RegExpClass; | |
15645 | } | |
15646 | extern __attribute__((visibility ("default"))) JSBool | |
15647 | js_ObjectIsRegExp(JSObject *obj); | |
15648 | extern JSObject * | |
15649 | js_InitRegExpClass(JSContext *cx, JSObject *obj); | |
15650 | extern JSBool | |
15651 | js_regexp_toString(JSContext *cx, JSObject *obj, js::Value *vp); | |
15652 | extern __attribute__((visibility ("default"))) JSObject * | |
15653 | js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto); | |
15654 | extern __attribute__((visibility ("default"))) void | |
15655 | js_SaveAndClearRegExpStatics(JSContext *cx, js::RegExpStatics *res, js::AutoStringRooter *tvr); | |
15656 | extern __attribute__((visibility ("default"))) void | |
15657 | js_RestoreRegExpStatics(JSContext *cx, js::RegExpStatics *res); | |
15658 | extern JSBool | |
15659 | js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp); | |
15660 | extern JSBool | |
15661 | js_regexp_exec(JSContext *cx, uintN argc, js::Value *vp); | |
15662 | extern JSBool | |
15663 | js_regexp_test(JSContext *cx, uintN argc, js::Value *vp); | |
15664 | namespace js { | |
15665 | static inline JSObject * | |
15666 | GetGlobalForScopeChain(JSContext *cx) | |
15667 | { | |
15668 | ((void) 0); | |
15669 | if (cx->hasfp()) | |
15670 | return cx->fp()->scopeChain().getGlobal(); | |
15671 | JSObject *scope = cx->globalObject; | |
15672 | if (!scope) { | |
15673 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_INACTIVE); | |
15674 | return __null; | |
15675 | } | |
15676 | OBJ_TO_INNER_OBJECT(cx, scope); | |
15677 | return scope; | |
15678 | } | |
15679 | } | |
15680 | inline | |
15681 | bool | |
15682 | JSContext::ensureGeneratorStackSpace() | |
15683 | { | |
15684 | bool ok = genStack.reserve(genStack.length() + 1); | |
15685 | if (!ok) | |
15686 | js_ReportOutOfMemory(this); | |
15687 | return ok; | |
15688 | } | |
15689 | JSStackFrame * | |
15690 | JSContext::computeNextFrame(JSStackFrame *fp) | |
15691 | { | |
15692 | JSStackFrame *next = __null; | |
15693 | for (js::StackSegment *ss = currentSegment; ; ss = ss->getPreviousInContext()) { | |
15694 | JSStackFrame *end = ss->getInitialFrame()->prev(); | |
15695 | for (JSStackFrame *f = ss->getCurrentFrame(); f != end; next = f, f = f->prev()) { | |
15696 | if (f == fp) | |
15697 | return next; | |
15698 | } | |
15699 | if (end != ss->getPreviousInContext()->getCurrentFrame()) | |
15700 | next = __null; | |
15701 | } | |
15702 | } | |
15703 | inline js::RegExpStatics * | |
15704 | JSContext::regExpStatics() | |
15705 | { | |
15706 | return js::RegExpStatics::extractFrom(js::GetGlobalForScopeChain(this)); | |
15707 | } | |
15708 | namespace js { | |
15709 | __attribute__((always_inline)) inline JSFrameRegs * | |
15710 | StackSegment::getCurrentRegs() const | |
15711 | { | |
15712 | ((void) 0); | |
15713 | return isActive() ? cx->regs : getSuspendedRegs(); | |
15714 | } | |
15715 | __attribute__((always_inline)) inline JSStackFrame * | |
15716 | StackSegment::getCurrentFrame() const | |
15717 | { | |
15718 | return getCurrentRegs()->fp; | |
15719 | } | |
15720 | inline Value * | |
15721 | StackSpace::firstUnused() const | |
15722 | { | |
15723 | StackSegment *seg = currentSegment; | |
15724 | if (!seg) { | |
15725 | ((void) 0); | |
15726 | return base; | |
15727 | } | |
15728 | if (seg->inContext()) { | |
15729 | Value *sp = seg->getCurrentRegs()->sp; | |
15730 | if (invokeArgEnd > sp) { | |
15731 | ((void) 0); | |
15732 | ((void) 0) | |
15733 | ; | |
15734 | return invokeArgEnd; | |
15735 | } | |
15736 | return sp; | |
15737 | } | |
15738 | ((void) 0); | |
15739 | ((void) 0); | |
15740 | return invokeArgEnd; | |
15741 | } | |
15742 | __attribute__((always_inline)) inline | |
15743 | bool | |
15744 | StackSpace::isCurrentAndActive(JSContext *cx) const | |
15745 | { | |
15746 | return currentSegment && | |
15747 | currentSegment->isActive() && | |
15748 | currentSegment == cx->getCurrentSegment(); | |
15749 | } | |
15750 | __attribute__((always_inline)) inline | |
15751 | bool | |
15752 | StackSpace::ensureSpace(JSContext *maybecx, Value *from, ptrdiff_t nvals) const | |
15753 | { | |
15754 | ((void) 0); | |
15755 | if (end - from < nvals) { | |
15756 | if (maybecx) | |
15757 | js_ReportOutOfScriptQuota(maybecx); | |
15758 | return false; | |
15759 | } | |
15760 | goto success; | |
15761 | success: | |
15762 | return true; | |
15763 | } | |
15764 | __attribute__((always_inline)) inline | |
15765 | bool | |
15766 | StackSpace::ensureEnoughSpaceToEnterTrace() | |
15767 | { | |
15768 | return end - firstUnused() > MAX_TRACE_SPACE_VALS; | |
15769 | } | |
15770 | __attribute__((always_inline)) inline | |
15771 | bool | |
15772 | StackSpace::EnsureSpaceCheck::operator()(const StackSpace &stack, JSContext *cx, | |
15773 | Value *from, uintN nvals) | |
15774 | { | |
15775 | return stack.ensureSpace(cx, from, nvals); | |
15776 | } | |
15777 | __attribute__((always_inline)) inline | |
15778 | bool | |
15779 | StackSpace::LimitCheck::operator()(const StackSpace &stack, JSContext *cx, | |
15780 | Value *from, uintN nvals) | |
15781 | { | |
15782 | ((void) 0); | |
15783 | ((void) 0); | |
15784 | if (*limit - from >= ptrdiff_t(nvals)) | |
15785 | return true; | |
15786 | if (stack.bumpCommitAndLimit(base, from, nvals, limit)) | |
15787 | return true; | |
15788 | js_ReportOverRecursed(cx); | |
15789 | return false; | |
15790 | } | |
15791 | __attribute__((always_inline)) inline | |
15792 | bool | |
15793 | StackSpace::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag) | |
15794 | { | |
15795 | if ((__builtin_expect((!isCurrentAndActive(cx)), 0))) | |
15796 | return pushSegmentForInvoke(cx, argc, ag); | |
15797 | Value *sp = cx->regs->sp; | |
15798 | Value *start = invokeArgEnd > sp ? invokeArgEnd : sp; | |
15799 | ((void) 0); | |
15800 | uintN nvals = 2 + argc; | |
15801 | if (!ensureSpace(cx, start, nvals)) | |
15802 | return false; | |
15803 | Value *vp = start; | |
15804 | Value *vpend = vp + nvals; | |
15805 | ag->prevInvokeArgEnd = invokeArgEnd; | |
15806 | invokeArgEnd = vpend; | |
15807 | ag->cx = cx; | |
15808 | ag->argv_ = vp + 2; | |
15809 | ag->argc_ = argc; | |
15810 | return true; | |
15811 | } | |
15812 | __attribute__((always_inline)) inline void | |
15813 | StackSpace::popInvokeArgs(const InvokeArgsGuard &ag) | |
15814 | { | |
15815 | if ((__builtin_expect((ag.seg != __null), 0))) { | |
15816 | popSegmentForInvoke(ag); | |
15817 | return; | |
15818 | } | |
15819 | ((void) 0); | |
15820 | ((void) 0); | |
15821 | ((void) 0); | |
15822 | ((void) 0); | |
15823 | invokeArgEnd = ag.prevInvokeArgEnd; | |
15824 | } | |
15825 | __attribute__((always_inline)) inline | |
15826 | InvokeArgsGuard::~InvokeArgsGuard() | |
15827 | { | |
15828 | if ((__builtin_expect((!pushed()), 0))) | |
15829 | return; | |
15830 | cx->stack().popInvokeArgs(*this); | |
15831 | } | |
15832 | template <class Check> | |
15833 | __attribute__((always_inline)) inline JSStackFrame * | |
15834 | StackSpace::getCallFrame(JSContext *cx, Value *firstUnused, uintN nactual, | |
15835 | JSFunction *fun, JSScript *script, uint32 *flags, | |
15836 | Check check) const | |
15837 | { | |
15838 | ((void) 0); | |
15839 | uintN nvals = VALUES_PER_STACK_FRAME + script->nslots; | |
15840 | uintN nformal = fun->nargs; | |
15841 | if (nactual == nformal) { | |
15842 | if ((__builtin_expect((!check(*this, cx, firstUnused, nvals)), 0))) | |
15843 | return __null; | |
15844 | return reinterpret_cast<JSStackFrame *>(firstUnused); | |
15845 | } | |
15846 | if (nactual < nformal) { | |
15847 | *flags |= JSFRAME_UNDERFLOW_ARGS; | |
15848 | uintN nmissing = nformal - nactual; | |
15849 | if ((__builtin_expect((!check(*this, cx, firstUnused, nmissing + nvals)), 0))) | |
15850 | return __null; | |
15851 | SetValueRangeToUndefined(firstUnused, nmissing); | |
15852 | return reinterpret_cast<JSStackFrame *>(firstUnused + nmissing); | |
15853 | } | |
15854 | *flags |= JSFRAME_OVERFLOW_ARGS; | |
15855 | uintN ncopy = 2 + nformal; | |
15856 | if ((__builtin_expect((!check(*this, cx, firstUnused, ncopy + nvals)), 0))) | |
15857 | return __null; | |
15858 | Value *dst = firstUnused; | |
15859 | Value *src = firstUnused - (2 + nactual); | |
15860 | PodCopy(dst, src, ncopy); | |
15861 | Debug_SetValueRangeToCrashOnTouch(src, ncopy); | |
15862 | return reinterpret_cast<JSStackFrame *>(firstUnused + ncopy); | |
15863 | } | |
15864 | __attribute__((always_inline)) inline | |
15865 | bool | |
15866 | StackSpace::getInvokeFrame(JSContext *cx, const CallArgs &args, | |
15867 | JSFunction *fun, JSScript *script, | |
15868 | uint32 *flags, InvokeFrameGuard *fg) const | |
15869 | { | |
15870 | ((void) 0); | |
15871 | Value *firstUnused = args.argv() + args.argc(); | |
15872 | fg->regs_.fp = getCallFrame(cx, firstUnused, args.argc(), fun, script, flags, | |
15873 | EnsureSpaceCheck()); | |
15874 | fg->regs_.sp = fg->regs_.fp->slots() + script->nfixed; | |
15875 | fg->regs_.pc = script->code; | |
15876 | return fg->regs_.fp != __null; | |
15877 | } | |
15878 | __attribute__((always_inline)) inline void | |
15879 | StackSpace::pushInvokeFrame(JSContext *cx, const CallArgs &args, | |
15880 | InvokeFrameGuard *fg) | |
15881 | { | |
15882 | ((void) 0); | |
15883 | if ((__builtin_expect((!currentSegment->inContext()), 0))) { | |
15884 | cx->pushSegmentAndFrame(currentSegment, fg->regs_); | |
15885 | } else { | |
15886 | fg->prevRegs_ = cx->regs; | |
15887 | cx->setCurrentRegs(&fg->regs_); | |
15888 | } | |
15889 | fg->cx_ = cx; | |
15890 | ((void) 0); | |
15891 | } | |
15892 | __attribute__((always_inline)) inline void | |
15893 | StackSpace::popInvokeFrame(const InvokeFrameGuard &fg) | |
15894 | { | |
15895 | JSContext *cx = fg.cx_; | |
15896 | JSStackFrame *fp = fg.regs_.fp; | |
15897 | ((void) 0); | |
15898 | if ((__builtin_expect((currentSegment->getInitialFrame() == fp), 0))) { | |
15899 | cx->popSegmentAndFrame(); | |
15900 | } else { | |
15901 | ((void) 0); | |
15902 | ((void) 0); | |
15903 | ((void) 0); | |
15904 | cx->setCurrentRegs(fg.prevRegs_); | |
15905 | } | |
15906 | } | |
15907 | __attribute__((always_inline)) inline void | |
15908 | InvokeFrameGuard::pop() | |
15909 | { | |
15910 | ((void) 0); | |
15911 | cx_->stack().popInvokeFrame(*this); | |
15912 | cx_ = __null; | |
15913 | } | |
15914 | __attribute__((always_inline)) inline JSStackFrame * | |
15915 | StackSpace::getInlineFrame(JSContext *cx, Value *sp, uintN nactual, | |
15916 | JSFunction *fun, JSScript *script, uint32 *flags) const | |
15917 | { | |
15918 | ((void) 0); | |
15919 | ((void) 0); | |
15920 | ((void) 0); | |
15921 | return getCallFrame(cx, sp, nactual, fun, script, flags, EnsureSpaceCheck()); | |
15922 | } | |
15923 | __attribute__((always_inline)) inline JSStackFrame * | |
15924 | StackSpace::getInlineFrameWithinLimit(JSContext *cx, Value *sp, uintN nactual, | |
15925 | JSFunction *fun, JSScript *script, uint32 *flags, | |
15926 | JSStackFrame *base, Value **limit) const | |
15927 | { | |
15928 | ((void) 0); | |
15929 | ((void) 0); | |
15930 | ((void) 0); | |
15931 | return getCallFrame(cx, sp, nactual, fun, script, flags, LimitCheck(base, limit)); | |
15932 | } | |
15933 | __attribute__((always_inline)) inline void | |
15934 | StackSpace::pushInlineFrame(JSContext *cx, JSScript *script, JSStackFrame *fp, | |
15935 | JSFrameRegs *regs) | |
15936 | { | |
15937 | ((void) 0); | |
15938 | ((void) 0); | |
15939 | regs->fp = fp; | |
15940 | regs->pc = script->code; | |
15941 | regs->sp = fp->slots() + script->nfixed; | |
15942 | } | |
15943 | __attribute__((always_inline)) inline void | |
15944 | StackSpace::popInlineFrame(JSContext *cx, JSStackFrame *prev, Value *newsp) | |
15945 | { | |
15946 | ((void) 0); | |
15947 | ((void) 0); | |
15948 | ((void) 0); | |
15949 | ((void) 0); | |
15950 | ((void) 0); | |
15951 | JSFrameRegs *regs = cx->regs; | |
15952 | regs->pc = prev->pc(cx, regs->fp); | |
15953 | regs->fp = prev; | |
15954 | regs->sp = newsp; | |
15955 | } | |
15956 | __attribute__((always_inline)) inline Value * | |
15957 | StackSpace::getStackLimit(JSContext *cx) | |
15958 | { | |
15959 | Value *sp = cx->regs->sp; | |
15960 | ((void) 0); | |
15961 | Value *limit = sp + STACK_QUOTA; | |
15962 | if ((__builtin_expect((limit <= end), 1))) | |
15963 | return limit; | |
15964 | uintN minimum = cx->fp()->numSlots() + VALUES_PER_STACK_FRAME; | |
15965 | return ensureSpace(cx, sp, minimum) ? sp + minimum : __null; | |
15966 | } | |
15967 | inline | |
15968 | FrameRegsIter::FrameRegsIter(JSContext *cx) | |
15969 | : cx(cx) | |
15970 | { | |
15971 | curseg = cx->getCurrentSegment(); | |
15972 | if ((__builtin_expect((!curseg || !curseg->isActive()), 0))) { | |
15973 | initSlow(); | |
15974 | return; | |
15975 | } | |
15976 | ((void) 0); | |
15977 | curfp = cx->regs->fp; | |
15978 | cursp = cx->regs->sp; | |
15979 | curpc = cx->regs->pc; | |
15980 | return; | |
15981 | } | |
15982 | inline FrameRegsIter & | |
15983 | FrameRegsIter::operator++() | |
15984 | { | |
15985 | JSStackFrame *fp = curfp; | |
15986 | JSStackFrame *prev = curfp = curfp->prev(); | |
15987 | if (!prev) | |
15988 | return *this; | |
15989 | curpc = curfp->pc(cx, fp); | |
15990 | if ((__builtin_expect((fp == curseg->getInitialFrame()), 0))) { | |
15991 | incSlow(fp, prev); | |
15992 | return *this; | |
15993 | } | |
15994 | cursp = fp->formalArgsEnd(); | |
15995 | return *this; | |
15996 | } | |
15997 | class AutoNamespaceArray : protected AutoGCRooter { | |
15998 | public: | |
15999 | AutoNamespaceArray(JSContext *cx) : AutoGCRooter(cx, NAMESPACES) { | |
16000 | array.init(); | |
16001 | } | |
16002 | ~AutoNamespaceArray() { | |
16003 | array.finish(context); | |
16004 | } | |
16005 | uint32 length() const { return array.length; } | |
16006 | public: | |
16007 | friend void AutoGCRooter::trace(JSTracer *trc); | |
16008 | JSXMLArray array; | |
16009 | }; | |
16010 | template <class T1> inline void | |
16011 | assertSameCompartment(JSContext *cx, T1 t1) | |
16012 | { | |
16013 | } | |
16014 | template <class T1, class T2> inline void | |
16015 | assertSameCompartment(JSContext *cx, T1 t1, T2 t2) | |
16016 | { | |
16017 | } | |
16018 | template <class T1, class T2, class T3> inline void | |
16019 | assertSameCompartment(JSContext *cx, T1 t1, T2 t2, T3 t3) | |
16020 | { | |
16021 | } | |
16022 | template <class T1, class T2, class T3, class T4> inline void | |
16023 | assertSameCompartment(JSContext *cx, T1 t1, T2 t2, T3 t3, T4 t4) | |
16024 | { | |
16025 | } | |
16026 | template <class T1, class T2, class T3, class T4, class T5> inline void | |
16027 | assertSameCompartment(JSContext *cx, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) | |
16028 | { | |
16029 | } | |
16030 | __attribute__((always_inline)) inline | |
16031 | bool | |
16032 | CallJSNative(JSContext *cx, js::Native native, uintN argc, js::Value *vp) | |
16033 | { | |
16034 | assertSameCompartment(cx, ValueArray(vp, argc + 2)); | |
16035 | JSBool ok = native(cx, argc, vp); | |
16036 | if (ok) { | |
16037 | assertSameCompartment(cx, vp[0]); | |
16038 | ((void) 0); | |
16039 | } | |
16040 | return ok; | |
16041 | } | |
16042 | extern JSBool CallOrConstructBoundFunction(JSContext *, uintN, js::Value *); | |
16043 | __attribute__((always_inline)) inline | |
16044 | bool | |
16045 | CallJSNativeConstructor(JSContext *cx, js::Native native, uintN argc, js::Value *vp) | |
16046 | { | |
16047 | ((void) 0); | |
16048 | if (!CallJSNative(cx, native, argc, vp)) | |
16049 | return false; | |
16050 | extern JSBool proxy_Construct(JSContext *, uintN, Value *); | |
16051 | ((void) 0) | |
16052 | ; | |
16053 | return true; | |
16054 | } | |
16055 | __attribute__((always_inline)) inline | |
16056 | bool | |
16057 | CallJSPropertyOp(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp) | |
16058 | { | |
16059 | assertSameCompartment(cx, obj, id, *vp); | |
16060 | JSBool ok = op(cx, obj, id, vp); | |
16061 | if (ok) | |
16062 | assertSameCompartment(cx, obj, *vp); | |
16063 | return ok; | |
16064 | } | |
16065 | __attribute__((always_inline)) inline | |
16066 | bool | |
16067 | CallJSPropertyOpSetter(JSContext *cx, js::StrictPropertyOp op, JSObject *obj, jsid id, | |
16068 | JSBool strict, js::Value *vp) | |
16069 | { | |
16070 | assertSameCompartment(cx, obj, id, *vp); | |
16071 | return op(cx, obj, id, strict, vp); | |
16072 | } | |
16073 | inline | |
16074 | bool | |
16075 | CallSetter(JSContext *cx, JSObject *obj, jsid id, js::StrictPropertyOp op, uintN attrs, | |
16076 | uintN shortid, JSBool strict, js::Value *vp) | |
16077 | { | |
16078 | if (attrs & 0x20) | |
16079 | return ExternalGetOrSet(cx, obj, id, CastAsObjectJsval(op), JSACC_WRITE, 1, vp, vp); | |
16080 | if (attrs & 0x10) | |
16081 | return js_ReportGetterOnlyAssignment(cx); | |
16082 | if (attrs & 0x100) | |
16083 | id = INT_TO_JSID(shortid); | |
16084 | return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp); | |
16085 | } | |
16086 | static inline void | |
16087 | LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj) | |
16088 | { | |
16089 | if (!obj->parent) | |
16090 | LeaveTrace(cx); | |
16091 | } | |
16092 | static inline void | |
16093 | LeaveTraceIfArgumentsObject(JSContext *cx, JSObject *obj) | |
16094 | { | |
16095 | if (obj->isArguments()) | |
16096 | LeaveTrace(cx); | |
16097 | } | |
16098 | static inline JSBool | |
16099 | CanLeaveTrace(JSContext *cx) | |
16100 | { | |
16101 | ((void) 0); | |
16102 | return (JSIntn)0; | |
16103 | } | |
16104 | } | |
16105 | inline void | |
16106 | JSContext::setPendingException(js::Value v) { | |
16107 | this->throwing = true; | |
16108 | this->exception = v; | |
16109 | assertSameCompartment(this, v); | |
16110 | } | |
16111 | namespace js { | |
16112 | static inline | |
16113 | bool | |
16114 | CheckStringLength(JSContext *cx, size_t length) | |
16115 | { | |
16116 | if ((__builtin_expect((length > JSString::MAX_LENGTH), 0))) { | |
16117 | js_ReportAllocationOverflow(cx); | |
16118 | return false; | |
16119 | } | |
16120 | return true; | |
16121 | } | |
16122 | class StringBuffer | |
16123 | { | |
16124 | typedef Vector<jschar, 32> CharBuffer; | |
16125 | CharBuffer cb; | |
16126 | static inline bool checkLength(JSContext *cx, size_t length); | |
16127 | inline bool checkLength(size_t length); | |
16128 | JSContext *context() const { return cb.allocPolicy().context(); } | |
16129 | public: | |
16130 | explicit inline StringBuffer(JSContext *cx); | |
16131 | bool reserve(size_t len); | |
16132 | bool resize(size_t len); | |
16133 | bool append(const jschar c); | |
16134 | bool append(const jschar *chars, size_t len); | |
16135 | bool append(const jschar *begin, const jschar *end); | |
16136 | bool append(JSString *str); | |
16137 | bool append(JSAtom *atom); | |
16138 | bool appendN(const jschar c, size_t n); | |
16139 | bool appendInflated(const char *cstr, size_t len); | |
16140 | JSAtom *atomize(uintN flags = 0); | |
16141 | static JSAtom *atomize(JSContext *cx, const CharBuffer &cb, uintN flags = 0); | |
16142 | static JSAtom *atomize(JSContext *cx, const jschar *begin, size_t length, uintN flags = 0); | |
16143 | void replaceRawBuffer(jschar *chars, size_t len) { cb.replaceRawBuffer(chars, len); } | |
16144 | jschar *begin() { return cb.begin(); } | |
16145 | jschar *end() { return cb.end(); } | |
16146 | const jschar *begin() const { return cb.begin(); } | |
16147 | const jschar *end() const { return cb.end(); } | |
16148 | bool empty() const { return cb.empty(); } | |
16149 | inline jsint length() const; | |
16150 | JSFlatString *finishString(); | |
16151 | template <size_t ArrayLength> | |
16152 | bool append(const char (&array)[ArrayLength]) { | |
16153 | return cb.append(array, array + ArrayLength - 1); | |
16154 | } | |
16155 | }; | |
16156 | inline | |
16157 | StringBuffer::StringBuffer(JSContext *cx) | |
16158 | : cb(cx) | |
16159 | {} | |
16160 | inline | |
16161 | bool | |
16162 | StringBuffer::reserve(size_t len) | |
16163 | { | |
16164 | if (!checkLength(len)) | |
16165 | return false; | |
16166 | return cb.reserve(len); | |
16167 | } | |
16168 | inline | |
16169 | bool | |
16170 | StringBuffer::resize(size_t len) | |
16171 | { | |
16172 | if (!checkLength(len)) | |
16173 | return false; | |
16174 | return cb.resize(len); | |
16175 | } | |
16176 | inline | |
16177 | bool | |
16178 | StringBuffer::append(const jschar c) | |
16179 | { | |
16180 | if (!checkLength(cb.length() + 1)) | |
16181 | return false; | |
16182 | return cb.append(c); | |
16183 | } | |
16184 | inline | |
16185 | bool | |
16186 | StringBuffer::append(const jschar *chars, size_t len) | |
16187 | { | |
16188 | if (!checkLength(cb.length() + len)) | |
16189 | return false; | |
16190 | return cb.append(chars, len); | |
16191 | } | |
16192 | inline | |
16193 | bool | |
16194 | StringBuffer::append(const jschar *begin, const jschar *end) | |
16195 | { | |
16196 | if (!checkLength(cb.length() + (end - begin))) | |
16197 | return false; | |
16198 | return cb.append(begin, end); | |
16199 | } | |
16200 | inline | |
16201 | bool | |
16202 | StringBuffer::append(JSString *str) | |
16203 | { | |
16204 | JSLinearString *linear = str->ensureLinear(context()); | |
16205 | size_t strLen = linear->length(); | |
16206 | if (!checkLength(cb.length() + strLen)) | |
16207 | return false; | |
16208 | return cb.append(linear->chars(), strLen); | |
16209 | } | |
16210 | inline | |
16211 | bool | |
16212 | StringBuffer::append(JSAtom *atom) | |
16213 | { | |
16214 | size_t strLen = atom->length(); | |
16215 | if (!checkLength(cb.length() + strLen)) | |
16216 | return false; | |
16217 | return cb.append(atom->chars(), strLen); | |
16218 | } | |
16219 | inline | |
16220 | bool | |
16221 | StringBuffer::appendN(const jschar c, size_t n) | |
16222 | { | |
16223 | if (!checkLength(cb.length() + n)) | |
16224 | return false; | |
16225 | return cb.appendN(c, n); | |
16226 | } | |
16227 | inline | |
16228 | bool | |
16229 | StringBuffer::appendInflated(const char *cstr, size_t cstrlen) | |
16230 | { | |
16231 | size_t lengthBefore = length(); | |
16232 | if (!cb.growByUninitialized(cstrlen)) | |
16233 | return false; | |
16234 | js_InflateStringToBuffer(context(), cstr, cstrlen, begin() + lengthBefore, &cstrlen); | |
16235 | ((void) 0); | |
16236 | return true; | |
16237 | } | |
16238 | inline jsint | |
16239 | StringBuffer::length() const | |
16240 | { | |
16241 | typedef int js_static_assert65[(jsint(JSString::MAX_LENGTH) == JSString::MAX_LENGTH) ? 1 : -1]; | |
16242 | ((void) 0); | |
16243 | return jsint(cb.length()); | |
16244 | } | |
16245 | inline | |
16246 | bool | |
16247 | StringBuffer::checkLength(size_t length) | |
16248 | { | |
16249 | return CheckStringLength(context(), length); | |
16250 | } | |
16251 | } | |
16252 | inline JSFlatString * | |
16253 | JSString::unitString(jschar c) | |
16254 | { | |
16255 | ((void) 0); | |
16256 | return const_cast<JSString *>(&unitStringTable[c])->assertIsFlat(); | |
16257 | } | |
16258 | inline JSLinearString * | |
16259 | JSString::getUnitString(JSContext *cx, JSString *str, size_t index) | |
16260 | { | |
16261 | ((void) 0); | |
16262 | const jschar *chars = str->getChars(cx); | |
16263 | if (!chars) | |
16264 | return __null; | |
16265 | jschar c = chars[index]; | |
16266 | if (c < UNIT_STRING_LIMIT) | |
16267 | return unitString(c); | |
16268 | return js_NewDependentString(cx, str, index, 1); | |
16269 | } | |
16270 | inline JSFlatString * | |
16271 | JSString::length2String(jschar c1, jschar c2) | |
16272 | { | |
16273 | ((void) 0); | |
16274 | ((void) 0); | |
16275 | return const_cast<JSString *> ( | |
16276 | &length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]] | |
16277 | )->assertIsFlat(); | |
16278 | } | |
16279 | inline JSFlatString * | |
16280 | JSString::length2String(uint32 i) | |
16281 | { | |
16282 | ((void) 0); | |
16283 | return length2String('0' + i / 10, '0' + i % 10); | |
16284 | } | |
16285 | inline JSFlatString * | |
16286 | JSString::intString(jsint i) | |
16287 | { | |
16288 | jsuint u = jsuint(i); | |
16289 | ((void) 0); | |
16290 | return const_cast<JSString *>(JSString::intStringTable[u])->assertIsFlat(); | |
16291 | } | |
16292 | inline JSFlatString * | |
16293 | JSString::lookupStaticString(const jschar *chars, size_t length) | |
16294 | { | |
16295 | if (length == 1) { | |
16296 | if (chars[0] < UNIT_STRING_LIMIT) | |
16297 | return unitString(chars[0]); | |
16298 | } | |
16299 | if (length == 2) { | |
16300 | if (fitsInSmallChar(chars[0]) && fitsInSmallChar(chars[1])) | |
16301 | return length2String(chars[0], chars[1]); | |
16302 | } | |
16303 | typedef int js_static_assert66[(INT_STRING_LIMIT <= 999) ? 1 : -1]; | |
16304 | if (length == 3) { | |
16305 | if ('1' <= chars[0] && chars[0] <= '9' && | |
16306 | '0' <= chars[1] && chars[1] <= '9' && | |
16307 | '0' <= chars[2] && chars[2] <= '9') { | |
16308 | jsint i = (chars[0] - '0') * 100 + | |
16309 | (chars[1] - '0') * 10 + | |
16310 | (chars[2] - '0'); | |
16311 | if (jsuint(i) < INT_STRING_LIMIT) | |
16312 | return intString(i); | |
16313 | } | |
16314 | } | |
16315 | return __null; | |
16316 | } | |
16317 | inline void | |
16318 | JSString::finalize(JSContext *cx) { | |
16319 | ((void) 0); | |
16320 | ; | |
16321 | if (isDependent()) { | |
16322 | ; | |
16323 | } else if (isFlat()) { | |
16324 | cx->runtime->stringMemoryUsed -= length() * 2; | |
16325 | cx->free(const_cast<jschar *>(flatChars())); | |
16326 | } | |
16327 | } | |
16328 | inline void | |
16329 | JSShortString::finalize(JSContext *cx) | |
16330 | { | |
16331 | ((void) 0); | |
16332 | ((void) 0); | |
16333 | ; | |
16334 | } | |
16335 | inline void | |
16336 | JSExternalString::finalize(JSContext *cx) | |
16337 | { | |
16338 | ((void) 0); | |
16339 | ((void) 0); | |
16340 | ((void) 0); | |
16341 | ; | |
16342 | jschar *chars = const_cast<jschar *>(flatChars()); | |
16343 | if (!chars) | |
16344 | return; | |
16345 | JSStringFinalizeOp finalizer = str_finalizers[externalStringType]; | |
16346 | if (finalizer) | |
16347 | finalizer(cx, this); | |
16348 | } | |
16349 | inline void | |
16350 | JSExternalString::finalize() | |
16351 | { | |
16352 | ((void) 0); | |
16353 | JSStringFinalizeOp finalizer = str_finalizers[externalStringType]; | |
16354 | if (finalizer) { | |
16355 | finalizer(__null, this); | |
16356 | } | |
16357 | } | |
16358 | namespace js { | |
16359 | class RopeBuilder { | |
16360 | JSContext *cx; | |
16361 | JSString *res; | |
16362 | public: | |
16363 | RopeBuilder(JSContext *cx) | |
16364 | : cx(cx), res(cx->runtime->emptyString) | |
16365 | {} | |
16366 | inline bool append(JSString *str) { | |
16367 | res = js_ConcatStrings(cx, res, str); | |
16368 | return !!res; | |
16369 | } | |
16370 | inline JSString *result() { | |
16371 | return res; | |
16372 | } | |
16373 | }; | |
16374 | class StringSegmentRange | |
16375 | { | |
16376 | Vector<JSString *, 32> stack; | |
16377 | JSString *cur; | |
16378 | bool settle(JSString *str) { | |
16379 | while (str->isRope()) { | |
16380 | if (!stack.append(str->ropeRight())) | |
16381 | return false; | |
16382 | str = str->ropeLeft(); | |
16383 | } | |
16384 | cur = str; | |
16385 | return true; | |
16386 | } | |
16387 | public: | |
16388 | StringSegmentRange(JSContext *cx) | |
16389 | : stack(cx), cur(__null) | |
16390 | {} | |
16391 | __attribute__((warn_unused_result)) bool init(JSString *str) { | |
16392 | ((void) 0); | |
16393 | return settle(str); | |
16394 | } | |
16395 | bool empty() const { | |
16396 | return cur == __null; | |
16397 | } | |
16398 | JSString *front() const { | |
16399 | ((void) 0); | |
16400 | return cur; | |
16401 | } | |
16402 | __attribute__((warn_unused_result)) bool popFront() { | |
16403 | ((void) 0); | |
16404 | if (stack.empty()) { | |
16405 | cur = __null; | |
16406 | return true; | |
16407 | } | |
16408 | return settle(stack.popCopy()); | |
16409 | } | |
16410 | }; | |
16411 | } | |
16412 | namespace js { | |
16413 | struct PropertyTable { | |
16414 | static const uint32 MAX_LINEAR_SEARCHES = 7; | |
16415 | static const uint32 MIN_SIZE_LOG2 = 4; | |
16416 | static const uint32 MIN_SIZE = ((JSUint32)1 << (MIN_SIZE_LOG2)); | |
16417 | int hashShift; | |
16418 | uint32 entryCount; | |
16419 | uint32 removedCount; | |
16420 | uint32 freelist; | |
16421 | js::Shape **entries; | |
16422 | PropertyTable(uint32 nentries) | |
16423 | : hashShift(32 - MIN_SIZE_LOG2), | |
16424 | entryCount(nentries), | |
16425 | removedCount(0), | |
16426 | freelist(0xffffffff) | |
16427 | { | |
16428 | } | |
16429 | ~PropertyTable() { | |
16430 | js_free(entries); | |
16431 | } | |
16432 | uint32 capacity() const { return ((JSUint32)1 << (32 - hashShift)); } | |
16433 | bool needsToGrow() const { | |
16434 | uint32 size = capacity(); | |
16435 | return entryCount + removedCount >= size - (size >> 2); | |
16436 | } | |
16437 | bool grow(JSContext *cx); | |
16438 | bool init(JSRuntime *rt, js::Shape *lastProp); | |
16439 | bool change(int log2Delta, JSContext *cx); | |
16440 | js::Shape **search(jsid id, bool adding); | |
16441 | }; | |
16442 | } | |
16443 | struct JSObject; | |
16444 | namespace js { | |
16445 | class PropertyTree; | |
16446 | static inline PropertyOp | |
16447 | CastAsPropertyOp(js::Class *clasp) | |
16448 | { | |
16449 | return (__extension__ (PropertyOp) (size_t) (clasp)); | |
16450 | } | |
16451 | struct Shape : public JSObjectMap | |
16452 | { | |
16453 | friend struct ::JSObject; | |
16454 | friend struct ::JSFunction; | |
16455 | friend class js::PropertyTree; | |
16456 | friend class js::Bindings; | |
16457 | friend bool IsShapeAboutToBeFinalized(JSContext *cx, const js::Shape *shape); | |
16458 | union { | |
16459 | mutable size_t numLinearSearches; | |
16460 | mutable js::PropertyTable *table; | |
16461 | }; | |
16462 | public: | |
16463 | inline void freeTable(JSContext *cx); | |
16464 | static bool initEmptyShapes(JSCompartment *comp); | |
16465 | static void finishEmptyShapes(JSCompartment *comp); | |
16466 | jsid id; | |
16467 | protected: | |
16468 | union { | |
16469 | js::PropertyOp rawGetter; | |
16470 | JSObject *getterObj; | |
16471 | js::Class *clasp; | |
16472 | }; | |
16473 | union { | |
16474 | js::StrictPropertyOp rawSetter; | |
16475 | JSObject *setterObj; | |
16476 | }; | |
16477 | public: | |
16478 | uint32 slot; | |
16479 | private: | |
16480 | uint8 attrs; | |
16481 | mutable uint8 flags; | |
16482 | public: | |
16483 | int16 shortid; | |
16484 | protected: | |
16485 | mutable js::Shape *parent; | |
16486 | union { | |
16487 | mutable js::KidsPointer kids; | |
16488 | mutable js::Shape **listp; | |
16489 | }; | |
16490 | static inline js::Shape **search(JSRuntime *rt, js::Shape **startp, jsid id, | |
16491 | bool adding = false); | |
16492 | static js::Shape *newDictionaryShape(JSContext *cx, const js::Shape &child, js::Shape **listp); | |
16493 | static js::Shape *newDictionaryList(JSContext *cx, js::Shape **listp); | |
16494 | inline void removeFromDictionary(JSObject *obj) const; | |
16495 | inline void insertIntoDictionary(js::Shape **dictp); | |
16496 | js::Shape *getChild(JSContext *cx, const js::Shape &child, js::Shape **listp); | |
16497 | bool hashify(JSRuntime *rt); | |
16498 | bool hasTable() const { | |
16499 | return numLinearSearches > PropertyTable::MAX_LINEAR_SEARCHES; | |
16500 | } | |
16501 | js::PropertyTable *getTable() const { | |
16502 | ((void) 0); | |
16503 | return table; | |
16504 | } | |
16505 | void setTable(js::PropertyTable *t) const { | |
16506 | ((void) 0); | |
16507 | table = t; | |
16508 | } | |
16509 | void setParent(js::Shape *p) { | |
16510 | typedef int js_static_assert67[(uint32(0xffffffff) == ~uint32(0)) ? 1 : -1]; | |
16511 | if (p) | |
16512 | slotSpan = ((p->slotSpan)>(slot + 1)?(p->slotSpan):(slot + 1)); | |
16513 | ((void) 0); | |
16514 | parent = p; | |
16515 | } | |
16516 | void insertFree(js::Shape **freep) { | |
16517 | id = ((jsid)0x2); | |
16518 | parent = *freep; | |
16519 | if (parent) | |
16520 | parent->listp = &parent; | |
16521 | listp = freep; | |
16522 | *freep = this; | |
16523 | } | |
16524 | void removeFree() { | |
16525 | ((void) 0); | |
16526 | *listp = parent; | |
16527 | if (parent) | |
16528 | parent->listp = listp; | |
16529 | } | |
16530 | public: | |
16531 | const js::Shape *previous() const { | |
16532 | return parent; | |
16533 | } | |
16534 | class Range { | |
16535 | protected: | |
16536 | friend struct Shape; | |
16537 | const Shape *cursor; | |
16538 | const Shape *end; | |
16539 | public: | |
16540 | Range(const Shape *shape) : cursor(shape) { } | |
16541 | bool empty() const { | |
16542 | ((void) 0); | |
16543 | return !cursor->parent; | |
16544 | } | |
16545 | const Shape &front() const { | |
16546 | ((void) 0); | |
16547 | return *cursor; | |
16548 | } | |
16549 | void popFront() { | |
16550 | ((void) 0); | |
16551 | cursor = cursor->parent; | |
16552 | } | |
16553 | }; | |
16554 | Range all() const { | |
16555 | return Range(this); | |
16556 | } | |
16557 | protected: | |
16558 | enum { | |
16559 | MARK = 0x01, | |
16560 | SHARED_EMPTY = 0x02, | |
16561 | SHAPE_REGEN = 0x04, | |
16562 | IN_DICTIONARY = 0x08, | |
16563 | FROZEN = 0x10 | |
16564 | }; | |
16565 | Shape(jsid id, js::PropertyOp getter, js::StrictPropertyOp setter, uint32 slot, uintN attrs, | |
16566 | uintN flags, intN shortid, uint32 shape = INVALID_SHAPE, uint32 slotSpan = 0); | |
16567 | Shape(JSCompartment *comp, Class *aclasp); | |
16568 | bool marked() const { return (flags & MARK) != 0; } | |
16569 | void mark() const { flags |= MARK; } | |
16570 | void clearMark() { flags &= ~MARK; } | |
16571 | bool hasRegenFlag() const { return (flags & SHAPE_REGEN) != 0; } | |
16572 | void setRegenFlag() { flags |= SHAPE_REGEN; } | |
16573 | void clearRegenFlag() { flags &= ~SHAPE_REGEN; } | |
16574 | bool inDictionary() const { return (flags & IN_DICTIONARY) != 0; } | |
16575 | bool frozen() const { return (flags & FROZEN) != 0; } | |
16576 | void setFrozen() { flags |= FROZEN; } | |
16577 | bool isEmptyShape() const { ((void) 0); return !parent; } | |
16578 | public: | |
16579 | enum { | |
16580 | ALIAS = 0x20, | |
16581 | HAS_SHORTID = 0x40, | |
16582 | METHOD = 0x80, | |
16583 | PUBLIC_FLAGS = ALIAS | HAS_SHORTID | METHOD | |
16584 | }; | |
16585 | uintN getFlags() const { return flags & PUBLIC_FLAGS; } | |
16586 | bool isAlias() const { return (flags & ALIAS) != 0; } | |
16587 | bool hasShortID() const { return (flags & HAS_SHORTID) != 0; } | |
16588 | bool isMethod() const { return (flags & METHOD) != 0; } | |
16589 | JSObject &methodObject() const { ((void) 0); return *getterObj; } | |
16590 | js::PropertyOp getter() const { return rawGetter; } | |
16591 | bool hasDefaultGetter() const { return !rawGetter; } | |
16592 | js::PropertyOp getterOp() const { ((void) 0); return rawGetter; } | |
16593 | JSObject *getterObject() const { ((void) 0); return getterObj; } | |
16594 | js::Value getterValue() const { | |
16595 | ((void) 0); | |
16596 | return getterObj ? js::ObjectValue(*getterObj) : js::UndefinedValue(); | |
16597 | } | |
16598 | js::Value getterOrUndefined() const { | |
16599 | return hasGetterValue() && getterObj ? js::ObjectValue(*getterObj) : js::UndefinedValue(); | |
16600 | } | |
16601 | js::StrictPropertyOp setter() const { return rawSetter; } | |
16602 | bool hasDefaultSetter() const { return !rawSetter; } | |
16603 | js::StrictPropertyOp setterOp() const { ((void) 0); return rawSetter; } | |
16604 | JSObject *setterObject() const { ((void) 0); return setterObj; } | |
16605 | js::Value setterValue() const { | |
16606 | ((void) 0); | |
16607 | return setterObj ? js::ObjectValue(*setterObj) : js::UndefinedValue(); | |
16608 | } | |
16609 | js::Value setterOrUndefined() const { | |
16610 | return hasSetterValue() && setterObj ? js::ObjectValue(*setterObj) : js::UndefinedValue(); | |
16611 | } | |
16612 | inline JSDHashNumber hash() const; | |
16613 | inline bool matches(const js::Shape *p) const; | |
16614 | inline bool matchesParamsAfterId(js::PropertyOp agetter, js::StrictPropertyOp asetter, | |
16615 | uint32 aslot, uintN aattrs, uintN aflags, | |
16616 | intN ashortid) const; | |
16617 | bool get(JSContext* cx, JSObject *receiver, JSObject *obj, JSObject *pobj, js::Value* vp) const; | |
16618 | bool set(JSContext* cx, JSObject *obj, bool strict, js::Value* vp) const; | |
16619 | inline bool isSharedPermanent() const; | |
16620 | void trace(JSTracer *trc) const; | |
16621 | bool hasSlot() const { return (attrs & 0x40) == 0; } | |
16622 | uint8 attributes() const { return attrs; } | |
16623 | bool configurable() const { return (attrs & 0x04) == 0; } | |
16624 | bool enumerable() const { return (attrs & 0x01) != 0; } | |
16625 | bool writable() const { | |
16626 | return (attrs & 0x02) == 0; | |
16627 | } | |
16628 | bool hasGetterValue() const { return attrs & 0x10; } | |
16629 | bool hasSetterValue() const { return attrs & 0x20; } | |
16630 | bool hasDefaultGetterOrIsMethod() const { | |
16631 | return hasDefaultGetter() || isMethod(); | |
16632 | } | |
16633 | bool isDataDescriptor() const { | |
16634 | return (attrs & (0x20 | 0x10)) == 0; | |
16635 | } | |
16636 | bool isAccessorDescriptor() const { | |
16637 | return (attrs & (0x20 | 0x10)) != 0; | |
16638 | } | |
16639 | bool shadowable() const { | |
16640 | ((void) 0); | |
16641 | return hasSlot() || (attrs & 0x80); | |
16642 | } | |
16643 | uint32 entryCount() const { | |
16644 | if (hasTable()) | |
16645 | return getTable()->entryCount; | |
16646 | const js::Shape *shape = this; | |
16647 | uint32 count = 0; | |
16648 | for (js::Shape::Range r = shape->all(); !r.empty(); r.popFront()) | |
16649 | ++count; | |
16650 | return count; | |
16651 | } | |
16652 | }; | |
16653 | struct EmptyShape : public js::Shape | |
16654 | { | |
16655 | EmptyShape(JSCompartment *comp, js::Class *aclasp); | |
16656 | js::Class *getClass() const { return clasp; }; | |
16657 | static EmptyShape *create(JSCompartment *comp, js::Class *clasp) { | |
16658 | js::Shape *eprop = comp->propertyTree.newShapeUnchecked(); | |
16659 | if (!eprop) | |
16660 | return __null; | |
16661 | return new (eprop) EmptyShape(comp, clasp); | |
16662 | } | |
16663 | static EmptyShape *create(JSContext *cx, js::Class *clasp) { | |
16664 | js::Shape *eprop = ((cx)->compartment->propertyTree).newShape(cx); | |
16665 | if (!eprop) | |
16666 | return __null; | |
16667 | return new (eprop) EmptyShape(cx->compartment, clasp); | |
16668 | } | |
16669 | }; | |
16670 | } | |
16671 | inline js::Shape ** | |
16672 | JSObject::nativeSearch(jsid id, bool adding) | |
16673 | { | |
16674 | return js::Shape::search(compartment()->rt, &lastProp, id, adding); | |
16675 | } | |
16676 | inline const js::Shape * | |
16677 | JSObject::nativeLookup(jsid id) | |
16678 | { | |
16679 | ((void) 0); | |
16680 | return ((js::Shape *) (jsuword(*(nativeSearch(id))) & ~(jsuword(1)))); | |
16681 | } | |
16682 | inline | |
16683 | bool | |
16684 | JSObject::nativeContains(jsid id) | |
16685 | { | |
16686 | return nativeLookup(id) != __null; | |
16687 | } | |
16688 | inline | |
16689 | bool | |
16690 | JSObject::nativeContains(const js::Shape &shape) | |
16691 | { | |
16692 | return nativeLookup(shape.id) == &shape; | |
16693 | } | |
16694 | inline const js::Shape * | |
16695 | JSObject::lastProperty() const | |
16696 | { | |
16697 | ((void) 0); | |
16698 | ((void) 0); | |
16699 | return lastProp; | |
16700 | } | |
16701 | inline | |
16702 | bool | |
16703 | JSObject::nativeEmpty() const | |
16704 | { | |
16705 | return lastProperty()->isEmptyShape(); | |
16706 | } | |
16707 | inline | |
16708 | bool | |
16709 | JSObject::inDictionaryMode() const | |
16710 | { | |
16711 | return lastProperty()->inDictionary(); | |
16712 | } | |
16713 | inline uint32 | |
16714 | JSObject::propertyCount() const | |
16715 | { | |
16716 | return lastProperty()->entryCount(); | |
16717 | } | |
16718 | inline | |
16719 | bool | |
16720 | JSObject::hasPropertyTable() const | |
16721 | { | |
16722 | return lastProperty()->hasTable(); | |
16723 | } | |
16724 | inline void | |
16725 | JSObject::setLastProperty(const js::Shape *shape) | |
16726 | { | |
16727 | ((void) 0); | |
16728 | ((void) 0); | |
16729 | ((void) 0); | |
16730 | ((void) 0); | |
16731 | lastProp = const_cast<js::Shape *>(shape); | |
16732 | } | |
16733 | inline void | |
16734 | JSObject::removeLastProperty() | |
16735 | { | |
16736 | ((void) 0); | |
16737 | ((void) 0); | |
16738 | lastProp = lastProp->parent; | |
16739 | } | |
16740 | namespace js { | |
16741 | inline void | |
16742 | Shape::removeFromDictionary(JSObject *obj) const | |
16743 | { | |
16744 | ((void) 0); | |
16745 | ((void) 0); | |
16746 | ((void) 0); | |
16747 | ((void) 0); | |
16748 | ((void) 0); | |
16749 | ((void) 0); | |
16750 | ((void) 0); | |
16751 | ((void) 0); | |
16752 | ((void) 0); | |
16753 | if (parent) | |
16754 | parent->listp = listp; | |
16755 | *listp = parent; | |
16756 | listp = __null; | |
16757 | } | |
16758 | inline void | |
16759 | Shape::insertIntoDictionary(js::Shape **dictp) | |
16760 | { | |
16761 | ((void) 0); | |
16762 | ((void) 0); | |
16763 | ((void) 0); | |
16764 | ((void) 0); | |
16765 | ((void) 0); | |
16766 | ((void) 0); | |
16767 | ((void) 0); | |
16768 | setParent(*dictp); | |
16769 | if (parent) | |
16770 | parent->listp = &parent; | |
16771 | listp = dictp; | |
16772 | *dictp = this; | |
16773 | } | |
16774 | } | |
16775 | extern uint32 | |
16776 | js_GenerateShape(JSRuntime *rt); | |
16777 | extern uint32 | |
16778 | js_GenerateShape(JSContext *cx); | |
16779 | namespace js { | |
16780 | __attribute__((always_inline)) inline js::Shape ** | |
16781 | Shape::search(JSRuntime *rt, js::Shape **startp, jsid id, bool adding) | |
16782 | { | |
16783 | js::Shape *start = *startp; | |
16784 | ; | |
16785 | if (start->hasTable()) | |
16786 | return start->getTable()->search(id, adding); | |
16787 | if (start->numLinearSearches == PropertyTable::MAX_LINEAR_SEARCHES) { | |
16788 | if (start->hashify(rt)) | |
16789 | return start->getTable()->search(id, adding); | |
16790 | ((void) 0); | |
16791 | } else { | |
16792 | ((void) 0); | |
16793 | start->numLinearSearches++; | |
16794 | } | |
16795 | js::Shape **spp; | |
16796 | for (spp = startp; js::Shape *shape = *spp; spp = &shape->parent) { | |
16797 | if (shape->id == id) { | |
16798 | ; | |
16799 | return spp; | |
16800 | } | |
16801 | } | |
16802 | ; | |
16803 | return spp; | |
16804 | } | |
16805 | inline | |
16806 | bool | |
16807 | Shape::isSharedPermanent() const | |
16808 | { | |
16809 | return (~attrs & (0x40 | 0x04)) == 0; | |
16810 | } | |
16811 | } | |
16812 | inline | |
16813 | bool | |
16814 | js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp) | |
16815 | { | |
16816 | JSString *str; | |
16817 | JSAtom *atom; | |
16818 | if (v.isString()) { | |
16819 | str = v.toString(); | |
16820 | if (str->isAtomized()) { | |
16821 | *atomp = (((void) 0), (JSAtom *)str); | |
16822 | return true; | |
16823 | } | |
16824 | } else { | |
16825 | str = js_ValueToString(cx, v); | |
16826 | if (!str) | |
16827 | return false; | |
16828 | } | |
16829 | atom = js_AtomizeString(cx, str, 0); | |
16830 | if (!atom) | |
16831 | return false; | |
16832 | *atomp = atom; | |
16833 | return true; | |
16834 | } | |
16835 | inline | |
16836 | bool | |
16837 | js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp) | |
16838 | { | |
16839 | JSAtom *atom; | |
16840 | if (js_ValueToAtom(cx, v, &atom)) { | |
16841 | *idp = ATOM_TO_JSID(atom); | |
16842 | return true; | |
16843 | } | |
16844 | return false; | |
16845 | } | |
16846 | inline | |
16847 | bool | |
16848 | js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, | |
16849 | jsid *idp) | |
16850 | { | |
16851 | ((void) 0); | |
16852 | extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *, | |
16853 | const js::Value &, jsid *); | |
16854 | if (idval.isObject()) | |
16855 | return js_InternNonIntElementIdSlow(cx, obj, idval, idp); | |
16856 | return js_ValueToStringId(cx, idval, idp); | |
16857 | } | |
16858 | inline | |
16859 | bool | |
16860 | js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, | |
16861 | jsid *idp, js::Value *vp) | |
16862 | { | |
16863 | ((void) 0); | |
16864 | extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *, | |
16865 | const js::Value &, | |
16866 | jsid *, js::Value *); | |
16867 | if (idval.isObject()) | |
16868 | return js_InternNonIntElementIdSlow(cx, obj, idval, idp, vp); | |
16869 | JSAtom *atom; | |
16870 | if (js_ValueToAtom(cx, idval, &atom)) { | |
16871 | *idp = ATOM_TO_JSID(atom); | |
16872 | vp->setString((atom)); | |
16873 | return true; | |
16874 | } | |
16875 | return false; | |
16876 | } | |
16877 | inline | |
16878 | bool | |
16879 | js_Int32ToId(JSContext* cx, int32 index, jsid* id) | |
16880 | { | |
16881 | if (INT_FITS_IN_JSID(index)) { | |
16882 | *id = INT_TO_JSID(index); | |
16883 | return true; | |
16884 | } | |
16885 | JSString* str = js_NumberToString(cx, index); | |
16886 | if (!str) | |
16887 | return false; | |
16888 | return js_ValueToStringId(cx, js::StringValue(str), id); | |
16889 | } | |
16890 | namespace js { | |
16891 | class Probes { | |
16892 | static const char nullName[]; | |
16893 | static const char *FunctionClassname(const JSFunction *fun); | |
16894 | static const char *ScriptFilename(JSScript *script); | |
16895 | static int FunctionLineNumber(JSContext *cx, const JSFunction *fun); | |
16896 | static const char *FunctionName(JSContext *cx, const JSFunction *fun, JSAutoByteString *bytes); | |
16897 | static void enterJSFunImpl(JSContext *cx, JSFunction *fun, JSScript *script); | |
16898 | static void handleFunctionReturn(JSContext *cx, JSFunction *fun, JSScript *script); | |
16899 | static void finalizeObjectImpl(JSObject *obj); | |
16900 | public: | |
16901 | static bool callTrackingActive(JSContext *); | |
16902 | static void enterJSFun(JSContext *, JSFunction *, JSScript *, int counter = 1); | |
16903 | static void exitJSFun(JSContext *, JSFunction *, JSScript *, int counter = 0); | |
16904 | static void startExecution(JSContext *cx, JSScript *script); | |
16905 | static void stopExecution(JSContext *cx, JSScript *script); | |
16906 | static void resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize); | |
16907 | static void createObject(JSContext *cx, JSObject *obj); | |
16908 | static void resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize); | |
16909 | static void finalizeObject(JSObject *obj); | |
16910 | static void createString(JSContext *cx, JSString *string, size_t length); | |
16911 | static void finalizeString(JSString *string); | |
16912 | static void compileScriptBegin(JSContext *cx, const char *filename, int lineno); | |
16913 | static void compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno); | |
16914 | static void calloutBegin(JSContext *cx, JSFunction *fun); | |
16915 | static void calloutEnd(JSContext *cx, JSFunction *fun); | |
16916 | static void acquireMemory(JSContext *cx, void *address, size_t nbytes); | |
16917 | static void releaseMemory(JSContext *cx, void *address, size_t nbytes); | |
16918 | static void GCStart(JSCompartment *compartment); | |
16919 | static void GCEnd(JSCompartment *compartment); | |
16920 | static void GCStartMarkPhase(JSCompartment *compartment); | |
16921 | static void GCEndMarkPhase(JSCompartment *compartment); | |
16922 | static void GCStartSweepPhase(JSCompartment *compartment); | |
16923 | static void GCEndSweepPhase(JSCompartment *compartment); | |
16924 | static bool CustomMark(JSString *string); | |
16925 | static bool CustomMark(const char *string); | |
16926 | static bool CustomMark(int marker); | |
16927 | static bool startProfiling(); | |
16928 | static void stopProfiling(); | |
16929 | }; | |
16930 | inline | |
16931 | bool | |
16932 | Probes::callTrackingActive(JSContext *cx) | |
16933 | { | |
16934 | return false; | |
16935 | } | |
16936 | inline void | |
16937 | Probes::enterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) | |
16938 | { | |
16939 | } | |
16940 | inline void | |
16941 | Probes::exitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) | |
16942 | { | |
16943 | } | |
16944 | inline void | |
16945 | Probes::createObject(JSContext *cx, JSObject *obj) | |
16946 | { | |
16947 | } | |
16948 | inline void | |
16949 | Probes::finalizeObject(JSObject *obj) | |
16950 | { | |
16951 | } | |
16952 | inline void | |
16953 | Probes::startExecution(JSContext *cx, JSScript *script) | |
16954 | { | |
16955 | } | |
16956 | inline void | |
16957 | Probes::stopExecution(JSContext *cx, JSScript *script) | |
16958 | { | |
16959 | } | |
16960 | inline void Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize) {} | |
16961 | inline void Probes::resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize) {} | |
16962 | inline void Probes::createString(JSContext *cx, JSString *string, size_t length) {} | |
16963 | inline void Probes::finalizeString(JSString *string) {} | |
16964 | inline void Probes::compileScriptBegin(JSContext *cx, const char *filename, int lineno) {} | |
16965 | inline void Probes::compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno) {} | |
16966 | inline void Probes::calloutBegin(JSContext *cx, JSFunction *fun) {} | |
16967 | inline void Probes::calloutEnd(JSContext *cx, JSFunction *fun) {} | |
16968 | inline void Probes::acquireMemory(JSContext *cx, void *address, size_t nbytes) {} | |
16969 | inline void Probes::releaseMemory(JSContext *cx, void *address, size_t nbytes) {} | |
16970 | inline void Probes::GCStart(JSCompartment *compartment) {} | |
16971 | inline void Probes::GCEnd(JSCompartment *compartment) {} | |
16972 | inline void Probes::GCStartMarkPhase(JSCompartment *compartment) {} | |
16973 | inline void Probes::GCEndMarkPhase(JSCompartment *compartment) {} | |
16974 | inline void Probes::GCStartSweepPhase(JSCompartment *compartment) {} | |
16975 | inline void Probes::GCEndSweepPhase(JSCompartment *compartment) {} | |
16976 | inline bool Probes::CustomMark(JSString *string) { return (JSIntn)1; } | |
16977 | inline bool Probes::CustomMark(const char *string) { return (JSIntn)1; } | |
16978 | inline bool Probes::CustomMark(int marker) { return (JSIntn)1; } | |
16979 | struct AutoFunctionCallProbe { | |
16980 | JSContext * const cx; | |
16981 | JSFunction *fun; | |
16982 | JSScript *script; | |
16983 | ||
16984 | AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, JSScript *script | |
16985 | ) | |
16986 | : cx(cx), fun(fun), script(script) | |
16987 | { | |
16988 | do { } while (0); | |
16989 | Probes::enterJSFun(cx, fun, script); | |
16990 | } | |
16991 | ~AutoFunctionCallProbe() { | |
16992 | Probes::exitJSFun(cx, fun, script); | |
16993 | } | |
16994 | }; | |
16995 | } | |
16996 | inline | |
16997 | bool | |
16998 | JSFunction::inStrictMode() const | |
16999 | { | |
17000 | return script()->strictModeCode; | |
17001 | } | |
17002 | inline void | |
17003 | JSStackFrame::initPrev(JSContext *cx) | |
17004 | { | |
17005 | ((void) 0); | |
17006 | if (JSFrameRegs *regs = cx->regs) { | |
17007 | prev_ = regs->fp; | |
17008 | prevpc_ = regs->pc; | |
17009 | ((void) 0) | |
17010 | ; | |
17011 | } else { | |
17012 | prev_ = __null; | |
17013 | } | |
17014 | } | |
17015 | inline void | |
17016 | JSStackFrame::resetGeneratorPrev(JSContext *cx) | |
17017 | { | |
17018 | flags_ |= JSFRAME_HAS_PREVPC; | |
17019 | initPrev(cx); | |
17020 | } | |
17021 | inline void | |
17022 | JSStackFrame::initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun, | |
17023 | uint32 nactual, uint32 flagsArg) | |
17024 | { | |
17025 | ((void) 0) | |
17026 | ; | |
17027 | ((void) 0); | |
17028 | flags_ = JSFRAME_FUNCTION | JSFRAME_HAS_PREVPC | JSFRAME_HAS_SCOPECHAIN | flagsArg; | |
17029 | exec.fun = fun; | |
17030 | args.nactual = nactual; | |
17031 | scopeChain_ = callee.getParent(); | |
17032 | initPrev(cx); | |
17033 | ((void) 0); | |
17034 | ((void) 0); | |
17035 | ((void) 0); | |
17036 | ((void) 0); | |
17037 | } | |
17038 | inline void | |
17039 | JSStackFrame::resetInvokeCallFrame() | |
17040 | { | |
17041 | ((void) 0) | |
17042 | ; | |
17043 | flags_ &= JSFRAME_FUNCTION | | |
17044 | JSFRAME_OVERFLOW_ARGS | | |
17045 | JSFRAME_HAS_PREVPC | | |
17046 | JSFRAME_UNDERFLOW_ARGS; | |
17047 | ((void) 0); | |
17048 | scopeChain_ = callee().getParent(); | |
17049 | } | |
17050 | inline void | |
17051 | JSStackFrame::initCallFrameCallerHalf(JSContext *cx, uint32 flagsArg, | |
17052 | void *ncode) | |
17053 | { | |
17054 | ((void) 0) | |
17055 | ; | |
17056 | flags_ = JSFRAME_FUNCTION | flagsArg; | |
17057 | prev_ = cx->regs->fp; | |
17058 | ncode_ = ncode; | |
17059 | } | |
17060 | inline void | |
17061 | JSStackFrame::initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual) | |
17062 | { | |
17063 | exec.fun = fun; | |
17064 | if (flags_ & (JSFRAME_OVERFLOW_ARGS | JSFRAME_UNDERFLOW_ARGS)) | |
17065 | args.nactual = nactual; | |
17066 | } | |
17067 | inline void | |
17068 | JSStackFrame::initCallFrameLatePrologue() | |
17069 | { | |
17070 | SetValueRangeToUndefined(slots(), script()->nfixed); | |
17071 | } | |
17072 | inline void | |
17073 | JSStackFrame::initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev, uint32 flagsArg) | |
17074 | { | |
17075 | ((void) 0); | |
17076 | ((void) 0); | |
17077 | ((void) 0); | |
17078 | js::Value *dstvp = (js::Value *)this - 2; | |
17079 | js::Value *srcvp = prev->flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL) | |
17080 | ? (js::Value *)prev - 2 | |
17081 | : prev->formalArgs() - 2; | |
17082 | dstvp[0] = srcvp[0]; | |
17083 | dstvp[1] = srcvp[1]; | |
17084 | ((void) 0) | |
17085 | ; | |
17086 | flags_ = flagsArg | JSFRAME_HAS_PREVPC | JSFRAME_HAS_SCOPECHAIN | | |
17087 | (prev->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL | JSFRAME_HAS_CALL_OBJ)); | |
17088 | if (isFunctionFrame()) { | |
17089 | exec = prev->exec; | |
17090 | args.script = script; | |
17091 | } else { | |
17092 | exec.script = script; | |
17093 | } | |
17094 | scopeChain_ = &prev->scopeChain(); | |
17095 | ((void) 0); | |
17096 | prev_ = prev; | |
17097 | prevpc_ = prev->pc(cx); | |
17098 | ((void) 0); | |
17099 | ((void) 0); | |
17100 | setAnnotation(prev->annotation()); | |
17101 | } | |
17102 | inline void | |
17103 | JSStackFrame::initGlobalFrame(JSScript *script, JSObject &chain, uint32 flagsArg) | |
17104 | { | |
17105 | ((void) 0); | |
17106 | js::Value *vp = (js::Value *)this - 2; | |
17107 | vp[0].setUndefined(); | |
17108 | vp[1].setUndefined(); | |
17109 | flags_ = flagsArg | JSFRAME_GLOBAL | JSFRAME_HAS_PREVPC | JSFRAME_HAS_SCOPECHAIN; | |
17110 | exec.script = script; | |
17111 | args.script = (JSScript *)0xbad; | |
17112 | scopeChain_ = &chain; | |
17113 | prev_ = __null; | |
17114 | ((void) 0); | |
17115 | ((void) 0); | |
17116 | ((void) 0); | |
17117 | } | |
17118 | inline void | |
17119 | JSStackFrame::initDummyFrame(JSContext *cx, JSObject &chain) | |
17120 | { | |
17121 | js::PodZero(this); | |
17122 | flags_ = JSFRAME_DUMMY | JSFRAME_HAS_PREVPC | JSFRAME_HAS_SCOPECHAIN; | |
17123 | initPrev(cx); | |
17124 | chain.isGlobal(); | |
17125 | setScopeChainNoCallObj(chain); | |
17126 | } | |
17127 | inline void | |
17128 | JSStackFrame::stealFrameAndSlots(js::Value *vp, JSStackFrame *otherfp, | |
17129 | js::Value *othervp, js::Value *othersp) | |
17130 | { | |
17131 | ((void) 0); | |
17132 | ((void) 0); | |
17133 | ((void) 0); | |
17134 | ((void) 0); | |
17135 | PodCopy(vp, othervp, othersp - othervp); | |
17136 | ((void) 0); | |
17137 | if (otherfp->hasOverflowArgs()) | |
17138 | Debug_SetValueRangeToCrashOnTouch(othervp, othervp + 2 + otherfp->numFormalArgs()); | |
17139 | if (hasCallObj()) { | |
17140 | callObj().setPrivate(this); | |
17141 | otherfp->flags_ &= ~JSFRAME_HAS_CALL_OBJ; | |
17142 | if (js_IsNamedLambda(fun())) { | |
17143 | JSObject *env = callObj().getParent(); | |
17144 | ((void) 0); | |
17145 | env->setPrivate(this); | |
17146 | } | |
17147 | } | |
17148 | if (hasArgsObj()) { | |
17149 | JSObject &args = argsObj(); | |
17150 | ((void) 0); | |
17151 | if (args.isNormalArguments()) | |
17152 | args.setPrivate(this); | |
17153 | else | |
17154 | ((void) 0); | |
17155 | otherfp->flags_ &= ~JSFRAME_HAS_ARGS_OBJ; | |
17156 | } | |
17157 | } | |
17158 | inline js::Value & | |
17159 | JSStackFrame::canonicalActualArg(uintN i) const | |
17160 | { | |
17161 | if (i < numFormalArgs()) | |
17162 | return formalArg(i); | |
17163 | ((void) 0); | |
17164 | return actualArgs()[i]; | |
17165 | } | |
17166 | template <class Op> | |
17167 | inline void | |
17168 | JSStackFrame::forEachCanonicalActualArg(Op op) | |
17169 | { | |
17170 | uintN nformal = fun()->nargs; | |
17171 | js::Value *formals = formalArgsEnd() - nformal; | |
17172 | uintN nactual = numActualArgs(); | |
17173 | if (nactual <= nformal) { | |
17174 | uintN i = 0; | |
17175 | js::Value *actualsEnd = formals + nactual; | |
17176 | for (js::Value *p = formals; p != actualsEnd; ++p, ++i) | |
17177 | op(i, p); | |
17178 | } else { | |
17179 | uintN i = 0; | |
17180 | js::Value *formalsEnd = formalArgsEnd(); | |
17181 | for (js::Value *p = formals; p != formalsEnd; ++p, ++i) | |
17182 | op(i, p); | |
17183 | js::Value *actuals = formalsEnd - (nactual + 2); | |
17184 | js::Value *actualsEnd = formals - 2; | |
17185 | for (js::Value *p = actuals; p != actualsEnd; ++p, ++i) | |
17186 | op(i, p); | |
17187 | } | |
17188 | } | |
17189 | template <class Op> | |
17190 | inline void | |
17191 | JSStackFrame::forEachFormalArg(Op op) | |
17192 | { | |
17193 | js::Value *formals = formalArgsEnd() - fun()->nargs; | |
17194 | js::Value *formalsEnd = formalArgsEnd(); | |
17195 | uintN i = 0; | |
17196 | for (js::Value *p = formals; p != formalsEnd; ++p, ++i) | |
17197 | op(i, p); | |
17198 | } | |
17199 | namespace js { | |
17200 | struct CopyNonHoleArgsTo | |
17201 | { | |
17202 | CopyNonHoleArgsTo(JSObject *aobj, Value *dst) : aobj(aobj), dst(dst) {} | |
17203 | JSObject *aobj; | |
17204 | Value *dst; | |
17205 | void operator()(uintN argi, Value *src) { | |
17206 | if (aobj->getArgsElement(argi).isMagic(JS_ARGS_HOLE)) | |
17207 | dst->setUndefined(); | |
17208 | else | |
17209 | *dst = *src; | |
17210 | ++dst; | |
17211 | } | |
17212 | }; | |
17213 | struct CopyTo | |
17214 | { | |
17215 | Value *dst; | |
17216 | CopyTo(Value *dst) : dst(dst) {} | |
17217 | void operator()(uintN, Value *src) { | |
17218 | *dst++ = *src; | |
17219 | } | |
17220 | }; | |
17221 | } | |
17222 | __attribute__((always_inline)) inline void | |
17223 | JSStackFrame::clearMissingArgs() | |
17224 | { | |
17225 | if (flags_ & JSFRAME_UNDERFLOW_ARGS) | |
17226 | SetValueRangeToUndefined(formalArgs() + numActualArgs(), formalArgsEnd()); | |
17227 | } | |
17228 | inline | |
17229 | bool | |
17230 | JSStackFrame::computeThis(JSContext *cx) | |
17231 | { | |
17232 | js::Value &thisv = thisValue(); | |
17233 | if (thisv.isObject()) | |
17234 | return true; | |
17235 | if (isFunctionFrame()) { | |
17236 | if (fun()->inStrictMode()) | |
17237 | return true; | |
17238 | ((void) 0); | |
17239 | } | |
17240 | if (!js::BoxThisForVp(cx, &thisv - 1)) | |
17241 | return false; | |
17242 | return true; | |
17243 | } | |
17244 | inline JSObject & | |
17245 | JSStackFrame::varobj(js::StackSegment *seg) const | |
17246 | { | |
17247 | ((void) 0); | |
17248 | return isFunctionFrame() ? callObj() : seg->getInitialVarObj(); | |
17249 | } | |
17250 | inline JSObject & | |
17251 | JSStackFrame::varobj(JSContext *cx) const | |
17252 | { | |
17253 | ((void) 0); | |
17254 | return isFunctionFrame() ? callObj() : cx->activeSegment()->getInitialVarObj(); | |
17255 | } | |
17256 | inline uintN | |
17257 | JSStackFrame::numActualArgs() const | |
17258 | { | |
17259 | ((void) 0); | |
17260 | if ((__builtin_expect((flags_ & (JSFRAME_OVERFLOW_ARGS | JSFRAME_UNDERFLOW_ARGS)), 0))) | |
17261 | return hasArgsObj() ? argsObj().getArgsInitialLength() : args.nactual; | |
17262 | return numFormalArgs(); | |
17263 | } | |
17264 | inline js::Value * | |
17265 | JSStackFrame::actualArgs() const | |
17266 | { | |
17267 | ((void) 0); | |
17268 | js::Value *argv = formalArgs(); | |
17269 | if ((__builtin_expect((flags_ & JSFRAME_OVERFLOW_ARGS), 0))) { | |
17270 | uintN nactual = hasArgsObj() ? argsObj().getArgsInitialLength() : args.nactual; | |
17271 | return argv - (2 + nactual); | |
17272 | } | |
17273 | return argv; | |
17274 | } | |
17275 | inline js::Value * | |
17276 | JSStackFrame::actualArgsEnd() const | |
17277 | { | |
17278 | ((void) 0); | |
17279 | if ((__builtin_expect((flags_ & JSFRAME_OVERFLOW_ARGS), 0))) | |
17280 | return formalArgs() - 2; | |
17281 | return formalArgs() + numActualArgs(); | |
17282 | } | |
17283 | inline void | |
17284 | JSStackFrame::setArgsObj(JSObject &obj) | |
17285 | { | |
17286 | ((void) 0); | |
17287 | ((void) 0); | |
17288 | args.obj = &obj; | |
17289 | flags_ |= JSFRAME_HAS_ARGS_OBJ; | |
17290 | } | |
17291 | inline void | |
17292 | JSStackFrame::clearArgsObj() | |
17293 | { | |
17294 | ((void) 0); | |
17295 | args.nactual = args.obj->getArgsInitialLength(); | |
17296 | flags_ ^= JSFRAME_HAS_ARGS_OBJ; | |
17297 | } | |
17298 | inline void | |
17299 | JSStackFrame::setScopeChainNoCallObj(JSObject &obj) | |
17300 | { | |
17301 | scopeChain_ = &obj; | |
17302 | flags_ |= JSFRAME_HAS_SCOPECHAIN; | |
17303 | ((void) 0); | |
17304 | } | |
17305 | inline void | |
17306 | JSStackFrame::setScopeChainAndCallObj(JSObject &obj) | |
17307 | { | |
17308 | ((void) 0); | |
17309 | ((void) 0); | |
17310 | scopeChain_ = &obj; | |
17311 | flags_ |= JSFRAME_HAS_SCOPECHAIN | JSFRAME_HAS_CALL_OBJ; | |
17312 | } | |
17313 | inline void | |
17314 | JSStackFrame::clearCallObj() | |
17315 | { | |
17316 | ((void) 0); | |
17317 | flags_ ^= JSFRAME_HAS_CALL_OBJ; | |
17318 | } | |
17319 | inline JSObject & | |
17320 | JSStackFrame::callObj() const | |
17321 | { | |
17322 | ((void) 0); | |
17323 | JSObject *pobj = &scopeChain(); | |
17324 | while ((__builtin_expect((pobj->getClass() != &js_CallClass), 0))) { | |
17325 | ((void) 0); | |
17326 | pobj = pobj->getParent(); | |
17327 | } | |
17328 | return *pobj; | |
17329 | } | |
17330 | inline JSObject * | |
17331 | JSStackFrame::maybeCallObj() const | |
17332 | { | |
17333 | return hasCallObj() ? &callObj() : __null; | |
17334 | } | |
17335 | namespace js { | |
17336 | class AutoPreserveEnumerators { | |
17337 | JSContext *cx; | |
17338 | JSObject *enumerators; | |
17339 | public: | |
17340 | AutoPreserveEnumerators(JSContext *cx) : cx(cx), enumerators(cx->enumerators) | |
17341 | { | |
17342 | } | |
17343 | ~AutoPreserveEnumerators() | |
17344 | { | |
17345 | cx->enumerators = enumerators; | |
17346 | } | |
17347 | }; | |
17348 | struct AutoInterpPreparer { | |
17349 | JSContext *cx; | |
17350 | JSScript *script; | |
17351 | AutoInterpPreparer(JSContext *cx, JSScript *script) | |
17352 | : cx(cx), script(script) | |
17353 | { | |
17354 | cx->interpLevel++; | |
17355 | } | |
17356 | ~AutoInterpPreparer() | |
17357 | { | |
17358 | --cx->interpLevel; | |
17359 | } | |
17360 | }; | |
17361 | inline void | |
17362 | PutActivationObjects(JSContext *cx, JSStackFrame *fp) | |
17363 | { | |
17364 | ((void) 0); | |
17365 | ((void) 0); | |
17366 | if (fp->hasCallObj()) { | |
17367 | js_PutCallObject(cx, fp); | |
17368 | } else if (fp->hasArgsObj()) { | |
17369 | js_PutArgsObject(cx, fp); | |
17370 | } | |
17371 | } | |
17372 | inline void | |
17373 | PutOwnedActivationObjects(JSContext *cx, JSStackFrame *fp) | |
17374 | { | |
17375 | ((void) 0); | |
17376 | if (!fp->isEvalFrame() || fp->script()->strictModeCode) | |
17377 | PutActivationObjects(cx, fp); | |
17378 | } | |
17379 | class InvokeSessionGuard | |
17380 | { | |
17381 | InvokeArgsGuard args_; | |
17382 | InvokeFrameGuard frame_; | |
17383 | Value savedCallee_, savedThis_; | |
17384 | Value *formals_, *actuals_; | |
17385 | unsigned nformals_; | |
17386 | JSScript *script_; | |
17387 | Value *stackLimit_; | |
17388 | jsbytecode *stop_; | |
17389 | bool optimized() const { return frame_.pushed(); } | |
17390 | public: | |
17391 | InvokeSessionGuard() : args_(), frame_() {} | |
17392 | inline ~InvokeSessionGuard(); | |
17393 | bool start(JSContext *cx, const Value &callee, const Value &thisv, uintN argc); | |
17394 | bool invoke(JSContext *cx) const; | |
17395 | bool started() const { | |
17396 | return args_.pushed(); | |
17397 | } | |
17398 | Value &operator[](unsigned i) const { | |
17399 | ((void) 0); | |
17400 | Value &arg = i < nformals_ ? formals_[i] : actuals_[i]; | |
17401 | ((void) 0); | |
17402 | ((void) 0); | |
17403 | return arg; | |
17404 | } | |
17405 | uintN argc() const { | |
17406 | return args_.argc(); | |
17407 | } | |
17408 | const Value &rval() const { | |
17409 | return optimized() ? frame_.fp()->returnValue() : args_.rval(); | |
17410 | } | |
17411 | }; | |
17412 | inline | |
17413 | InvokeSessionGuard::~InvokeSessionGuard() | |
17414 | { | |
17415 | if (frame_.pushed()) | |
17416 | PutActivationObjects(frame_.pushedFrameContext(), frame_.fp()); | |
17417 | } | |
17418 | inline | |
17419 | bool | |
17420 | InvokeSessionGuard::invoke(JSContext *cx) const | |
17421 | { | |
17422 | formals_[-2] = savedCallee_; | |
17423 | formals_[-1] = savedThis_; | |
17424 | if (!optimized()) | |
17425 | return Invoke(cx, args_, 0); | |
17426 | JSStackFrame *fp = frame_.fp(); | |
17427 | fp->clearMissingArgs(); | |
17428 | PutActivationObjects(cx, frame_.fp()); | |
17429 | fp->resetInvokeCallFrame(); | |
17430 | SetValueRangeToUndefined(fp->slots(), script_->nfixed); | |
17431 | JSBool ok; | |
17432 | { | |
17433 | AutoPreserveEnumerators preserve(cx); | |
17434 | Probes::enterJSFun(cx, fp->fun(), script_); | |
17435 | cx->regs->pc = script_->code; | |
17436 | ok = Interpret(cx, cx->fp()); | |
17437 | Probes::exitJSFun(cx, fp->fun(), script_); | |
17438 | } | |
17439 | return ok; | |
17440 | } | |
17441 | namespace detail { | |
17442 | template<typename T> class PrimitiveBehavior { }; | |
17443 | template<> | |
17444 | class PrimitiveBehavior<JSString *> { | |
17445 | public: | |
17446 | static inline bool isType(const Value &v) { return v.isString(); } | |
17447 | static inline JSString *extract(const Value &v) { return v.toString(); } | |
17448 | static inline Class *getClass() { return &js_StringClass; } | |
17449 | }; | |
17450 | template<> | |
17451 | class PrimitiveBehavior<bool> { | |
17452 | public: | |
17453 | static inline bool isType(const Value &v) { return v.isBoolean(); } | |
17454 | static inline bool extract(const Value &v) { return v.toBoolean(); } | |
17455 | static inline Class *getClass() { return &js_BooleanClass; } | |
17456 | }; | |
17457 | template<> | |
17458 | class PrimitiveBehavior<double> { | |
17459 | public: | |
17460 | static inline bool isType(const Value &v) { return v.isNumber(); } | |
17461 | static inline double extract(const Value &v) { return v.toNumber(); } | |
17462 | static inline Class *getClass() { return &js_NumberClass; } | |
17463 | }; | |
17464 | } | |
17465 | inline | |
17466 | bool | |
17467 | ComputeImplicitThis(JSContext *cx, JSObject *obj, const Value &funval, Value *vp) | |
17468 | { | |
17469 | vp->setUndefined(); | |
17470 | if (!funval.isObject()) | |
17471 | return true; | |
17472 | if (!obj->isGlobal()) { | |
17473 | if (IsCacheableNonGlobalScope(obj)) | |
17474 | return true; | |
17475 | } else { | |
17476 | JSObject *callee = &funval.toObject(); | |
17477 | if (callee->isProxy()) { | |
17478 | callee = callee->unwrap(); | |
17479 | if (!callee->isFunction()) | |
17480 | return true; | |
17481 | } | |
17482 | if (callee->isFunction()) { | |
17483 | JSFunction *fun = callee->getFunctionPrivate(); | |
17484 | if (fun->isInterpreted() && fun->inStrictMode()) | |
17485 | return true; | |
17486 | } | |
17487 | if (callee->getGlobal() == cx->fp()->scopeChain().getGlobal()) | |
17488 | return true;; | |
17489 | } | |
17490 | obj = obj->thisObject(cx); | |
17491 | if (!obj) | |
17492 | return false; | |
17493 | vp->setObject(*obj); | |
17494 | return true; | |
17495 | } | |
17496 | template <typename T> | |
17497 | bool | |
17498 | GetPrimitiveThis(JSContext *cx, Value *vp, T *v) | |
17499 | { | |
17500 | typedef detail::PrimitiveBehavior<T> Behavior; | |
17501 | const Value &thisv = vp[1]; | |
17502 | if (Behavior::isType(thisv)) { | |
17503 | *v = Behavior::extract(thisv); | |
17504 | return true; | |
17505 | } | |
17506 | if (thisv.isObject() && thisv.toObject().getClass() == Behavior::getClass()) { | |
17507 | *v = Behavior::extract(thisv.toObject().getPrimitiveThis()); | |
17508 | return true; | |
17509 | } | |
17510 | ReportIncompatibleMethod(cx, vp, Behavior::getClass()); | |
17511 | return false; | |
17512 | } | |
17513 | __attribute__((always_inline)) inline JSObject * | |
17514 | ValuePropertyBearer(JSContext *cx, const Value &v, int spindex) | |
17515 | { | |
17516 | if (v.isObject()) | |
17517 | return &v.toObject(); | |
17518 | JSProtoKey protoKey; | |
17519 | if (v.isString()) { | |
17520 | protoKey = JSProto_String; | |
17521 | } else if (v.isNumber()) { | |
17522 | protoKey = JSProto_Number; | |
17523 | } else if (v.isBoolean()) { | |
17524 | protoKey = JSProto_Boolean; | |
17525 | } else { | |
17526 | ((void) 0); | |
17527 | js_ReportIsNullOrUndefined(cx, spindex, v, __null); | |
17528 | return __null; | |
17529 | } | |
17530 | JSObject *pobj; | |
17531 | if (!js_GetClassPrototype(cx, __null, protoKey, &pobj)) | |
17532 | return __null; | |
17533 | return pobj; | |
17534 | } | |
17535 | static inline | |
17536 | bool | |
17537 | ScriptEpilogue(JSContext *cx, JSStackFrame *fp, JSBool ok) | |
17538 | { | |
17539 | if (!fp->isExecuteFrame()) | |
17540 | Probes::exitJSFun(cx, fp->maybeFun(), fp->maybeScript()); | |
17541 | JSInterpreterHook hook = | |
17542 | fp->isExecuteFrame() ? cx->debugHooks->executeHook : cx->debugHooks->callHook; | |
17543 | void* hookData; | |
17544 | if ((__builtin_expect((hook != __null), 0)) && (hookData = fp->maybeHookData())) | |
17545 | hook(cx, fp, (JSIntn)0, &ok, hookData); | |
17546 | if (fp->isEvalFrame()) { | |
17547 | if (fp->script()->strictModeCode) { | |
17548 | ((void) 0); | |
17549 | ((void) 0); | |
17550 | ((void) 0); | |
17551 | ((void) 0); | |
17552 | js_PutCallObject(cx, fp); | |
17553 | } | |
17554 | } else { | |
17555 | if (fp->isFunctionFrame() && !fp->isYielding()) { | |
17556 | ((void) 0); | |
17557 | PutActivationObjects(cx, fp); | |
17558 | } | |
17559 | } | |
17560 | if (fp->isConstructing() && ok) { | |
17561 | if (fp->returnValue().isPrimitive()) | |
17562 | fp->setReturnValue(ObjectValue(fp->constructorThis())); | |
17563 | ; | |
17564 | } | |
17565 | return ok; | |
17566 | } | |
17567 | } | |
17568 | extern js::Class js_DateClass; | |
17569 | inline | |
17570 | bool | |
17571 | JSObject::isDate() const | |
17572 | { | |
17573 | return getClass() == &js_DateClass; | |
17574 | } | |
17575 | extern JSObject * | |
17576 | js_InitDateClass(JSContext *cx, JSObject *obj); | |
17577 | extern __attribute__((visibility ("default"))) JSObject* | |
17578 | js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time); | |
17579 | extern __attribute__((visibility ("default"))) JSObject* | |
17580 | js_NewDateObject(JSContext* cx, int year, int mon, int mday, | |
17581 | int hour, int min, int sec); | |
17582 | extern __attribute__((visibility ("default"))) JSBool | |
17583 | js_DateIsValid(JSContext *cx, JSObject* obj); | |
17584 | extern __attribute__((visibility ("default"))) int | |
17585 | js_DateGetYear(JSContext *cx, JSObject* obj); | |
17586 | extern __attribute__((visibility ("default"))) int | |
17587 | js_DateGetMonth(JSContext *cx, JSObject* obj); | |
17588 | extern __attribute__((visibility ("default"))) int | |
17589 | js_DateGetDate(JSContext *cx, JSObject* obj); | |
17590 | extern __attribute__((visibility ("default"))) int | |
17591 | js_DateGetHours(JSContext *cx, JSObject* obj); | |
17592 | extern __attribute__((visibility ("default"))) int | |
17593 | js_DateGetMinutes(JSContext *cx, JSObject* obj); | |
17594 | extern __attribute__((visibility ("default"))) int | |
17595 | js_DateGetSeconds(JSContext *cx, JSObject* obj); | |
17596 | extern __attribute__((visibility ("default"))) jsdouble | |
17597 | js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj); | |
17598 | typedef uint32 JSIntervalTime; | |
17599 | extern __attribute__((visibility ("default"))) JSIntervalTime | |
17600 | js_IntervalNow(); | |
17601 | JSBool | |
17602 | js_Date(JSContext *cx, uintN argc, js::Value *vp); | |
17603 | namespace js { | |
17604 | struct NativeIterator { | |
17605 | JSObject *obj; | |
17606 | jsid *props_array; | |
17607 | jsid *props_cursor; | |
17608 | jsid *props_end; | |
17609 | uint32 *shapes_array; | |
17610 | uint32 shapes_length; | |
17611 | uint32 shapes_key; | |
17612 | uint32 flags; | |
17613 | JSObject *next; | |
17614 | bool isKeyIter() const { return (flags & 0x2) == 0; } | |
17615 | inline jsid *begin() const { | |
17616 | return props_array; | |
17617 | } | |
17618 | inline jsid *end() const { | |
17619 | return props_end; | |
17620 | } | |
17621 | size_t numKeys() const { | |
17622 | return end() - begin(); | |
17623 | } | |
17624 | jsid *current() const { | |
17625 | ((void) 0); | |
17626 | return props_cursor; | |
17627 | } | |
17628 | void incCursor() { | |
17629 | props_cursor = props_cursor + 1; | |
17630 | } | |
17631 | static NativeIterator *allocateIterator(JSContext *cx, uint32 slength, | |
17632 | const js::AutoIdVector &props); | |
17633 | void init(JSObject *obj, uintN flags, uint32 slength, uint32 key); | |
17634 | void mark(JSTracer *trc); | |
17635 | }; | |
17636 | bool | |
17637 | VectorToIdArray(JSContext *cx, js::AutoIdVector &props, JSIdArray **idap); | |
17638 | __attribute__((visibility ("default"))) bool | |
17639 | GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector *props); | |
17640 | bool | |
17641 | GetIterator(JSContext *cx, JSObject *obj, uintN flags, js::Value *vp); | |
17642 | bool | |
17643 | VectorToKeyIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); | |
17644 | bool | |
17645 | VectorToValueIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); | |
17646 | bool | |
17647 | EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); | |
17648 | } | |
17649 | extern __attribute__((visibility ("default"))) JSBool | |
17650 | js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp); | |
17651 | extern __attribute__((visibility ("default"))) JSBool | |
17652 | js_CloseIterator(JSContext *cx, JSObject *iterObj); | |
17653 | bool | |
17654 | js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id); | |
17655 | bool | |
17656 | js_SuppressDeletedIndexProperties(JSContext *cx, JSObject *obj, jsint begin, jsint end); | |
17657 | extern JSBool | |
17658 | js_IteratorMore(JSContext *cx, JSObject *iterobj, js::Value *rval); | |
17659 | extern JSBool | |
17660 | js_IteratorNext(JSContext *cx, JSObject *iterobj, js::Value *rval); | |
17661 | extern JSBool | |
17662 | js_ThrowStopIteration(JSContext *cx); | |
17663 | typedef enum JSGeneratorState { | |
17664 | JSGEN_NEWBORN, | |
17665 | JSGEN_OPEN, | |
17666 | JSGEN_RUNNING, | |
17667 | JSGEN_CLOSING, | |
17668 | JSGEN_CLOSED | |
17669 | } JSGeneratorState; | |
17670 | struct JSGenerator { | |
17671 | JSObject *obj; | |
17672 | JSGeneratorState state; | |
17673 | JSFrameRegs regs; | |
17674 | JSObject *enumerators; | |
17675 | JSStackFrame *floating; | |
17676 | js::Value floatingStack[1]; | |
17677 | JSStackFrame *floatingFrame() { | |
17678 | return floating; | |
17679 | } | |
17680 | JSStackFrame *liveFrame() { | |
17681 | ((void) 0) | |
17682 | ; | |
17683 | return regs.fp; | |
17684 | } | |
17685 | }; | |
17686 | extern JSObject * | |
17687 | js_NewGenerator(JSContext *cx); | |
17688 | inline JSStackFrame * | |
17689 | js_FloatingFrameIfGenerator(JSContext *cx, JSStackFrame *fp) | |
17690 | { | |
17691 | ((void) 0); | |
17692 | if ((__builtin_expect((fp->isGeneratorFrame()), 0))) | |
17693 | return cx->generatorFor(fp)->floatingFrame(); | |
17694 | return fp; | |
17695 | } | |
17696 | extern JSGenerator * | |
17697 | js_FloatingFrameToGenerator(JSStackFrame *fp); | |
17698 | inline JSStackFrame * | |
17699 | js_LiveFrameIfGenerator(JSStackFrame *fp) | |
17700 | { | |
17701 | return fp->isGeneratorFrame() ? js_FloatingFrameToGenerator(fp)->liveFrame() : fp; | |
17702 | } | |
17703 | extern js::Class js_GeneratorClass; | |
17704 | extern js::Class js_IteratorClass; | |
17705 | extern js::Class js_StopIterationClass; | |
17706 | static inline | |
17707 | bool | |
17708 | js_ValueIsStopIteration(const js::Value &v) | |
17709 | { | |
17710 | return v.isObject() && v.toObject().getClass() == &js_StopIterationClass; | |
17711 | } | |
17712 | extern JSObject * | |
17713 | js_InitIteratorClasses(JSContext *cx, JSObject *obj); | |
17714 | namespace js { | |
17715 | class __attribute__((visibility ("default"))) JSProxyHandler { | |
17716 | void *mFamily; | |
17717 | public: | |
17718 | explicit JSProxyHandler(void *family); | |
17719 | virtual ~JSProxyHandler(); | |
17720 | virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, | |
17721 | PropertyDescriptor *desc) = 0; | |
17722 | virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, | |
17723 | PropertyDescriptor *desc) = 0; | |
17724 | virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, | |
17725 | PropertyDescriptor *desc) = 0; | |
17726 | virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, js::AutoIdVector &props) = 0; | |
17727 | virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) = 0; | |
17728 | virtual bool enumerate(JSContext *cx, JSObject *proxy, js::AutoIdVector &props) = 0; | |
17729 | virtual bool fix(JSContext *cx, JSObject *proxy, Value *vp) = 0; | |
17730 | virtual bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp); | |
17731 | virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp); | |
17732 | virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, js::Value *vp); | |
17733 | virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, | |
17734 | js::Value *vp); | |
17735 | virtual bool keys(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); | |
17736 | virtual bool iterate(JSContext *cx, JSObject *proxy, uintN flags, js::Value *vp); | |
17737 | virtual bool call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp); | |
17738 | virtual bool construct(JSContext *cx, JSObject *proxy, | |
17739 | uintN argc, js::Value *argv, js::Value *rval); | |
17740 | virtual bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp); | |
17741 | virtual JSType typeOf(JSContext *cx, JSObject *proxy); | |
17742 | virtual JSString *obj_toString(JSContext *cx, JSObject *proxy); | |
17743 | virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); | |
17744 | virtual void finalize(JSContext *cx, JSObject *proxy); | |
17745 | virtual void trace(JSTracer *trc, JSObject *proxy); | |
17746 | virtual bool isOuterWindow() { | |
17747 | return false; | |
17748 | } | |
17749 | inline void *family() { | |
17750 | return mFamily; | |
17751 | } | |
17752 | }; | |
17753 | class JSProxy { | |
17754 | public: | |
17755 | static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, | |
17756 | PropertyDescriptor *desc); | |
17757 | static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp); | |
17758 | static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, | |
17759 | PropertyDescriptor *desc); | |
17760 | static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, | |
17761 | Value *vp); | |
17762 | static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc); | |
17763 | static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v); | |
17764 | static bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); | |
17765 | static bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp); | |
17766 | static bool enumerate(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); | |
17767 | static bool fix(JSContext *cx, JSObject *proxy, Value *vp); | |
17768 | static bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp); | |
17769 | static bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp); | |
17770 | static bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp); | |
17771 | static bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, | |
17772 | Value *vp); | |
17773 | static bool keys(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); | |
17774 | static bool iterate(JSContext *cx, JSObject *proxy, uintN flags, Value *vp); | |
17775 | static bool call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp); | |
17776 | static bool construct(JSContext *cx, JSObject *proxy, uintN argc, js::Value *argv, js::Value *rval); | |
17777 | static bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp); | |
17778 | static JSType typeOf(JSContext *cx, JSObject *proxy); | |
17779 | static JSString *obj_toString(JSContext *cx, JSObject *proxy); | |
17780 | static JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); | |
17781 | }; | |
17782 | const uint32 JSSLOT_PROXY_HANDLER = 0; | |
17783 | const uint32 JSSLOT_PROXY_PRIVATE = 1; | |
17784 | const uint32 JSSLOT_PROXY_EXTRA = 2; | |
17785 | const uint32 JSSLOT_PROXY_CALL = 3; | |
17786 | const uint32 JSSLOT_PROXY_CONSTRUCT = 4; | |
17787 | extern __attribute__((visibility ("default"))) js::Class ObjectProxyClass; | |
17788 | extern __attribute__((visibility ("default"))) js::Class FunctionProxyClass; | |
17789 | extern __attribute__((visibility ("default"))) js::Class OuterWindowProxyClass; | |
17790 | extern js::Class CallableObjectClass; | |
17791 | } | |
17792 | inline | |
17793 | bool | |
17794 | JSObject::isObjectProxy() const | |
17795 | { | |
17796 | return getClass() == &js::ObjectProxyClass || | |
17797 | getClass() == &js::OuterWindowProxyClass; | |
17798 | } | |
17799 | inline | |
17800 | bool | |
17801 | JSObject::isFunctionProxy() const | |
17802 | { | |
17803 | return getClass() == &js::FunctionProxyClass; | |
17804 | } | |
17805 | inline | |
17806 | bool | |
17807 | JSObject::isProxy() const | |
17808 | { | |
17809 | return isObjectProxy() || isFunctionProxy(); | |
17810 | } | |
17811 | inline js::JSProxyHandler * | |
17812 | JSObject::getProxyHandler() const | |
17813 | { | |
17814 | ((void) 0); | |
17815 | return (js::JSProxyHandler *) getSlot(js::JSSLOT_PROXY_HANDLER).toPrivate(); | |
17816 | } | |
17817 | inline const js::Value & | |
17818 | JSObject::getProxyPrivate() const | |
17819 | { | |
17820 | ((void) 0); | |
17821 | return getSlot(js::JSSLOT_PROXY_PRIVATE); | |
17822 | } | |
17823 | inline void | |
17824 | JSObject::setProxyPrivate(const js::Value &priv) | |
17825 | { | |
17826 | ((void) 0); | |
17827 | setSlot(js::JSSLOT_PROXY_PRIVATE, priv); | |
17828 | } | |
17829 | inline const js::Value & | |
17830 | JSObject::getProxyExtra() const | |
17831 | { | |
17832 | ((void) 0); | |
17833 | return getSlot(js::JSSLOT_PROXY_EXTRA); | |
17834 | } | |
17835 | inline void | |
17836 | JSObject::setProxyExtra(const js::Value &extra) | |
17837 | { | |
17838 | ((void) 0); | |
17839 | setSlot(js::JSSLOT_PROXY_EXTRA, extra); | |
17840 | } | |
17841 | namespace js { | |
17842 | __attribute__((visibility ("default"))) JSObject * | |
17843 | NewProxyObject(JSContext *cx, JSProxyHandler *handler, const js::Value &priv, | |
17844 | JSObject *proto, JSObject *parent, | |
17845 | JSObject *call = __null, JSObject *construct = __null); | |
17846 | __attribute__((visibility ("default"))) JSBool | |
17847 | FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp); | |
17848 | } | |
17849 | extern "C" { | |
17850 | extern js::Class js_ProxyClass; | |
17851 | extern __attribute__((visibility ("default"))) JSObject * | |
17852 | js_InitProxyClass(JSContext *cx, JSObject *obj); | |
17853 | } | |
17854 | inline void | |
17855 | js::Shape::freeTable(JSContext *cx) | |
17856 | { | |
17857 | if (hasTable()) { | |
17858 | cx->destroy(getTable()); | |
17859 | setTable(__null); | |
17860 | } | |
17861 | } | |
17862 | inline js::EmptyShape * | |
17863 | JSObject::getEmptyShape(JSContext *cx, js::Class *aclasp, | |
17864 | unsigned kind) | |
17865 | { | |
17866 | ((void) 0); | |
17867 | int i = kind - js::gc::FINALIZE_OBJECT0; | |
17868 | if (!emptyShapes) { | |
17869 | emptyShapes = (js::EmptyShape**) | |
17870 | cx->calloc(sizeof(js::EmptyShape*) * js::gc::JS_FINALIZE_OBJECT_LIMIT); | |
17871 | if (!emptyShapes) | |
17872 | return __null; | |
17873 | emptyShapes[0] = js::EmptyShape::create(cx, aclasp); | |
17874 | if (!emptyShapes[0]) { | |
17875 | cx->free(emptyShapes); | |
17876 | emptyShapes = __null; | |
17877 | return __null; | |
17878 | } | |
17879 | } | |
17880 | ((void) 0); | |
17881 | if (!emptyShapes[i]) { | |
17882 | emptyShapes[i] = js::EmptyShape::create(cx, aclasp); | |
17883 | if (!emptyShapes[i]) | |
17884 | return __null; | |
17885 | } | |
17886 | return emptyShapes[i]; | |
17887 | } | |
17888 | inline | |
17889 | bool | |
17890 | JSObject::canProvideEmptyShape(js::Class *aclasp) | |
17891 | { | |
17892 | return !emptyShapes || emptyShapes[0]->getClass() == aclasp; | |
17893 | } | |
17894 | inline void | |
17895 | JSObject::updateShape(JSContext *cx) | |
17896 | { | |
17897 | ((void) 0); | |
17898 | js::LeaveTraceIfGlobalObject(cx, this); | |
17899 | if (hasOwnShape()) | |
17900 | setOwnShape(js_GenerateShape(cx)); | |
17901 | else | |
17902 | objShape = lastProp->shape; | |
17903 | } | |
17904 | inline void | |
17905 | JSObject::updateFlags(const js::Shape *shape, bool isDefinitelyAtom) | |
17906 | { | |
17907 | jsuint index; | |
17908 | if (!isDefinitelyAtom && js_IdIsIndex(shape->id, &index)) | |
17909 | setIndexed(); | |
17910 | if (shape->isMethod()) | |
17911 | setMethodBarrier(); | |
17912 | } | |
17913 | inline void | |
17914 | JSObject::extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom) | |
17915 | { | |
17916 | setLastProperty(shape); | |
17917 | updateFlags(shape, isDefinitelyAtom); | |
17918 | updateShape(cx); | |
17919 | } | |
17920 | inline void | |
17921 | JSObject::trace(JSTracer *trc) | |
17922 | { | |
17923 | if (!isNative()) | |
17924 | return; | |
17925 | JSContext *cx = trc->context; | |
17926 | js::Shape *shape = lastProp; | |
17927 | if (((trc)->callback == __null) && cx->runtime->gcRegenShapes) { | |
17928 | if (!shape->hasRegenFlag()) { | |
17929 | shape->shape = js_RegenerateShapeForGC(cx->runtime); | |
17930 | shape->setRegenFlag(); | |
17931 | } | |
17932 | uint32 newShape = shape->shape; | |
17933 | if (hasOwnShape()) { | |
17934 | newShape = js_RegenerateShapeForGC(cx->runtime); | |
17935 | ((void) 0); | |
17936 | } | |
17937 | objShape = newShape; | |
17938 | } | |
17939 | do { | |
17940 | shape->trace(trc); | |
17941 | } while ((shape = shape->parent) != __null); | |
17942 | } | |
17943 | namespace js { | |
17944 | inline | |
17945 | Shape::Shape(jsid id, js::PropertyOp getter, js::StrictPropertyOp setter, uint32 slot, uintN attrs, | |
17946 | uintN flags, intN shortid, uint32 shape, uint32 slotSpan) | |
17947 | : JSObjectMap(shape, slotSpan), | |
17948 | numLinearSearches(0), id(id), rawGetter(getter), rawSetter(setter), slot(slot), | |
17949 | attrs(uint8(attrs)), flags(uint8(flags)), shortid(int16(shortid)), parent(__null) | |
17950 | { | |
17951 | ((void) 0); | |
17952 | ((void) 0); | |
17953 | ((void) 0); | |
17954 | kids.setNull(); | |
17955 | } | |
17956 | inline | |
17957 | Shape::Shape(JSCompartment *comp, Class *aclasp) | |
17958 | : JSObjectMap(js_GenerateShape(comp->rt), (((aclasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1))), | |
17959 | numLinearSearches(0), | |
17960 | id(((jsid)0x4)), | |
17961 | clasp(aclasp), | |
17962 | rawSetter(__null), | |
17963 | slot(0xffffffff), | |
17964 | attrs(0), | |
17965 | flags(SHARED_EMPTY), | |
17966 | shortid(0), | |
17967 | parent(__null) | |
17968 | { | |
17969 | kids.setNull(); | |
17970 | } | |
17971 | inline JSDHashNumber | |
17972 | Shape::hash() const | |
17973 | { | |
17974 | JSDHashNumber hash = 0; | |
17975 | ((void) 0); | |
17976 | if (rawGetter) | |
17977 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ jsuword(rawGetter); | |
17978 | if (rawSetter) | |
17979 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ jsuword(rawSetter); | |
17980 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ (flags & PUBLIC_FLAGS); | |
17981 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ attrs; | |
17982 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ shortid; | |
17983 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ slot; | |
17984 | hash = (((hash) << (4)) | ((hash) >> (32 - (4)))) ^ (id); | |
17985 | return hash; | |
17986 | } | |
17987 | inline | |
17988 | bool | |
17989 | Shape::matches(const js::Shape *other) const | |
17990 | { | |
17991 | ((void) 0); | |
17992 | ((void) 0); | |
17993 | return id == other->id && | |
17994 | matchesParamsAfterId(other->rawGetter, other->rawSetter, other->slot, other->attrs, | |
17995 | other->flags, other->shortid); | |
17996 | } | |
17997 | inline | |
17998 | bool | |
17999 | Shape::matchesParamsAfterId(js::PropertyOp agetter, js::StrictPropertyOp asetter, uint32 aslot, | |
18000 | uintN aattrs, uintN aflags, intN ashortid) const | |
18001 | { | |
18002 | ((void) 0); | |
18003 | return rawGetter == agetter && | |
18004 | rawSetter == asetter && | |
18005 | slot == aslot && | |
18006 | attrs == aattrs && | |
18007 | ((flags ^ aflags) & PUBLIC_FLAGS) == 0 && | |
18008 | shortid == ashortid; | |
18009 | } | |
18010 | inline | |
18011 | bool | |
18012 | Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const | |
18013 | { | |
18014 | ((void) 0); | |
18015 | ((void) 0); | |
18016 | if (hasGetterValue()) { | |
18017 | ((void) 0); | |
18018 | js::Value fval = getterValue(); | |
18019 | return js::ExternalGetOrSet(cx, receiver, id, fval, JSACC_READ, 0, 0, vp); | |
18020 | } | |
18021 | if (isMethod()) { | |
18022 | vp->setObject(methodObject()); | |
18023 | return pobj->methodReadBarrier(cx, *this, vp); | |
18024 | } | |
18025 | if (obj->getClass() == &js_WithClass) | |
18026 | obj = js_UnwrapWithObject(cx, obj); | |
18027 | return js::CallJSPropertyOp(cx, getterOp(), obj, ((this)->hasShortID() ? INT_TO_JSID((this)->shortid) : (this)->id), vp); | |
18028 | } | |
18029 | inline | |
18030 | bool | |
18031 | Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const | |
18032 | { | |
18033 | ((void) 0); | |
18034 | if (attrs & 0x20) { | |
18035 | js::Value fval = setterValue(); | |
18036 | return js::ExternalGetOrSet(cx, obj, id, fval, JSACC_WRITE, 1, vp, vp); | |
18037 | } | |
18038 | if (attrs & 0x10) | |
18039 | return js_ReportGetterOnlyAssignment(cx); | |
18040 | if (obj->getClass() == &js_WithClass) | |
18041 | obj = js_UnwrapWithObject(cx, obj); | |
18042 | return js::CallJSPropertyOpSetter(cx, setterOp(), obj, ((this)->hasShortID() ? INT_TO_JSID((this)->shortid) : (this)->id), strict, vp); | |
18043 | } | |
18044 | inline | |
18045 | EmptyShape::EmptyShape(JSCompartment *comp, js::Class *aclasp) | |
18046 | : js::Shape(comp, aclasp) | |
18047 | { | |
18048 | } | |
18049 | } | |
18050 | namespace js { | |
18051 | namespace gc { | |
18052 | const size_t SLOTS_TO_THING_KIND_LIMIT = 17; | |
18053 | static inline FinalizeKind | |
18054 | GetGCObjectKind(size_t numSlots) | |
18055 | { | |
18056 | extern FinalizeKind slotsToThingKind[]; | |
18057 | if (numSlots >= SLOTS_TO_THING_KIND_LIMIT) | |
18058 | return FINALIZE_OBJECT0; | |
18059 | return slotsToThingKind[numSlots]; | |
18060 | } | |
18061 | static inline size_t | |
18062 | GetGCKindSlots(FinalizeKind thingKind) | |
18063 | { | |
18064 | switch (thingKind) { | |
18065 | case FINALIZE_OBJECT0: | |
18066 | return 0; | |
18067 | case FINALIZE_OBJECT2: | |
18068 | return 2; | |
18069 | case FINALIZE_OBJECT4: | |
18070 | return 4; | |
18071 | case FINALIZE_OBJECT8: | |
18072 | return 8; | |
18073 | case FINALIZE_OBJECT12: | |
18074 | return 12; | |
18075 | case FINALIZE_OBJECT16: | |
18076 | return 16; | |
18077 | default: | |
18078 | ; | |
18079 | return 0; | |
18080 | } | |
18081 | } | |
18082 | } | |
18083 | } | |
18084 | template <typename T> | |
18085 | __attribute__((always_inline)) inline T * | |
18086 | NewFinalizableGCThing(JSContext *cx, unsigned thingKind) | |
18087 | { | |
18088 | ((void) 0); | |
18089 | ((void) 0) | |
18090 | ; | |
18091 | ((void) 0); | |
18092 | do { | |
18093 | js::gc::FreeCell *cell = cx->compartment->freeLists.getNext(thingKind); | |
18094 | if (cell) { | |
18095 | CheckGCFreeListLink(cell); | |
18096 | return (T *)cell; | |
18097 | } | |
18098 | if (!RefillFinalizableFreeList(cx, thingKind)) | |
18099 | return __null; | |
18100 | } while (true); | |
18101 | } | |
18102 | inline JSObject * | |
18103 | js_NewGCObject(JSContext *cx, js::gc::FinalizeKind kind) | |
18104 | { | |
18105 | ((void) 0); | |
18106 | JSObject *obj = NewFinalizableGCThing<JSObject>(cx, kind); | |
18107 | if (obj) | |
18108 | obj->capacity = js::gc::GetGCKindSlots(kind); | |
18109 | return obj; | |
18110 | } | |
18111 | inline JSString * | |
18112 | js_NewGCString(JSContext *cx) | |
18113 | { | |
18114 | return NewFinalizableGCThing<JSString>(cx, js::gc::FINALIZE_STRING); | |
18115 | } | |
18116 | inline JSShortString * | |
18117 | js_NewGCShortString(JSContext *cx) | |
18118 | { | |
18119 | return NewFinalizableGCThing<JSShortString>(cx, js::gc::FINALIZE_SHORT_STRING); | |
18120 | } | |
18121 | inline JSExternalString * | |
18122 | js_NewGCExternalString(JSContext *cx, uintN type) | |
18123 | { | |
18124 | ((void) 0); | |
18125 | JSExternalString *str = NewFinalizableGCThing<JSExternalString>(cx, js::gc::FINALIZE_EXTERNAL_STRING); | |
18126 | return str; | |
18127 | } | |
18128 | inline JSFunction* | |
18129 | js_NewGCFunction(JSContext *cx) | |
18130 | { | |
18131 | JSFunction *fun = NewFinalizableGCThing<JSFunction>(cx, js::gc::FINALIZE_FUNCTION); | |
18132 | if (fun) | |
18133 | fun->capacity = JSObject::FUN_CLASS_RESERVED_SLOTS; | |
18134 | return fun; | |
18135 | } | |
18136 | inline JSXML * | |
18137 | js_NewGCXML(JSContext *cx) | |
18138 | { | |
18139 | return NewFinalizableGCThing<JSXML>(cx, js::gc::FINALIZE_XML); | |
18140 | } | |
18141 | namespace js { | |
18142 | namespace gc { | |
18143 | static __attribute__((always_inline)) inline void | |
18144 | TypedMarker(JSTracer *trc, JSXML *thing); | |
18145 | static __attribute__((always_inline)) inline void | |
18146 | TypedMarker(JSTracer *trc, JSObject *thing); | |
18147 | static __attribute__((always_inline)) inline void | |
18148 | TypedMarker(JSTracer *trc, JSFunction *thing); | |
18149 | static __attribute__((always_inline)) inline void | |
18150 | TypedMarker(JSTracer *trc, JSShortString *thing); | |
18151 | static __attribute__((always_inline)) inline void | |
18152 | TypedMarker(JSTracer *trc, JSString *thing); | |
18153 | template<typename T> | |
18154 | static __attribute__((always_inline)) inline void | |
18155 | Mark(JSTracer *trc, T *thing) | |
18156 | { | |
18157 | ((void) 0); | |
18158 | ((void) 0); | |
18159 | ((void) 0); | |
18160 | ((void) 0); | |
18161 | JSRuntime *rt = trc->context->runtime; | |
18162 | if (rt->gcCurrentCompartment && thing->asCell()->compartment() != rt->gcCurrentCompartment) | |
18163 | goto out; | |
18164 | if (!((trc)->callback == __null)) { | |
18165 | uint32 kind = GetGCThingTraceKind(thing); | |
18166 | trc->callback(trc, thing, kind); | |
18167 | goto out; | |
18168 | } | |
18169 | TypedMarker(trc, thing); | |
18170 | out: | |
18171 | return; | |
18172 | } | |
18173 | static inline void | |
18174 | MarkString(JSTracer *trc, JSString *str) | |
18175 | { | |
18176 | ((void) 0); | |
18177 | if (JSString::isStatic(str)) | |
18178 | return; | |
18179 | ((void) 0); | |
18180 | Mark(trc, str); | |
18181 | } | |
18182 | static inline void | |
18183 | MarkString(JSTracer *trc, JSString *str, const char *name) | |
18184 | { | |
18185 | ((void) 0); | |
18186 | do { } while (0); | |
18187 | MarkString(trc, str); | |
18188 | } | |
18189 | static inline void | |
18190 | MarkObject(JSTracer *trc, JSObject &obj, const char *name) | |
18191 | { | |
18192 | ((void) 0); | |
18193 | ((void) 0); | |
18194 | do { } while (0); | |
18195 | ((void) 0) | |
18196 | ; | |
18197 | Mark(trc, &obj); | |
18198 | } | |
18199 | static inline void | |
18200 | MarkChildren(JSTracer *trc, JSObject *obj) | |
18201 | { | |
18202 | if (!obj->map) | |
18203 | return; | |
18204 | if (JSObject *proto = obj->getProto()) | |
18205 | MarkObject(trc, *proto, "proto"); | |
18206 | if (JSObject *parent = obj->getParent()) | |
18207 | MarkObject(trc, *parent, "parent"); | |
18208 | if (obj->emptyShapes) { | |
18209 | int count = FINALIZE_OBJECT_LAST - FINALIZE_OBJECT0 + 1; | |
18210 | for (int i = 0; i < count; i++) { | |
18211 | if (obj->emptyShapes[i]) | |
18212 | obj->emptyShapes[i]->trace(trc); | |
18213 | } | |
18214 | } | |
18215 | TraceOp op = obj->getOps()->trace; | |
18216 | (op ? op : js_TraceObject)(trc, obj); | |
18217 | } | |
18218 | static inline void | |
18219 | MarkChildren(JSTracer *trc, JSString *str) | |
18220 | { | |
18221 | if (str->isDependent()) | |
18222 | MarkString(trc, str->dependentBase(), "base"); | |
18223 | else if (str->isRope()) { | |
18224 | MarkString(trc, str->ropeLeft(), "left child"); | |
18225 | MarkString(trc, str->ropeRight(), "right child"); | |
18226 | } | |
18227 | } | |
18228 | static inline void | |
18229 | MarkChildren(JSTracer *trc, JSXML *xml) | |
18230 | { | |
18231 | js_TraceXML(trc, xml); | |
18232 | } | |
18233 | static inline | |
18234 | bool | |
18235 | RecursionTooDeep(GCMarker *gcmarker) { | |
18236 | int stackDummy; | |
18237 | return !((jsuword)(&stackDummy) > gcmarker->stackLimit); | |
18238 | } | |
18239 | static __attribute__((always_inline)) inline void | |
18240 | TypedMarker(JSTracer *trc, JSXML *thing) | |
18241 | { | |
18242 | if (!reinterpret_cast<Cell *>(thing)->markIfUnmarked(reinterpret_cast<GCMarker *>(trc)->getMarkColor())) | |
18243 | return; | |
18244 | GCMarker *gcmarker = static_cast<GCMarker *>(trc); | |
18245 | if (RecursionTooDeep(gcmarker)) { | |
18246 | gcmarker->delayMarkingChildren(thing); | |
18247 | } else { | |
18248 | MarkChildren(trc, thing); | |
18249 | } | |
18250 | } | |
18251 | static __attribute__((always_inline)) inline void | |
18252 | TypedMarker(JSTracer *trc, JSObject *thing) | |
18253 | { | |
18254 | ((void) 0); | |
18255 | ((void) 0); | |
18256 | GCMarker *gcmarker = static_cast<GCMarker *>(trc); | |
18257 | if (!thing->markIfUnmarked(gcmarker->getMarkColor())) | |
18258 | return; | |
18259 | if (RecursionTooDeep(gcmarker)) { | |
18260 | gcmarker->delayMarkingChildren(thing); | |
18261 | } else { | |
18262 | MarkChildren(trc, thing); | |
18263 | } | |
18264 | } | |
18265 | static __attribute__((always_inline)) inline void | |
18266 | TypedMarker(JSTracer *trc, JSFunction *thing) | |
18267 | { | |
18268 | ((void) 0); | |
18269 | ((void) 0); | |
18270 | GCMarker *gcmarker = static_cast<GCMarker *>(trc); | |
18271 | if (!thing->markIfUnmarked(gcmarker->getMarkColor())) | |
18272 | return; | |
18273 | if (RecursionTooDeep(gcmarker)) { | |
18274 | gcmarker->delayMarkingChildren(thing); | |
18275 | } else { | |
18276 | MarkChildren(trc, static_cast<JSObject *>(thing)); | |
18277 | } | |
18278 | } | |
18279 | static __attribute__((always_inline)) inline void | |
18280 | TypedMarker(JSTracer *trc, JSShortString *thing) | |
18281 | { | |
18282 | (void) thing->asCell()->markIfUnmarked(); | |
18283 | } | |
18284 | } | |
18285 | namespace detail { | |
18286 | static __attribute__((always_inline)) inline JSString * | |
18287 | Tag(JSString *str) | |
18288 | { | |
18289 | ((void) 0); | |
18290 | return (JSString *)(size_t(str) | 1); | |
18291 | } | |
18292 | static __attribute__((always_inline)) inline | |
18293 | bool | |
18294 | Tagged(JSString *str) | |
18295 | { | |
18296 | return (size_t(str) & 1) != 0; | |
18297 | } | |
18298 | static __attribute__((always_inline)) inline JSString * | |
18299 | Untag(JSString *str) | |
18300 | { | |
18301 | ((void) 0); | |
18302 | return (JSString *)(size_t(str) & ~size_t(1)); | |
18303 | } | |
18304 | static __attribute__((always_inline)) inline void | |
18305 | NonRopeTypedMarker(JSRuntime *rt, JSString *str) | |
18306 | { | |
18307 | ((void) 0); | |
18308 | if (rt->gcCurrentCompartment) { | |
18309 | for (;;) { | |
18310 | if (JSString::isStatic(str)) | |
18311 | break; | |
18312 | if (str->asCell()->compartment() != rt->gcCurrentCompartment) { | |
18313 | ((void) 0); | |
18314 | break; | |
18315 | } | |
18316 | if (!str->asCell()->markIfUnmarked()) | |
18317 | break; | |
18318 | if (!str->isDependent()) | |
18319 | break; | |
18320 | str = str->dependentBase(); | |
18321 | } | |
18322 | } else { | |
18323 | while (!JSString::isStatic(str) && | |
18324 | str->asCell()->markIfUnmarked() && | |
18325 | str->isDependent()) { | |
18326 | str = str->dependentBase(); | |
18327 | } | |
18328 | } | |
18329 | } | |
18330 | } | |
18331 | namespace gc { | |
18332 | static __attribute__((always_inline)) inline void | |
18333 | TypedMarker(JSTracer *trc, JSString *str) | |
18334 | { | |
18335 | using namespace detail; | |
18336 | JSRuntime *rt = trc->context->runtime; | |
18337 | ((void) 0); | |
18338 | if (!str->isRope()) { | |
18339 | NonRopeTypedMarker(rt, str); | |
18340 | return; | |
18341 | } | |
18342 | JSString *parent = __null; | |
18343 | first_visit_node: { | |
18344 | ((void) 0); | |
18345 | ((void) 0); | |
18346 | if (!str->asCell()->markIfUnmarked()) | |
18347 | goto finish_node; | |
18348 | JSString *left = str->ropeLeft(); | |
18349 | if (left->isRope()) { | |
18350 | ((void) 0); | |
18351 | str->u.left = Tag(parent); | |
18352 | parent = str; | |
18353 | str = left; | |
18354 | goto first_visit_node; | |
18355 | } | |
18356 | ((void) 0) | |
18357 | ; | |
18358 | NonRopeTypedMarker(rt, left); | |
18359 | } | |
18360 | visit_right_child: { | |
18361 | JSString *right = str->ropeRight(); | |
18362 | if (right->isRope()) { | |
18363 | ((void) 0); | |
18364 | str->s.right = Tag(parent); | |
18365 | parent = str; | |
18366 | str = right; | |
18367 | goto first_visit_node; | |
18368 | } | |
18369 | ((void) 0) | |
18370 | ; | |
18371 | NonRopeTypedMarker(rt, right); | |
18372 | } | |
18373 | finish_node: { | |
18374 | if (!parent) | |
18375 | return; | |
18376 | if (Tagged(parent->u.left)) { | |
18377 | ((void) 0); | |
18378 | JSString *nextParent = Untag(parent->u.left); | |
18379 | parent->u.left = str; | |
18380 | str = parent; | |
18381 | parent = nextParent; | |
18382 | goto visit_right_child; | |
18383 | } | |
18384 | ((void) 0); | |
18385 | JSString *nextParent = Untag(parent->s.right); | |
18386 | parent->s.right = str; | |
18387 | str = parent; | |
18388 | parent = nextParent; | |
18389 | goto finish_node; | |
18390 | } | |
18391 | } | |
18392 | static inline void | |
18393 | MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name) | |
18394 | { | |
18395 | for (uint32 i = 0; i < len; i++) { | |
18396 | if (JSAtom *atom = vec[i]) { | |
18397 | do { } while (0); | |
18398 | JSString *str = (atom); | |
18399 | if (!JSString::isStatic(str)) | |
18400 | Mark(trc, str); | |
18401 | } | |
18402 | } | |
18403 | } | |
18404 | static inline void | |
18405 | MarkObjectRange(JSTracer *trc, size_t len, JSObject **vec, const char *name) | |
18406 | { | |
18407 | for (uint32 i = 0; i < len; i++) { | |
18408 | if (JSObject *obj = vec[i]) { | |
18409 | do { } while (0); | |
18410 | Mark(trc, obj); | |
18411 | } | |
18412 | } | |
18413 | } | |
18414 | static inline void | |
18415 | MarkId(JSTracer *trc, jsid id) | |
18416 | { | |
18417 | if (JSID_IS_STRING(id)) { | |
18418 | JSString *str = JSID_TO_STRING(id); | |
18419 | if (!JSString::isStatic(str)) | |
18420 | Mark(trc, str); | |
18421 | } | |
18422 | else if ((__builtin_expect((JSID_IS_OBJECT(id)), 0))) | |
18423 | Mark(trc, JSID_TO_OBJECT(id)); | |
18424 | } | |
18425 | static inline void | |
18426 | MarkId(JSTracer *trc, jsid id, const char *name) | |
18427 | { | |
18428 | do { } while (0); | |
18429 | MarkId(trc, id); | |
18430 | } | |
18431 | static inline void | |
18432 | MarkIdRange(JSTracer *trc, jsid *beg, jsid *end, const char *name) | |
18433 | { | |
18434 | for (jsid *idp = beg; idp != end; ++idp) { | |
18435 | do { } while (0); | |
18436 | MarkId(trc, *idp); | |
18437 | } | |
18438 | } | |
18439 | static inline void | |
18440 | MarkIdRange(JSTracer *trc, size_t len, jsid *vec, const char *name) | |
18441 | { | |
18442 | MarkIdRange(trc, vec, vec + len, name); | |
18443 | } | |
18444 | static inline void | |
18445 | MarkKind(JSTracer *trc, void *thing, uint32 kind) | |
18446 | { | |
18447 | ((void) 0); | |
18448 | ((void) 0); | |
18449 | switch (kind) { | |
18450 | case 0: | |
18451 | Mark(trc, reinterpret_cast<JSObject *>(thing)); | |
18452 | break; | |
18453 | case 1: | |
18454 | MarkString(trc, reinterpret_cast<JSString *>(thing)); | |
18455 | break; | |
18456 | case 2: | |
18457 | Mark(trc, reinterpret_cast<JSXML *>(thing)); | |
18458 | break; | |
18459 | default: | |
18460 | ((void) 0); | |
18461 | } | |
18462 | } | |
18463 | static inline void | |
18464 | MarkValueRaw(JSTracer *trc, const js::Value &v) | |
18465 | { | |
18466 | if (v.isMarkable()) { | |
18467 | ((void) 0); | |
18468 | return MarkKind(trc, v.toGCThing(), v.gcKind()); | |
18469 | } | |
18470 | } | |
18471 | static inline void | |
18472 | MarkValue(JSTracer *trc, const js::Value &v, const char *name) | |
18473 | { | |
18474 | do { } while (0); | |
18475 | MarkValueRaw(trc, v); | |
18476 | } | |
18477 | static inline void | |
18478 | MarkValueRange(JSTracer *trc, Value *beg, Value *end, const char *name) | |
18479 | { | |
18480 | for (Value *vp = beg; vp < end; ++vp) { | |
18481 | do { } while (0); | |
18482 | MarkValueRaw(trc, *vp); | |
18483 | } | |
18484 | } | |
18485 | static inline void | |
18486 | MarkValueRange(JSTracer *trc, size_t len, Value *vec, const char *name) | |
18487 | { | |
18488 | MarkValueRange(trc, vec, vec + len, name); | |
18489 | } | |
18490 | static inline void | |
18491 | MarkShapeRange(JSTracer *trc, const Shape **beg, const Shape **end, const char *name) | |
18492 | { | |
18493 | for (const Shape **sp = beg; sp < end; ++sp) { | |
18494 | do { } while (0); | |
18495 | (*sp)->trace(trc); | |
18496 | } | |
18497 | } | |
18498 | static inline void | |
18499 | MarkShapeRange(JSTracer *trc, size_t len, const Shape **vec, const char *name) | |
18500 | { | |
18501 | MarkShapeRange(trc, vec, vec + len, name); | |
18502 | } | |
18503 | static inline void | |
18504 | MarkGCThing(JSTracer *trc, void *thing, uint32 kind) | |
18505 | { | |
18506 | if (!thing) | |
18507 | return; | |
18508 | MarkKind(trc, thing, kind); | |
18509 | } | |
18510 | static inline void | |
18511 | MarkGCThing(JSTracer *trc, void *thing) | |
18512 | { | |
18513 | if (!thing) | |
18514 | return; | |
18515 | MarkKind(trc, thing, GetGCThingTraceKind(thing)); | |
18516 | } | |
18517 | static inline void | |
18518 | MarkGCThing(JSTracer *trc, void *thing, const char *name) | |
18519 | { | |
18520 | do { } while (0); | |
18521 | MarkGCThing(trc, thing); | |
18522 | } | |
18523 | static inline void | |
18524 | MarkGCThing(JSTracer *trc, void *thing, const char *name, size_t index) | |
18525 | { | |
18526 | do { } while (0); | |
18527 | MarkGCThing(trc, thing); | |
18528 | } | |
18529 | static inline void | |
18530 | Mark(JSTracer *trc, void *thing, uint32 kind, const char *name) | |
18531 | { | |
18532 | ((void) 0); | |
18533 | do { } while (0); | |
18534 | MarkKind(trc, thing, kind); | |
18535 | } | |
18536 | }} | |
18537 | inline | |
18538 | bool | |
18539 | JSObject::preventExtensions(JSContext *cx, js::AutoIdVector *props) | |
18540 | { | |
18541 | ((void) 0); | |
18542 | if (js::FixOp fix = getOps()->fix) { | |
18543 | bool success; | |
18544 | if (!fix(cx, this, &success, props)) | |
18545 | return false; | |
18546 | if (!success) { | |
18547 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_CANT_CHANGE_EXTENSIBILITY); | |
18548 | return false; | |
18549 | } | |
18550 | } else { | |
18551 | if (!GetPropertyNames(cx, this, 0x10 | 0x8, props)) | |
18552 | return false; | |
18553 | } | |
18554 | if (isNative()) | |
18555 | extensibleShapeChange(cx); | |
18556 | flags |= NOT_EXTENSIBLE; | |
18557 | return true; | |
18558 | } | |
18559 | inline | |
18560 | bool | |
18561 | JSObject::brand(JSContext *cx) | |
18562 | { | |
18563 | ((void) 0); | |
18564 | ((void) 0); | |
18565 | ((void) 0); | |
18566 | generateOwnShape(cx); | |
18567 | if (js_IsPropertyCacheDisabled(cx)) | |
18568 | return false; | |
18569 | flags |= BRANDED; | |
18570 | return true; | |
18571 | } | |
18572 | inline | |
18573 | bool | |
18574 | JSObject::unbrand(JSContext *cx) | |
18575 | { | |
18576 | ((void) 0); | |
18577 | if (branded()) { | |
18578 | generateOwnShape(cx); | |
18579 | if (js_IsPropertyCacheDisabled(cx)) | |
18580 | return false; | |
18581 | flags &= ~BRANDED; | |
18582 | } | |
18583 | setGeneric(); | |
18584 | return true; | |
18585 | } | |
18586 | inline void | |
18587 | JSObject::syncSpecialEquality() | |
18588 | { | |
18589 | if (clasp->ext.equality) | |
18590 | flags |= JSObject::HAS_EQUALITY; | |
18591 | } | |
18592 | inline void | |
18593 | JSObject::finalize(JSContext *cx) | |
18594 | { | |
18595 | if (!map) | |
18596 | return; | |
18597 | js::Class *clasp = getClass(); | |
18598 | if (clasp->finalize) | |
18599 | clasp->finalize(cx, this); | |
18600 | js::Probes::finalizeObject(this); | |
18601 | finish(cx); | |
18602 | } | |
18603 | inline const js::Shape * | |
18604 | JSObject::methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp) | |
18605 | { | |
18606 | ((void) 0); | |
18607 | ((void) 0); | |
18608 | ((void) 0); | |
18609 | ((void) 0); | |
18610 | ((void) 0); | |
18611 | ((void) 0); | |
18612 | ((void) 0); | |
18613 | ((void) 0); | |
18614 | ((void) 0); | |
18615 | JSObject *funobj = &vp->toObject(); | |
18616 | JSFunction *fun = funobj->getFunctionPrivate(); | |
18617 | ((void) 0); | |
18618 | ((void) 0); | |
18619 | funobj = CloneFunctionObject(cx, fun, funobj->getParent()); | |
18620 | if (!funobj) | |
18621 | return __null; | |
18622 | funobj->setMethodObj(*this); | |
18623 | uint32 slot = shape.slot; | |
18624 | const js::Shape *newshape = methodShapeChange(cx, shape); | |
18625 | if (!newshape) | |
18626 | return __null; | |
18627 | ((void) 0); | |
18628 | ((void) 0); | |
18629 | vp->setObject(*funobj); | |
18630 | nativeSetSlot(slot, *vp); | |
18631 | return newshape; | |
18632 | } | |
18633 | static __attribute__((always_inline)) inline | |
18634 | bool | |
18635 | ChangesMethodValue(const js::Value &prev, const js::Value &v) | |
18636 | { | |
18637 | JSObject *prevObj; | |
18638 | return prev.isObject() && (prevObj = &prev.toObject())->isFunction() && | |
18639 | (!v.isObject() || &v.toObject() != prevObj); | |
18640 | } | |
18641 | inline const js::Shape * | |
18642 | JSObject::methodWriteBarrier(JSContext *cx, const js::Shape &shape, const js::Value &v) | |
18643 | { | |
18644 | if (brandedOrHasMethodBarrier() && shape.slot != 0xffffffff) { | |
18645 | const js::Value &prev = nativeGetSlot(shape.slot); | |
18646 | if (ChangesMethodValue(prev, v)) { | |
18647 | ((void)0); | |
18648 | return methodShapeChange(cx, shape); | |
18649 | } | |
18650 | } | |
18651 | return &shape; | |
18652 | } | |
18653 | inline | |
18654 | bool | |
18655 | JSObject::methodWriteBarrier(JSContext *cx, uint32 slot, const js::Value &v) | |
18656 | { | |
18657 | if (brandedOrHasMethodBarrier()) { | |
18658 | const js::Value &prev = nativeGetSlot(slot); | |
18659 | if (ChangesMethodValue(prev, v)) { | |
18660 | ((void)0); | |
18661 | return methodShapeChange(cx, slot); | |
18662 | } | |
18663 | } | |
18664 | return true; | |
18665 | } | |
18666 | inline | |
18667 | bool | |
18668 | JSObject::ensureClassReservedSlots(JSContext *cx) | |
18669 | { | |
18670 | return !nativeEmpty() || ensureClassReservedSlotsForEmptyObject(cx); | |
18671 | } | |
18672 | inline js::Value | |
18673 | JSObject::getReservedSlot(uintN index) const | |
18674 | { | |
18675 | return (index < numSlots()) ? getSlot(index) : js::UndefinedValue(); | |
18676 | } | |
18677 | inline | |
18678 | bool | |
18679 | JSObject::canHaveMethodBarrier() const | |
18680 | { | |
18681 | return isObject() || isFunction() || isPrimitive() || isDate(); | |
18682 | } | |
18683 | inline | |
18684 | bool | |
18685 | JSObject::isPrimitive() const | |
18686 | { | |
18687 | return isNumber() || isString() || isBoolean(); | |
18688 | } | |
18689 | inline const js::Value & | |
18690 | JSObject::getPrimitiveThis() const | |
18691 | { | |
18692 | ((void) 0); | |
18693 | return getSlot(JSSLOT_PRIMITIVE_THIS); | |
18694 | } | |
18695 | inline void | |
18696 | JSObject::setPrimitiveThis(const js::Value &pthis) | |
18697 | { | |
18698 | ((void) 0); | |
18699 | setSlot(JSSLOT_PRIMITIVE_THIS, pthis); | |
18700 | } | |
18701 | inline unsigned | |
18702 | JSObject::finalizeKind() const | |
18703 | { | |
18704 | return js::gc::FinalizeKind(arena()->header()->thingKind); | |
18705 | } | |
18706 | inline size_t | |
18707 | JSObject::numFixedSlots() const | |
18708 | { | |
18709 | if (isFunction()) | |
18710 | return JSObject::FUN_CLASS_RESERVED_SLOTS; | |
18711 | if (!hasSlotsArray()) | |
18712 | return capacity; | |
18713 | return js::gc::GetGCKindSlots(js::gc::FinalizeKind(finalizeKind())); | |
18714 | } | |
18715 | inline size_t | |
18716 | JSObject::slotsAndStructSize(uint32 nslots) const | |
18717 | { | |
18718 | bool isFun = isFunction() && this == (JSObject*) getPrivate(); | |
18719 | int ndslots = hasSlotsArray() ? nslots : 0; | |
18720 | int nfslots = isFun ? 0 : numFixedSlots(); | |
18721 | return sizeof(js::Value) * (ndslots + nfslots) | |
18722 | + isFun ? sizeof(JSFunction) : sizeof(JSObject); | |
18723 | } | |
18724 | inline uint32 | |
18725 | JSObject::getArrayLength() const | |
18726 | { | |
18727 | ((void) 0); | |
18728 | return (uint32)(size_t) getPrivate(); | |
18729 | } | |
18730 | inline void | |
18731 | JSObject::setArrayLength(uint32 length) | |
18732 | { | |
18733 | ((void) 0); | |
18734 | setPrivate((void*) length); | |
18735 | } | |
18736 | inline uint32 | |
18737 | JSObject::getDenseArrayCapacity() | |
18738 | { | |
18739 | ((void) 0); | |
18740 | return numSlots(); | |
18741 | } | |
18742 | inline js::Value* | |
18743 | JSObject::getDenseArrayElements() | |
18744 | { | |
18745 | ((void) 0); | |
18746 | return getSlots(); | |
18747 | } | |
18748 | inline const js::Value & | |
18749 | JSObject::getDenseArrayElement(uintN idx) | |
18750 | { | |
18751 | ((void) 0); | |
18752 | return getSlot(idx); | |
18753 | } | |
18754 | inline js::Value * | |
18755 | JSObject::addressOfDenseArrayElement(uintN idx) | |
18756 | { | |
18757 | ((void) 0); | |
18758 | return &getSlotRef(idx); | |
18759 | } | |
18760 | inline void | |
18761 | JSObject::setDenseArrayElement(uintN idx, const js::Value &val) | |
18762 | { | |
18763 | ((void) 0); | |
18764 | setSlot(idx, val); | |
18765 | } | |
18766 | inline void | |
18767 | JSObject::shrinkDenseArrayElements(JSContext *cx, uintN cap) | |
18768 | { | |
18769 | ((void) 0); | |
18770 | shrinkSlots(cx, cap); | |
18771 | } | |
18772 | inline void | |
18773 | JSObject::setArgsLength(uint32 argc) | |
18774 | { | |
18775 | ((void) 0); | |
18776 | ((void) 0); | |
18777 | ((void) 0); | |
18778 | getSlotRef(JSSLOT_ARGS_LENGTH).setInt32(argc << ARGS_PACKED_BITS_COUNT); | |
18779 | ((void) 0); | |
18780 | } | |
18781 | inline uint32 | |
18782 | JSObject::getArgsInitialLength() const | |
18783 | { | |
18784 | ((void) 0); | |
18785 | uint32 argc = uint32(getSlot(JSSLOT_ARGS_LENGTH).toInt32()) >> ARGS_PACKED_BITS_COUNT; | |
18786 | ((void) 0); | |
18787 | return argc; | |
18788 | } | |
18789 | inline void | |
18790 | JSObject::setArgsLengthOverridden() | |
18791 | { | |
18792 | ((void) 0); | |
18793 | getSlotRef(JSSLOT_ARGS_LENGTH).getInt32Ref() |= ARGS_LENGTH_OVERRIDDEN_BIT; | |
18794 | } | |
18795 | inline | |
18796 | bool | |
18797 | JSObject::isArgsLengthOverridden() const | |
18798 | { | |
18799 | ((void) 0); | |
18800 | const js::Value &v = getSlot(JSSLOT_ARGS_LENGTH); | |
18801 | return v.toInt32() & ARGS_LENGTH_OVERRIDDEN_BIT; | |
18802 | } | |
18803 | inline js::ArgumentsData * | |
18804 | JSObject::getArgsData() const | |
18805 | { | |
18806 | ((void) 0); | |
18807 | return (js::ArgumentsData *) getSlot(JSSLOT_ARGS_DATA).toPrivate(); | |
18808 | } | |
18809 | inline void | |
18810 | JSObject::setArgsData(js::ArgumentsData *data) | |
18811 | { | |
18812 | ((void) 0); | |
18813 | getSlotRef(JSSLOT_ARGS_DATA).setPrivate(data); | |
18814 | } | |
18815 | inline const js::Value & | |
18816 | JSObject::getArgsCallee() const | |
18817 | { | |
18818 | return getArgsData()->callee; | |
18819 | } | |
18820 | inline void | |
18821 | JSObject::setArgsCallee(const js::Value &callee) | |
18822 | { | |
18823 | getArgsData()->callee = callee; | |
18824 | } | |
18825 | inline const js::Value & | |
18826 | JSObject::getArgsElement(uint32 i) const | |
18827 | { | |
18828 | ((void) 0); | |
18829 | ((void) 0); | |
18830 | return getArgsData()->slots[i]; | |
18831 | } | |
18832 | inline js::Value * | |
18833 | JSObject::getArgsElements() const | |
18834 | { | |
18835 | ((void) 0); | |
18836 | return getArgsData()->slots; | |
18837 | } | |
18838 | inline js::Value * | |
18839 | JSObject::addressOfArgsElement(uint32 i) | |
18840 | { | |
18841 | ((void) 0); | |
18842 | ((void) 0); | |
18843 | return &getArgsData()->slots[i]; | |
18844 | } | |
18845 | inline void | |
18846 | JSObject::setArgsElement(uint32 i, const js::Value &v) | |
18847 | { | |
18848 | ((void) 0); | |
18849 | ((void) 0); | |
18850 | getArgsData()->slots[i] = v; | |
18851 | } | |
18852 | inline | |
18853 | bool | |
18854 | JSObject::callIsForEval() const | |
18855 | { | |
18856 | ((void) 0); | |
18857 | ((void) 0); | |
18858 | ((void) 0) | |
18859 | ; | |
18860 | return getSlot(JSSLOT_CALL_CALLEE).isNull(); | |
18861 | } | |
18862 | inline JSStackFrame * | |
18863 | JSObject::maybeCallObjStackFrame() const | |
18864 | { | |
18865 | ((void) 0); | |
18866 | return reinterpret_cast<JSStackFrame *>(getPrivate()); | |
18867 | } | |
18868 | inline void | |
18869 | JSObject::setCallObjCallee(JSObject *callee) | |
18870 | { | |
18871 | ((void) 0); | |
18872 | ((void) 0); | |
18873 | return getSlotRef(JSSLOT_CALL_CALLEE).setObjectOrNull(callee); | |
18874 | } | |
18875 | inline JSObject * | |
18876 | JSObject::getCallObjCallee() const | |
18877 | { | |
18878 | ((void) 0); | |
18879 | return getSlot(JSSLOT_CALL_CALLEE).toObjectOrNull(); | |
18880 | } | |
18881 | inline JSFunction * | |
18882 | JSObject::getCallObjCalleeFunction() const | |
18883 | { | |
18884 | ((void) 0); | |
18885 | return getSlot(JSSLOT_CALL_CALLEE).toObject().getFunctionPrivate(); | |
18886 | } | |
18887 | inline const js::Value & | |
18888 | JSObject::getCallObjArguments() const | |
18889 | { | |
18890 | ((void) 0); | |
18891 | ((void) 0); | |
18892 | return getSlot(JSSLOT_CALL_ARGUMENTS); | |
18893 | } | |
18894 | inline void | |
18895 | JSObject::setCallObjArguments(const js::Value &v) | |
18896 | { | |
18897 | ((void) 0); | |
18898 | ((void) 0); | |
18899 | setSlot(JSSLOT_CALL_ARGUMENTS, v); | |
18900 | } | |
18901 | inline const js::Value & | |
18902 | JSObject::callObjArg(uintN i) const | |
18903 | { | |
18904 | ((void) 0); | |
18905 | ((void) 0); | |
18906 | return getSlot(JSObject::CALL_RESERVED_SLOTS + i); | |
18907 | } | |
18908 | inline js::Value & | |
18909 | JSObject::callObjArg(uintN i) | |
18910 | { | |
18911 | ((void) 0); | |
18912 | ((void) 0); | |
18913 | return getSlotRef(JSObject::CALL_RESERVED_SLOTS + i); | |
18914 | } | |
18915 | inline const js::Value & | |
18916 | JSObject::callObjVar(uintN i) const | |
18917 | { | |
18918 | JSFunction *fun = getCallObjCalleeFunction(); | |
18919 | ((void) 0); | |
18920 | ((void) 0); | |
18921 | return getSlot(JSObject::CALL_RESERVED_SLOTS + fun->nargs + i); | |
18922 | } | |
18923 | inline js::Value & | |
18924 | JSObject::callObjVar(uintN i) | |
18925 | { | |
18926 | JSFunction *fun = getCallObjCalleeFunction(); | |
18927 | ((void) 0); | |
18928 | ((void) 0); | |
18929 | return getSlotRef(JSObject::CALL_RESERVED_SLOTS + fun->nargs + i); | |
18930 | } | |
18931 | inline const js::Value & | |
18932 | JSObject::getDateUTCTime() const | |
18933 | { | |
18934 | ((void) 0); | |
18935 | return getSlot(JSSLOT_DATE_UTC_TIME); | |
18936 | } | |
18937 | inline void | |
18938 | JSObject::setDateUTCTime(const js::Value &time) | |
18939 | { | |
18940 | ((void) 0); | |
18941 | setSlot(JSSLOT_DATE_UTC_TIME, time); | |
18942 | } | |
18943 | inline js::Value * | |
18944 | JSObject::getFlatClosureUpvars() const | |
18945 | { | |
18946 | return (js::Value *) getSlot(JSSLOT_FLAT_CLOSURE_UPVARS).toPrivate(); | |
18947 | } | |
18948 | inline js::Value | |
18949 | JSObject::getFlatClosureUpvar(uint32 i) const | |
18950 | { | |
18951 | ((void) 0); | |
18952 | return getFlatClosureUpvars()[i]; | |
18953 | } | |
18954 | inline js::Value & | |
18955 | JSObject::getFlatClosureUpvar(uint32 i) | |
18956 | { | |
18957 | ((void) 0); | |
18958 | return getFlatClosureUpvars()[i]; | |
18959 | } | |
18960 | inline void | |
18961 | JSObject::setFlatClosureUpvars(js::Value *upvars) | |
18962 | { | |
18963 | ((void) 0); | |
18964 | ((void) 0); | |
18965 | getSlotRef(JSSLOT_FLAT_CLOSURE_UPVARS).setPrivate(upvars); | |
18966 | } | |
18967 | inline | |
18968 | bool | |
18969 | JSObject::hasMethodObj(const JSObject& obj) const | |
18970 | { | |
18971 | return JSSLOT_FUN_METHOD_OBJ < numSlots() && | |
18972 | getSlot(JSSLOT_FUN_METHOD_OBJ).isObject() && | |
18973 | &getSlot(JSSLOT_FUN_METHOD_OBJ).toObject() == &obj; | |
18974 | } | |
18975 | inline void | |
18976 | JSObject::setMethodObj(JSObject& obj) | |
18977 | { | |
18978 | getSlotRef(JSSLOT_FUN_METHOD_OBJ).setObject(obj); | |
18979 | } | |
18980 | inline js::NativeIterator * | |
18981 | JSObject::getNativeIterator() const | |
18982 | { | |
18983 | return (js::NativeIterator *) getPrivate(); | |
18984 | } | |
18985 | inline void | |
18986 | JSObject::setNativeIterator(js::NativeIterator *ni) | |
18987 | { | |
18988 | setPrivate(ni); | |
18989 | } | |
18990 | inline JSLinearString * | |
18991 | JSObject::getNamePrefix() const | |
18992 | { | |
18993 | ((void) 0); | |
18994 | const js::Value &v = getSlot(JSSLOT_NAME_PREFIX); | |
18995 | return !v.isUndefined() ? v.toString()->assertIsLinear() : __null; | |
18996 | } | |
18997 | inline jsval | |
18998 | JSObject::getNamePrefixVal() const | |
18999 | { | |
19000 | ((void) 0); | |
19001 | return js::Jsvalify(getSlot(JSSLOT_NAME_PREFIX)); | |
19002 | } | |
19003 | inline void | |
19004 | JSObject::setNamePrefix(JSLinearString *prefix) | |
19005 | { | |
19006 | ((void) 0); | |
19007 | setSlot(JSSLOT_NAME_PREFIX, prefix ? js::StringValue(prefix) : js::UndefinedValue()); | |
19008 | } | |
19009 | inline void | |
19010 | JSObject::clearNamePrefix() | |
19011 | { | |
19012 | ((void) 0); | |
19013 | setSlot(JSSLOT_NAME_PREFIX, js::UndefinedValue()); | |
19014 | } | |
19015 | inline JSLinearString * | |
19016 | JSObject::getNameURI() const | |
19017 | { | |
19018 | ((void) 0); | |
19019 | const js::Value &v = getSlot(JSSLOT_NAME_URI); | |
19020 | return !v.isUndefined() ? v.toString()->assertIsLinear() : __null; | |
19021 | } | |
19022 | inline jsval | |
19023 | JSObject::getNameURIVal() const | |
19024 | { | |
19025 | ((void) 0); | |
19026 | return js::Jsvalify(getSlot(JSSLOT_NAME_URI)); | |
19027 | } | |
19028 | inline void | |
19029 | JSObject::setNameURI(JSLinearString *uri) | |
19030 | { | |
19031 | ((void) 0); | |
19032 | setSlot(JSSLOT_NAME_URI, uri ? js::StringValue(uri) : js::UndefinedValue()); | |
19033 | } | |
19034 | inline jsval | |
19035 | JSObject::getNamespaceDeclared() const | |
19036 | { | |
19037 | ((void) 0); | |
19038 | return js::Jsvalify(getSlot(JSSLOT_NAMESPACE_DECLARED)); | |
19039 | } | |
19040 | inline void | |
19041 | JSObject::setNamespaceDeclared(jsval decl) | |
19042 | { | |
19043 | ((void) 0); | |
19044 | setSlot(JSSLOT_NAMESPACE_DECLARED, js::Valueify(decl)); | |
19045 | } | |
19046 | inline JSLinearString * | |
19047 | JSObject::getQNameLocalName() const | |
19048 | { | |
19049 | ((void) 0); | |
19050 | const js::Value &v = getSlot(JSSLOT_QNAME_LOCAL_NAME); | |
19051 | return !v.isUndefined() ? v.toString()->assertIsLinear() : __null; | |
19052 | } | |
19053 | inline jsval | |
19054 | JSObject::getQNameLocalNameVal() const | |
19055 | { | |
19056 | ((void) 0); | |
19057 | return js::Jsvalify(getSlot(JSSLOT_QNAME_LOCAL_NAME)); | |
19058 | } | |
19059 | inline void | |
19060 | JSObject::setQNameLocalName(JSLinearString *name) | |
19061 | { | |
19062 | ((void) 0); | |
19063 | setSlot(JSSLOT_QNAME_LOCAL_NAME, name ? js::StringValue(name) : js::UndefinedValue()); | |
19064 | } | |
19065 | inline JSObject * | |
19066 | JSObject::getWithThis() const | |
19067 | { | |
19068 | return &getSlot(JSSLOT_WITH_THIS).toObject(); | |
19069 | } | |
19070 | inline void | |
19071 | JSObject::setWithThis(JSObject *thisp) | |
19072 | { | |
19073 | getSlotRef(JSSLOT_WITH_THIS).setObject(*thisp); | |
19074 | } | |
19075 | inline void | |
19076 | JSObject::init(JSContext *cx, js::Class *aclasp, JSObject *proto, JSObject *parent, | |
19077 | void *priv, bool useHoles) | |
19078 | { | |
19079 | clasp = aclasp; | |
19080 | flags = 0; | |
19081 | setProto(proto); | |
19082 | setParent(parent); | |
19083 | privateData = priv; | |
19084 | slots = fixedSlots(); | |
19085 | ((void) 0); | |
19086 | ClearValueRange(slots, capacity, useHoles); | |
19087 | emptyShapes = __null; | |
19088 | } | |
19089 | inline void | |
19090 | JSObject::finish(JSContext *cx) | |
19091 | { | |
19092 | if (hasSlotsArray()) | |
19093 | freeSlotsArray(cx); | |
19094 | if (emptyShapes) | |
19095 | cx->free(emptyShapes); | |
19096 | } | |
19097 | inline | |
19098 | bool | |
19099 | JSObject::initSharingEmptyShape(JSContext *cx, | |
19100 | js::Class *aclasp, | |
19101 | JSObject *proto, | |
19102 | JSObject *parent, | |
19103 | void *privateValue, | |
19104 | unsigned kind) | |
19105 | { | |
19106 | init(cx, aclasp, proto, parent, privateValue, false); | |
19107 | ((void) 0); | |
19108 | js::EmptyShape *empty = proto->getEmptyShape(cx, aclasp, kind); | |
19109 | if (!empty) | |
19110 | return false; | |
19111 | setMap(empty); | |
19112 | return true; | |
19113 | } | |
19114 | inline void | |
19115 | JSObject::freeSlotsArray(JSContext *cx) | |
19116 | { | |
19117 | ((void) 0); | |
19118 | cx->free(slots); | |
19119 | } | |
19120 | inline void | |
19121 | JSObject::revertToFixedSlots(JSContext *cx) | |
19122 | { | |
19123 | ((void) 0); | |
19124 | size_t fixed = numFixedSlots(); | |
19125 | ((void) 0); | |
19126 | memcpy(fixedSlots(), slots, fixed * sizeof(js::Value)); | |
19127 | freeSlotsArray(cx); | |
19128 | slots = fixedSlots(); | |
19129 | capacity = fixed; | |
19130 | } | |
19131 | inline | |
19132 | bool | |
19133 | JSObject::hasProperty(JSContext *cx, jsid id, bool *foundp, uintN flags) | |
19134 | { | |
19135 | JSObject *pobj; | |
19136 | JSProperty *prop; | |
19137 | JSAutoResolveFlags rf(cx, flags); | |
19138 | if (!lookupProperty(cx, id, &pobj, &prop)) | |
19139 | return false; | |
19140 | *foundp = !!prop; | |
19141 | return true; | |
19142 | } | |
19143 | inline | |
19144 | bool | |
19145 | JSObject::isCallable() | |
19146 | { | |
19147 | return isFunction() || getClass()->call; | |
19148 | } | |
19149 | static inline | |
19150 | bool | |
19151 | js_IsCallable(const js::Value &v) | |
19152 | { | |
19153 | return v.isObject() && v.toObject().isCallable(); | |
19154 | } | |
19155 | namespace js { | |
19156 | class AutoPropDescArrayRooter : private AutoGCRooter | |
19157 | { | |
19158 | public: | |
19159 | AutoPropDescArrayRooter(JSContext *cx) | |
19160 | : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx) | |
19161 | { } | |
19162 | PropDesc *append() { | |
19163 | if (!descriptors.append(PropDesc())) | |
19164 | return __null; | |
19165 | return &descriptors.back(); | |
19166 | } | |
19167 | PropDesc& operator[](size_t i) { | |
19168 | ((void) 0); | |
19169 | return descriptors[i]; | |
19170 | } | |
19171 | friend void AutoGCRooter::trace(JSTracer *trc); | |
19172 | private: | |
19173 | PropDescArray descriptors; | |
19174 | }; | |
19175 | class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescriptor | |
19176 | { | |
19177 | public: | |
19178 | AutoPropertyDescriptorRooter(JSContext *cx) : AutoGCRooter(cx, DESCRIPTOR) { | |
19179 | obj = __null; | |
19180 | attrs = 0; | |
19181 | getter = (PropertyOp) __null; | |
19182 | setter = (StrictPropertyOp) __null; | |
19183 | value.setUndefined(); | |
19184 | } | |
19185 | AutoPropertyDescriptorRooter(JSContext *cx, PropertyDescriptor *desc) | |
19186 | : AutoGCRooter(cx, DESCRIPTOR) | |
19187 | { | |
19188 | obj = desc->obj; | |
19189 | attrs = desc->attrs; | |
19190 | getter = desc->getter; | |
19191 | setter = desc->setter; | |
19192 | value = desc->value; | |
19193 | } | |
19194 | friend void AutoGCRooter::trace(JSTracer *trc); | |
19195 | }; | |
19196 | static inline | |
19197 | bool | |
19198 | InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* proto, | |
19199 | gc::FinalizeKind kind) | |
19200 | { | |
19201 | ((void) 0); | |
19202 | ((void) 0); | |
19203 | js::EmptyShape *empty = __null; | |
19204 | if (proto) { | |
19205 | if (proto->canProvideEmptyShape(clasp)) { | |
19206 | empty = proto->getEmptyShape(cx, clasp, kind); | |
19207 | if (!empty) | |
19208 | goto bad; | |
19209 | } | |
19210 | } | |
19211 | if (!empty) { | |
19212 | empty = js::EmptyShape::create(cx, clasp); | |
19213 | if (!empty) | |
19214 | goto bad; | |
19215 | uint32 freeslot = (((clasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1)); | |
19216 | if (freeslot > obj->numSlots() && !obj->allocSlots(cx, freeslot)) | |
19217 | goto bad; | |
19218 | } | |
19219 | obj->setMap(empty); | |
19220 | return true; | |
19221 | bad: | |
19222 | ((void) 0); | |
19223 | return false; | |
19224 | } | |
19225 | static inline JSObject * | |
19226 | NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, | |
19227 | JSObject *parent, gc::FinalizeKind kind) | |
19228 | { | |
19229 | ((void) 0); | |
19230 | ((void) 0); | |
19231 | JSObject* obj = js_NewGCObject(cx, kind); | |
19232 | if (obj) { | |
19233 | bool useHoles = (clasp == &js_ArrayClass); | |
19234 | obj->init(cx, clasp, proto, parent, __null, useHoles); | |
19235 | ((void) 0); | |
19236 | js::EmptyShape *empty = proto->getEmptyShape(cx, clasp, kind); | |
19237 | if (empty) | |
19238 | obj->setMap(empty); | |
19239 | else | |
19240 | obj = __null; | |
19241 | } | |
19242 | return obj; | |
19243 | } | |
19244 | static inline JSObject * | |
19245 | NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent) | |
19246 | { | |
19247 | gc::FinalizeKind kind = gc::GetGCObjectKind((((clasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1))); | |
19248 | return NewNativeClassInstance(cx, clasp, proto, parent, kind); | |
19249 | } | |
19250 | bool | |
19251 | FindClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, JSObject **protop, | |
19252 | Class *clasp); | |
19253 | static inline JSObject * | |
19254 | NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::FinalizeKind kind) | |
19255 | { | |
19256 | ((void) 0); | |
19257 | JSProtoKey protoKey = ((JSProtoKey) (((clasp)->flags >> ((8 + 8) + 8)) & (((JSUint32)1 << (8)) - 1))); | |
19258 | ((void) 0); | |
19259 | JSObject *global; | |
19260 | if (!cx->hasfp()) { | |
19261 | global = cx->globalObject; | |
19262 | OBJ_TO_INNER_OBJECT(cx, global); | |
19263 | if (!global) | |
19264 | return __null; | |
19265 | } else { | |
19266 | global = cx->fp()->scopeChain().getGlobal(); | |
19267 | } | |
19268 | ((void) 0); | |
19269 | const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey); | |
19270 | JSObject *proto; | |
19271 | if (v.isObject()) { | |
19272 | proto = &v.toObject(); | |
19273 | ((void) 0); | |
19274 | } else { | |
19275 | if (!FindClassPrototype(cx, global, protoKey, &proto, clasp)) | |
19276 | return __null; | |
19277 | } | |
19278 | return NewNativeClassInstance(cx, clasp, proto, global, kind); | |
19279 | } | |
19280 | static inline JSObject * | |
19281 | NewBuiltinClassInstance(JSContext *cx, Class *clasp) | |
19282 | { | |
19283 | gc::FinalizeKind kind = gc::GetGCObjectKind((((clasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1))); | |
19284 | return NewBuiltinClassInstance(cx, clasp, kind); | |
19285 | } | |
19286 | static inline JSProtoKey | |
19287 | GetClassProtoKey(js::Class *clasp) | |
19288 | { | |
19289 | JSProtoKey key = ((JSProtoKey) (((clasp)->flags >> ((8 + 8) + 8)) & (((JSUint32)1 << (8)) - 1))); | |
19290 | if (key != JSProto_Null) | |
19291 | return key; | |
19292 | if (clasp->flags & (1<<((8 + 8)+1))) | |
19293 | return JSProto_Object; | |
19294 | return JSProto_Null; | |
19295 | } | |
19296 | namespace WithProto { | |
19297 | enum e { | |
19298 | Class = 0, | |
19299 | Given = 1 | |
19300 | }; | |
19301 | } | |
19302 | static __attribute__((always_inline)) inline | |
19303 | bool | |
19304 | FindProto(JSContext *cx, js::Class *clasp, JSObject *parent, JSObject ** proto) | |
19305 | { | |
19306 | JSProtoKey protoKey = GetClassProtoKey(clasp); | |
19307 | if (!js_GetClassPrototype(cx, parent, protoKey, proto, clasp)) | |
19308 | return false; | |
19309 | if (!(*proto) && !js_GetClassPrototype(cx, parent, JSProto_Object, proto)) | |
19310 | return false; | |
19311 | return true; | |
19312 | } | |
19313 | namespace detail | |
19314 | { | |
19315 | template <bool withProto, bool isFunction> | |
19316 | static __attribute__((always_inline)) inline JSObject * | |
19317 | NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, | |
19318 | gc::FinalizeKind kind) | |
19319 | { | |
19320 | if (withProto == WithProto::Class && !proto) { | |
19321 | if (!FindProto(cx, clasp, parent, &proto)) | |
19322 | return __null; | |
19323 | } | |
19324 | JSObject* obj = isFunction ? js_NewGCFunction(cx) : js_NewGCObject(cx, kind); | |
19325 | if (!obj) | |
19326 | goto out; | |
19327 | ((void) 0); | |
19328 | obj->init(cx, clasp, proto, | |
19329 | (!parent && proto) ? proto->getParent() : parent, | |
19330 | __null, clasp == &js_ArrayClass); | |
19331 | if (clasp->isNative()) { | |
19332 | if (!InitScopeForObject(cx, obj, clasp, proto, kind)) { | |
19333 | obj = __null; | |
19334 | goto out; | |
19335 | } | |
19336 | } else { | |
19337 | obj->setSharedNonNativeMap(); | |
19338 | } | |
19339 | out: | |
19340 | Probes::createObject(cx, obj); | |
19341 | return obj; | |
19342 | } | |
19343 | } | |
19344 | static __attribute__((always_inline)) inline JSObject * | |
19345 | NewFunction(JSContext *cx, JSObject *parent) | |
19346 | { | |
19347 | return detail::NewObject<WithProto::Class, true>(cx, &js_FunctionClass, __null, parent, | |
19348 | gc::FINALIZE_OBJECT2); | |
19349 | } | |
19350 | template <WithProto::e withProto> | |
19351 | static __attribute__((always_inline)) inline JSObject * | |
19352 | NewNonFunction(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, | |
19353 | gc::FinalizeKind kind) | |
19354 | { | |
19355 | return detail::NewObject<withProto, false>(cx, clasp, proto, parent, kind); | |
19356 | } | |
19357 | template <WithProto::e withProto> | |
19358 | static __attribute__((always_inline)) inline JSObject * | |
19359 | NewNonFunction(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent) | |
19360 | { | |
19361 | gc::FinalizeKind kind = gc::GetGCObjectKind((((clasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1))); | |
19362 | return detail::NewObject<withProto, false>(cx, clasp, proto, parent, kind); | |
19363 | } | |
19364 | template <WithProto::e withProto> | |
19365 | static __attribute__((always_inline)) inline JSObject * | |
19366 | NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, | |
19367 | gc::FinalizeKind kind) | |
19368 | { | |
19369 | if (clasp == &js_FunctionClass) | |
19370 | return detail::NewObject<withProto, true>(cx, clasp, proto, parent, kind); | |
19371 | return detail::NewObject<withProto, false>(cx, clasp, proto, parent, kind); | |
19372 | } | |
19373 | template <WithProto::e withProto> | |
19374 | static __attribute__((always_inline)) inline JSObject * | |
19375 | NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent) | |
19376 | { | |
19377 | gc::FinalizeKind kind = gc::GetGCObjectKind((((clasp)->flags >> 8) & (((JSUint32)1 << (8)) - 1))); | |
19378 | return NewObject<withProto>(cx, clasp, proto, parent, kind); | |
19379 | } | |
19380 | static inline gc::FinalizeKind | |
19381 | GuessObjectGCKind(size_t numSlots, bool isArray) | |
19382 | { | |
19383 | if (numSlots) | |
19384 | return gc::GetGCObjectKind(numSlots); | |
19385 | return isArray ? gc::FINALIZE_OBJECT8 : gc::FINALIZE_OBJECT4; | |
19386 | } | |
19387 | static inline gc::FinalizeKind | |
19388 | NewObjectGCKind(JSContext *cx, js::Class *clasp) | |
19389 | { | |
19390 | if (clasp == &js_ArrayClass || clasp == &js_SlowArrayClass) | |
19391 | return gc::FINALIZE_OBJECT8; | |
19392 | if (clasp == &js_FunctionClass) | |
19393 | return gc::FINALIZE_OBJECT2; | |
19394 | return gc::FINALIZE_OBJECT4; | |
19395 | } | |
19396 | static inline JSObject * | |
19397 | CopyInitializerObject(JSContext *cx, JSObject *baseobj) | |
19398 | { | |
19399 | ((void) 0); | |
19400 | ((void) 0); | |
19401 | gc::FinalizeKind kind = gc::FinalizeKind(baseobj->finalizeKind()); | |
19402 | JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind); | |
19403 | if (!obj || !obj->ensureSlots(cx, baseobj->numSlots())) | |
19404 | return __null; | |
19405 | obj->flags = baseobj->flags; | |
19406 | obj->lastProp = baseobj->lastProp; | |
19407 | obj->objShape = baseobj->objShape; | |
19408 | return obj; | |
19409 | } | |
19410 | static __attribute__((always_inline)) inline | |
19411 | bool | |
19412 | ClassMethodIsNative(JSContext *cx, JSObject *obj, Class *clasp, jsid methodid, | |
19413 | Native native) | |
19414 | { | |
19415 | ((void) 0); | |
19416 | if (HasNativeMethod(obj, methodid, native)) | |
19417 | return true; | |
19418 | JSObject *pobj = obj->getProto(); | |
19419 | return pobj && pobj->getClass() == clasp && | |
19420 | HasNativeMethod(pobj, methodid, native); | |
19421 | } | |
19422 | } | |
19423 | using namespace js; | |
19424 | using namespace js::gc; | |
19425 | static inline | |
19426 | bool | |
19427 | js_EnterLocalRootScope(JSContext *cx) | |
19428 | { | |
19429 | return true; | |
19430 | } | |
19431 | static inline void | |
19432 | js_LeaveLocalRootScope(JSContext *cx) | |
19433 | { | |
19434 | } | |
19435 | static inline void | |
19436 | js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval) | |
19437 | { | |
19438 | } | |
19439 | static inline void | |
19440 | js_LeaveLocalRootScopeWithResult(JSContext *cx, Value rval) | |
19441 | { | |
19442 | } | |
19443 | static inline void | |
19444 | js_LeaveLocalRootScopeWithResult(JSContext *cx, void *rval) | |
19445 | { | |
19446 | } | |
19447 | const char js_AttributeName_str[] = "AttributeName"; | |
19448 | const char js_isXMLName_str[] = "isXMLName"; | |
19449 | const char js_XMLList_str[] = "XMLList"; | |
19450 | const char js_localName_str[] = "localName"; | |
19451 | const char js_xml_parent_str[] = "parent"; | |
19452 | const char js_prefix_str[] = "prefix"; | |
19453 | const char js_toXMLString_str[] = "toXMLString"; | |
19454 | const char js_uri_str[] = "uri"; | |
19455 | const char js_amp_entity_str[] = "&"; | |
19456 | const char js_gt_entity_str[] = ">"; | |
19457 | const char js_lt_entity_str[] = "<"; | |
19458 | const char js_quot_entity_str[] = """; | |
19459 | const char js_leftcurly_entity_str[] = "{"; | |
19460 | static JSBool | |
19461 | GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |
19462 | static JSBool | |
19463 | IsDeclared(const JSObject *obj) | |
19464 | { | |
19465 | jsval v; | |
19466 | ((void) 0); | |
19467 | v = obj->getNamespaceDeclared(); | |
19468 | ((void) 0); | |
19469 | return v == ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1)); | |
19470 | } | |
19471 | static JSBool | |
19472 | xml_isXMLName(JSContext *cx, uintN argc, jsval *vp) | |
19473 | { | |
19474 | *vp = BOOLEAN_TO_JSVAL(js_IsXMLName(cx, argc ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)))); | |
19475 | return (JSIntn)1; | |
19476 | } | |
19477 | static inline JSObject * | |
19478 | NewBuiltinClassInstanceXML(JSContext *cx, Class *clasp) | |
19479 | { | |
19480 | JSObject *obj = NewBuiltinClassInstance(cx, clasp); | |
19481 | if (obj) | |
19482 | obj->syncSpecialEquality(); | |
19483 | return obj; | |
19484 | } | |
19485 | static JSBool NamePrefix_getter(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNamePrefixVal(); return true; } | |
19486 | static JSBool NameURI_getter(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNameURIVal(); return true; } | |
19487 | static JSBool | |
19488 | namespace_equality(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp) | |
19489 | { | |
19490 | JSObject *obj2; | |
19491 | ((void) 0); | |
19492 | obj2 = v->toObjectOrNull(); | |
19493 | *bp = (!obj2 || obj2->getClass() != &js_NamespaceClass) | |
19494 | ? (JSIntn)0 | |
19495 | : EqualStrings(obj->getNameURI(), obj2->getNameURI()); | |
19496 | return (JSIntn)1; | |
19497 | } | |
19498 | __attribute__((visibility ("default"))) Class js_NamespaceClass = { | |
19499 | "Namespace", | |
19500 | (1<<6) | | |
19501 | (((JSObject::NAMESPACE_CLASS_RESERVED_SLOTS) & (((JSUint32)1 << (8)) - 1)) << 8) | | |
19502 | (1<<((8 + 8)+3)) | ((JSProto_Namespace) << ((8 + 8) + 8)), | |
19503 | PropertyStub, | |
19504 | PropertyStub, | |
19505 | PropertyStub, | |
19506 | StrictPropertyStub, | |
19507 | EnumerateStub, | |
19508 | ResolveStub, | |
19509 | ConvertStub, | |
19510 | FinalizeStub, | |
19511 | __null, | |
19512 | __null, | |
19513 | __null, | |
19514 | __null, | |
19515 | __null, | |
19516 | __null, | |
19517 | __null, | |
19518 | { | |
19519 | namespace_equality, | |
19520 | __null, | |
19521 | __null, | |
19522 | __null, | |
19523 | __null, | |
19524 | } | |
19525 | }; | |
19526 | static JSPropertySpec namespace_props[] = { | |
19527 | {js_prefix_str, 0, (0x01 | 0x02 | 0x04 | 0x40), NamePrefix_getter, 0}, | |
19528 | {js_uri_str, 0, (0x01 | 0x02 | 0x04 | 0x40), NameURI_getter, 0}, | |
19529 | {0,0,0,0,0} | |
19530 | }; | |
19531 | static JSBool | |
19532 | namespace_toString(JSContext *cx, uintN argc, Value *vp) | |
19533 | { | |
19534 | JSObject *obj = ToObject(cx, &vp[1]); | |
19535 | if (!obj) | |
19536 | return (JSIntn)0; | |
19537 | if (!JS_InstanceOf(cx, obj, Jsvalify(&js_NamespaceClass), Jsvalify(vp + 2))) | |
19538 | return (JSIntn)0; | |
19539 | *vp = Valueify(obj->getNameURIVal()); | |
19540 | return (JSIntn)1; | |
19541 | } | |
19542 | static JSFunctionSpec namespace_methods[] = { | |
19543 | {js_toString_str, ((JSNative)(namespace_toString)), 0, (0) | 0x1000}, | |
19544 | {__null, __null, 0, 0} | |
19545 | }; | |
19546 | static JSObject * | |
19547 | NewXMLNamespace(JSContext *cx, JSLinearString *prefix, JSLinearString *uri, JSBool declared) | |
19548 | { | |
19549 | JSObject *obj; | |
19550 | obj = NewBuiltinClassInstanceXML(cx, &js_NamespaceClass); | |
19551 | if (!obj) | |
19552 | return (JSIntn)0; | |
19553 | ((void) 0); | |
19554 | ((void) 0); | |
19555 | ((void) 0); | |
19556 | if (prefix) | |
19557 | obj->setNamePrefix(prefix); | |
19558 | if (uri) | |
19559 | obj->setNameURI(uri); | |
19560 | if (declared) | |
19561 | obj->setNamespaceDeclared(((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1))); | |
19562 | ; | |
19563 | return obj; | |
19564 | } | |
19565 | static JSBool QNameNameURI_getter(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { if (obj->getClass() == &js_QNameClass) *vp = JSVAL_IS_VOID(obj->getNameURIVal()) ? ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)) : obj->getNameURIVal(); return true; } | |
19566 | static JSBool QNameLocalName_getter(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { if (obj->getClass() == &js_QNameClass) *vp = obj->getQNameLocalNameVal(); return true; } | |
19567 | static JSBool | |
19568 | qname_identity(JSObject *qna, JSObject *qnb) | |
19569 | { | |
19570 | JSLinearString *uri1 = qna->getNameURI(); | |
19571 | JSLinearString *uri2 = qnb->getNameURI(); | |
19572 | if (!uri1 ^ !uri2) | |
19573 | return (JSIntn)0; | |
19574 | if (uri1 && !EqualStrings(uri1, uri2)) | |
19575 | return (JSIntn)0; | |
19576 | return EqualStrings(qna->getQNameLocalName(), qnb->getQNameLocalName()); | |
19577 | } | |
19578 | static JSBool | |
19579 | qname_equality(JSContext *cx, JSObject *qn, const Value *v, JSBool *bp) | |
19580 | { | |
19581 | JSObject *obj2; | |
19582 | obj2 = v->toObjectOrNull(); | |
19583 | *bp = (!obj2 || obj2->getClass() != &js_QNameClass) | |
19584 | ? (JSIntn)0 | |
19585 | : qname_identity(qn, obj2); | |
19586 | return (JSIntn)1; | |
19587 | } | |
19588 | __attribute__((visibility ("default"))) Class js_QNameClass = { | |
19589 | "QName", | |
19590 | (1<<6) | | |
19591 | (((JSObject::QNAME_CLASS_RESERVED_SLOTS) & (((JSUint32)1 << (8)) - 1)) << 8) | | |
19592 | (1<<((8 + 8)+3)) | ((JSProto_QName) << ((8 + 8) + 8)), | |
19593 | PropertyStub, | |
19594 | PropertyStub, | |
19595 | PropertyStub, | |
19596 | StrictPropertyStub, | |
19597 | EnumerateStub, | |
19598 | ResolveStub, | |
19599 | ConvertStub, | |
19600 | FinalizeStub, | |
19601 | __null, | |
19602 | __null, | |
19603 | __null, | |
19604 | __null, | |
19605 | __null, | |
19606 | __null, | |
19607 | __null, | |
19608 | { | |
19609 | qname_equality, | |
19610 | __null, | |
19611 | __null, | |
19612 | __null, | |
19613 | __null, | |
19614 | } | |
19615 | }; | |
19616 | __attribute__((visibility ("default"))) Class js_AttributeNameClass = { | |
19617 | js_AttributeName_str, | |
19618 | (1<<6) | | |
19619 | (((JSObject::QNAME_CLASS_RESERVED_SLOTS) & (((JSUint32)1 << (8)) - 1)) << 8) | | |
19620 | (1<<((8 + 8)+3)) | (1<<((8 + 8)+1)), | |
19621 | PropertyStub, | |
19622 | PropertyStub, | |
19623 | PropertyStub, | |
19624 | StrictPropertyStub, | |
19625 | EnumerateStub, | |
19626 | ResolveStub, | |
19627 | ConvertStub, | |
19628 | FinalizeStub | |
19629 | }; | |
19630 | __attribute__((visibility ("default"))) Class js_AnyNameClass = { | |
19631 | js_AnyName_str, | |
19632 | (1<<6) | | |
19633 | (((JSObject::QNAME_CLASS_RESERVED_SLOTS) & (((JSUint32)1 << (8)) - 1)) << 8) | | |
19634 | (1<<((8 + 8)+3)) | (1<<((8 + 8)+1)), | |
19635 | PropertyStub, | |
19636 | PropertyStub, | |
19637 | PropertyStub, | |
19638 | StrictPropertyStub, | |
19639 | EnumerateStub, | |
19640 | ResolveStub, | |
19641 | ConvertStub, | |
19642 | FinalizeStub | |
19643 | }; | |
19644 | static JSPropertySpec qname_props[] = { | |
19645 | {js_uri_str, 0, (0x01 | 0x02 | 0x04 | 0x40), QNameNameURI_getter, 0}, | |
19646 | {js_localName_str, 0, (0x01 | 0x02 | 0x04 | 0x40), QNameLocalName_getter, 0}, | |
19647 | {0,0,0,0,0} | |
19648 | }; | |
19649 | static JSString * | |
19650 | ConvertQNameToString(JSContext *cx, JSObject *obj) | |
19651 | { | |
19652 | ((void) 0); | |
19653 | JSString *uri = obj->getNameURI(); | |
19654 | JSString *str; | |
19655 | if (!uri) { | |
19656 | str = (cx->runtime->atomState.starQualifierAtom); | |
19657 | } else if (uri->empty()) { | |
19658 | str = cx->runtime->emptyString; | |
19659 | } else { | |
19660 | JSString *qualstr = (cx->runtime->atomState.qualifierAtom); | |
19661 | str = js_ConcatStrings(cx, uri, qualstr); | |
19662 | if (!str) | |
19663 | return __null; | |
19664 | } | |
19665 | str = js_ConcatStrings(cx, str, obj->getQNameLocalName()); | |
19666 | if (!str) | |
19667 | return __null; | |
19668 | if (obj->getClass() == &js_AttributeNameClass) { | |
19669 | JS::Anchor<JSString *> anchor(str); | |
19670 | size_t length = str->length(); | |
19671 | jschar *chars = (jschar *) cx->malloc((length + 2) * sizeof(jschar)); | |
19672 | if (!chars) | |
19673 | return (JSIntn)0; | |
19674 | *chars = '@'; | |
19675 | const jschar *strChars = str->getChars(cx); | |
19676 | if (!strChars) { | |
19677 | cx->free(chars); | |
19678 | return __null; | |
19679 | } | |
19680 | memcpy((chars + 1), (strChars), (length) * sizeof(jschar)); | |
19681 | chars[++length] = 0; | |
19682 | str = js_NewString(cx, chars, length); | |
19683 | if (!str) { | |
19684 | cx->free(chars); | |
19685 | return __null; | |
19686 | } | |
19687 | } | |
19688 | return str; | |
19689 | } | |
19690 | static JSBool | |
19691 | qname_toString(JSContext *cx, uintN argc, Value *vp) | |
19692 | { | |
19693 | JSObject *obj = ToObject(cx, &vp[1]); | |
19694 | if (!obj) | |
19695 | return false; | |
19696 | if (!InstanceOf(cx, obj, &js_QNameClass, vp + 2)) | |
19697 | return false; | |
19698 | JSString *str = ConvertQNameToString(cx, obj); | |
19699 | if (!str) | |
19700 | return false; | |
19701 | vp->setString(str); | |
19702 | return true; | |
19703 | } | |
19704 | static JSFunctionSpec qname_methods[] = { | |
19705 | {js_toString_str, ((JSNative)(qname_toString)), 0, (0) | 0x1000}, | |
19706 | {__null, __null, 0, 0} | |
19707 | }; | |
19708 | static void | |
19709 | InitXMLQName(JSObject *obj, JSLinearString *uri, JSLinearString *prefix, | |
19710 | JSLinearString *localName) | |
19711 | { | |
19712 | ((void) 0); | |
19713 | ((void) 0); | |
19714 | ((void) 0); | |
19715 | ((void) 0); | |
19716 | if (uri) | |
19717 | obj->setNameURI(uri); | |
19718 | if (prefix) | |
19719 | obj->setNamePrefix(prefix); | |
19720 | if (localName) | |
19721 | obj->setQNameLocalName(localName); | |
19722 | } | |
19723 | static JSObject * | |
19724 | NewXMLQName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix, | |
19725 | JSLinearString *localName) | |
19726 | { | |
19727 | JSObject *obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass); | |
19728 | if (!obj) | |
19729 | return __null; | |
19730 | InitXMLQName(obj, uri, prefix, localName); | |
19731 | ; | |
19732 | return obj; | |
19733 | } | |
19734 | static JSObject * | |
19735 | NewXMLAttributeName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix, | |
19736 | JSLinearString *localName) | |
19737 | { | |
19738 | JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AttributeNameClass, __null, __null); | |
19739 | if (!obj) | |
19740 | return __null; | |
19741 | ((void) 0); | |
19742 | InitXMLQName(obj, uri, prefix, localName); | |
19743 | ; | |
19744 | return obj; | |
19745 | } | |
19746 | JSObject * | |
19747 | js_ConstructXMLQNameObject(JSContext *cx, const Value &nsval, const Value &lnval) | |
19748 | { | |
19749 | Value argv[2]; | |
19750 | if (nsval.isObject() && | |
19751 | nsval.toObject().getClass() == &js_AnyNameClass) { | |
19752 | argv[0].setNull(); | |
19753 | } else { | |
19754 | argv[0] = nsval; | |
19755 | } | |
19756 | argv[1] = lnval; | |
19757 | return js_ConstructObject(cx, &js_QNameClass, __null, __null, 2, argv); | |
19758 | } | |
19759 | static JSBool | |
19760 | IsXMLName(const jschar *cp, size_t n) | |
19761 | { | |
19762 | JSBool rv; | |
19763 | jschar c; | |
19764 | rv = (JSIntn)0; | |
19765 | if (n != 0 && (((js_A[js_Y[(js_X[(uint16)(*cp)>>6]<<6)|((*cp)&0x3F)]]) & 0x00000100) || (*cp) == '_')) { | |
19766 | while (--n != 0) { | |
19767 | c = *++cp; | |
19768 | if (!(((js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]]) & 0x00000080) || (c) == '.' || (c) == '-' || (c) == '_')) | |
19769 | return rv; | |
19770 | } | |
19771 | rv = (JSIntn)1; | |
19772 | } | |
19773 | return rv; | |
19774 | } | |
19775 | JSBool | |
19776 | js_IsXMLName(JSContext *cx, jsval v) | |
19777 | { | |
19778 | JSLinearString *name = __null; | |
19779 | JSErrorReporter older; | |
19780 | if (!JSVAL_IS_PRIMITIVE(v) && | |
19781 | JSVAL_TO_OBJECT(v)->isQName()) { | |
19782 | name = JSVAL_TO_OBJECT(v)->getQNameLocalName(); | |
19783 | } else { | |
19784 | older = JS_SetErrorReporter(cx, __null); | |
19785 | JSString *str = js_ValueToString(cx, Valueify(v)); | |
19786 | if (str) | |
19787 | name = str->ensureLinear(cx); | |
19788 | JS_SetErrorReporter(cx, older); | |
19789 | if (!name) { | |
19790 | JS_ClearPendingException(cx); | |
19791 | return (JSIntn)0; | |
19792 | } | |
19793 | } | |
19794 | return IsXMLName(name->chars(), name->length()); | |
19795 | } | |
19796 | static JSBool | |
19797 | NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, | |
19798 | jsval *rval) | |
19799 | { | |
19800 | jsval urival, prefixval; | |
19801 | JSObject *uriobj; | |
19802 | JSBool isNamespace, isQName; | |
19803 | Class *clasp; | |
19804 | JSLinearString *empty, *prefix, *uri; | |
19805 | isNamespace = isQName = (JSIntn)0; | |
19806 | uriobj = __null; | |
19807 | if (argc <= 0) { | |
19808 | urival = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
19809 | } else { | |
19810 | urival = argv[argc > 1]; | |
19811 | if (!JSVAL_IS_PRIMITIVE(urival)) { | |
19812 | uriobj = JSVAL_TO_OBJECT(urival); | |
19813 | clasp = uriobj->getClass(); | |
19814 | isNamespace = (clasp == &js_NamespaceClass); | |
19815 | isQName = (clasp == &js_QNameClass); | |
19816 | } | |
19817 | } | |
19818 | if (!obj) { | |
19819 | if (argc == 1 && isNamespace) { | |
19820 | *rval = urival; | |
19821 | return (JSIntn)1; | |
19822 | } | |
19823 | obj = NewBuiltinClassInstanceXML(cx, &js_NamespaceClass); | |
19824 | if (!obj) | |
19825 | return (JSIntn)0; | |
19826 | } | |
19827 | *rval = OBJECT_TO_JSVAL(obj); | |
19828 | ; | |
19829 | empty = cx->runtime->emptyString; | |
19830 | obj->setNamePrefix(empty); | |
19831 | obj->setNameURI(empty); | |
19832 | if (argc == 1 || argc == -1) { | |
19833 | if (isNamespace) { | |
19834 | obj->setNameURI(uriobj->getNameURI()); | |
19835 | obj->setNamePrefix(uriobj->getNamePrefix()); | |
19836 | } else if (isQName && (uri = uriobj->getNameURI())) { | |
19837 | obj->setNameURI(uri); | |
19838 | obj->setNamePrefix(uriobj->getNamePrefix()); | |
19839 | } else { | |
19840 | JSString *str = js_ValueToString(cx, Valueify(urival)); | |
19841 | if (!str) | |
19842 | return (JSIntn)0; | |
19843 | uri = str->ensureLinear(cx); | |
19844 | if (!uri) | |
19845 | return (JSIntn)0; | |
19846 | obj->setNameURI(uri); | |
19847 | if (!uri->empty()) | |
19848 | obj->clearNamePrefix(); | |
19849 | } | |
19850 | } else if (argc == 2) { | |
19851 | if (!isQName || !(uri = uriobj->getNameURI())) { | |
19852 | JSString *str = js_ValueToString(cx, Valueify(urival)); | |
19853 | if (!str) | |
19854 | return (JSIntn)0; | |
19855 | uri = str->ensureLinear(cx); | |
19856 | if (!uri) | |
19857 | return (JSIntn)0; | |
19858 | } | |
19859 | obj->setNameURI(uri); | |
19860 | prefixval = argv[0]; | |
19861 | if (uri->empty()) { | |
19862 | if (!JSVAL_IS_VOID(prefixval)) { | |
19863 | JSString *str = js_ValueToString(cx, Valueify(prefixval)); | |
19864 | if (!str) | |
19865 | return (JSIntn)0; | |
19866 | if (!str->empty()) { | |
19867 | JSAutoByteString bytes; | |
19868 | if (js_ValueToPrintable(cx, StringValue(str), &bytes)) { | |
19869 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, | |
19870 | JSMSG_BAD_XML_NAMESPACE, bytes.ptr()); | |
19871 | } | |
19872 | return (JSIntn)0; | |
19873 | } | |
19874 | } | |
19875 | } else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) { | |
19876 | obj->clearNamePrefix(); | |
19877 | } else { | |
19878 | JSString *str = js_ValueToString(cx, Valueify(prefixval)); | |
19879 | if (!str) | |
19880 | return (JSIntn)0; | |
19881 | prefix = str->ensureLinear(cx); | |
19882 | if (!prefix) | |
19883 | return (JSIntn)0; | |
19884 | obj->setNamePrefix(prefix); | |
19885 | } | |
19886 | } | |
19887 | return (JSIntn)1; | |
19888 | } | |
19889 | static JSBool | |
19890 | Namespace(JSContext *cx, uintN argc, Value *vp) | |
19891 | { | |
19892 | JSObject *thisobj = __null; | |
19893 | (void)IsConstructing_PossiblyWithGivenThisObject(vp, &thisobj); | |
19894 | return NamespaceHelper(cx, thisobj, argc, Jsvalify(vp + 2), Jsvalify(vp)); | |
19895 | } | |
19896 | static JSBool | |
19897 | QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval) | |
19898 | { | |
19899 | jsval nameval, nsval; | |
19900 | JSBool isQName, isNamespace; | |
19901 | JSObject *qn; | |
19902 | JSLinearString *uri, *prefix, *name; | |
19903 | JSObject *obj2; | |
19904 | if (argc <= 0) { | |
19905 | nameval = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
19906 | isQName = (JSIntn)0; | |
19907 | } else { | |
19908 | nameval = argv[argc > 1]; | |
19909 | isQName = | |
19910 | !JSVAL_IS_PRIMITIVE(nameval) && | |
19911 | JSVAL_TO_OBJECT(nameval)->getClass() == &js_QNameClass; | |
19912 | } | |
19913 | if (!obj) { | |
19914 | if (argc == 1 && isQName) { | |
19915 | *rval = nameval; | |
19916 | return (JSIntn)1; | |
19917 | } | |
19918 | obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass); | |
19919 | if (!obj) | |
19920 | return (JSIntn)0; | |
19921 | } | |
19922 | *rval = OBJECT_TO_JSVAL(obj); | |
19923 | ; | |
19924 | if (isQName) { | |
19925 | qn = JSVAL_TO_OBJECT(nameval); | |
19926 | if (argc == 1) { | |
19927 | uri = qn->getNameURI(); | |
19928 | prefix = qn->getNamePrefix(); | |
19929 | name = qn->getQNameLocalName(); | |
19930 | goto out; | |
19931 | } | |
19932 | nameval = qn->getQNameLocalNameVal(); | |
19933 | } | |
19934 | if (argc == 0) { | |
19935 | name = cx->runtime->emptyString; | |
19936 | } else if (argc < 0) { | |
19937 | name = (cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); | |
19938 | } else { | |
19939 | JSString *str = js_ValueToString(cx, Valueify(nameval)); | |
19940 | if (!str) | |
19941 | return (JSIntn)0; | |
19942 | name = str->ensureLinear(cx); | |
19943 | if (!name) | |
19944 | return (JSIntn)0; | |
19945 | argv[argc > 1] = STRING_TO_JSVAL(name); | |
19946 | } | |
19947 | if (argc > 1 && !JSVAL_IS_VOID(argv[0])) { | |
19948 | nsval = argv[0]; | |
19949 | } else if (((name)->length() == 1 && *(name)->chars() == '*')) { | |
19950 | nsval = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
19951 | } else { | |
19952 | if (!js_GetDefaultXMLNamespace(cx, &nsval)) | |
19953 | return (JSIntn)0; | |
19954 | ((void) 0); | |
19955 | ((void) 0) | |
19956 | ; | |
19957 | } | |
19958 | if (JSVAL_IS_NULL(nsval)) { | |
19959 | prefix = uri = __null; | |
19960 | } else { | |
19961 | isNamespace = isQName = (JSIntn)0; | |
19962 | if (!JSVAL_IS_PRIMITIVE(nsval)) { | |
19963 | obj2 = JSVAL_TO_OBJECT(nsval); | |
19964 | isNamespace = (obj2->getClass() == &js_NamespaceClass); | |
19965 | isQName = (obj2->getClass() == &js_QNameClass); | |
19966 | } | |
19967 | else obj2 = __null; | |
19968 | if (isNamespace) { | |
19969 | uri = obj2->getNameURI(); | |
19970 | prefix = obj2->getNamePrefix(); | |
19971 | } else if (isQName && (uri = obj2->getNameURI())) { | |
19972 | ((void) 0); | |
19973 | prefix = obj2->getNamePrefix(); | |
19974 | } else { | |
19975 | ((void) 0); | |
19976 | JSString *str = js_ValueToString(cx, Valueify(nsval)); | |
19977 | if (!str) | |
19978 | return (JSIntn)0; | |
19979 | uri = str->ensureLinear(cx); | |
19980 | if (!uri) | |
19981 | return (JSIntn)0; | |
19982 | argv[0] = STRING_TO_JSVAL(uri); | |
19983 | prefix = uri->empty() ? cx->runtime->emptyString : __null; | |
19984 | } | |
19985 | } | |
19986 | out: | |
19987 | InitXMLQName(obj, uri, prefix, name); | |
19988 | return (JSIntn)1; | |
19989 | } | |
19990 | static JSBool | |
19991 | QName(JSContext *cx, uintN argc, Value *vp) | |
19992 | { | |
19993 | JSObject *thisobj = __null; | |
19994 | (void)IsConstructing_PossiblyWithGivenThisObject(vp, &thisobj); | |
19995 | return QNameHelper(cx, thisobj, argc, Jsvalify(vp + 2), Jsvalify(vp)); | |
19996 | } | |
19997 | static JSBool | |
19998 | namespace_identity(const void *a, const void *b) | |
19999 | { | |
20000 | const JSObject *nsa = (const JSObject *) a; | |
20001 | const JSObject *nsb = (const JSObject *) b; | |
20002 | JSLinearString *prefixa = nsa->getNamePrefix(); | |
20003 | JSLinearString *prefixb = nsb->getNamePrefix(); | |
20004 | if (prefixa && prefixb) { | |
20005 | if (!EqualStrings(prefixa, prefixb)) | |
20006 | return (JSIntn)0; | |
20007 | } else { | |
20008 | if (prefixa || prefixb) | |
20009 | return (JSIntn)0; | |
20010 | } | |
20011 | return EqualStrings(nsa->getNameURI(), nsb->getNameURI()); | |
20012 | } | |
20013 | static JSBool | |
20014 | attr_identity(const void *a, const void *b) | |
20015 | { | |
20016 | const JSXML *xmla = (const JSXML *) a; | |
20017 | const JSXML *xmlb = (const JSXML *) b; | |
20018 | return qname_identity(xmla->name, xmlb->name); | |
20019 | } | |
20020 | void | |
20021 | JSXMLArrayCursor::trace(JSTracer *trc) { | |
20022 | for (JSXMLArrayCursor *cursor = this; cursor; cursor = cursor->next) | |
20023 | js::gc::MarkGCThing(trc, cursor->root, "cursor_root", index++); | |
20024 | } | |
20025 | static void | |
20026 | XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor *cursor) | |
20027 | { | |
20028 | cursor->trace(trc); | |
20029 | } | |
20030 | bool | |
20031 | JSXMLArray::setCapacity(JSContext *cx, uint32 newCapacity) | |
20032 | { | |
20033 | if (newCapacity == 0) { | |
20034 | if (vector) { | |
20035 | if (cx) | |
20036 | cx->free(vector); | |
20037 | else | |
20038 | js_free(vector); | |
20039 | } | |
20040 | vector = __null; | |
20041 | } else { | |
20042 | void **tmp; | |
20043 | if ( | |
20044 | !(tmp = (void **) js_realloc(vector, newCapacity * sizeof(void *)))) { | |
20045 | if (cx) | |
20046 | JS_ReportOutOfMemory(cx); | |
20047 | return false; | |
20048 | } | |
20049 | vector = tmp; | |
20050 | } | |
20051 | capacity = ((JSUint32)1 << (31)) | newCapacity; | |
20052 | return true; | |
20053 | } | |
20054 | void | |
20055 | JSXMLArray::trim() | |
20056 | { | |
20057 | if (capacity & ((JSUint32)1 << (31))) | |
20058 | return; | |
20059 | if (length < capacity) | |
20060 | setCapacity(__null, length); | |
20061 | } | |
20062 | void | |
20063 | JSXMLArray::finish(JSContext *cx) | |
20064 | { | |
20065 | cx->free(vector); | |
20066 | while (JSXMLArrayCursor *cursor = cursors) | |
20067 | cursor->disconnect(); | |
20068 | } | |
20069 | static uint32 | |
20070 | XMLArrayFindMember(const JSXMLArray *array, void *elt, JSIdentityOp identity) | |
20071 | { | |
20072 | void **vector; | |
20073 | uint32 i, n; | |
20074 | vector = array->vector; | |
20075 | if (identity) { | |
20076 | for (i = 0, n = array->length; i < n; i++) { | |
20077 | if (identity(vector[i], elt)) | |
20078 | return i; | |
20079 | } | |
20080 | } else { | |
20081 | for (i = 0, n = array->length; i < n; i++) { | |
20082 | if (vector[i] == elt) | |
20083 | return i; | |
20084 | } | |
20085 | } | |
20086 | return ((uint32) -1); | |
20087 | } | |
20088 | static JSBool | |
20089 | XMLArrayAddMember(JSContext *cx, JSXMLArray *array, uint32 index, void *elt) | |
20090 | { | |
20091 | uint32 capacity, i; | |
20092 | int log2; | |
20093 | void **vector; | |
20094 | if (index >= array->length) { | |
20095 | if (index >= ((array)->capacity & (((JSUint32)1 << (31)) - 1))) { | |
20096 | capacity = index + 1; | |
20097 | if (index >= 256) { | |
20098 | capacity = ((((capacity)+(32)-1)/(32))*(32)); | |
20099 | } else { | |
20100 | do { unsigned int j_ = (unsigned int)(capacity); (log2) = (j_ <= 1 ? 0 : 32 - __builtin_clz(j_ - 1)); } while (0); | |
20101 | capacity = ((JSUint32)1 << (log2)); | |
20102 | } | |
20103 | if ( | |
20104 | !(vector = (void **) | |
20105 | js_realloc(array->vector, capacity * sizeof(void *)))) { | |
20106 | JS_ReportOutOfMemory(cx); | |
20107 | return (JSIntn)0; | |
20108 | } | |
20109 | array->capacity = capacity; | |
20110 | array->vector = vector; | |
20111 | for (i = array->length; i < index; i++) | |
20112 | vector[i] = __null; | |
20113 | } | |
20114 | array->length = index + 1; | |
20115 | } | |
20116 | array->vector[index] = elt; | |
20117 | return (JSIntn)1; | |
20118 | } | |
20119 | static JSBool | |
20120 | XMLArrayInsert(JSContext *cx, JSXMLArray *array, uint32 i, uint32 n) | |
20121 | { | |
20122 | uint32 j; | |
20123 | JSXMLArrayCursor *cursor; | |
20124 | j = array->length; | |
20125 | ((void) 0); | |
20126 | if (!array->setCapacity(cx, j + n)) | |
20127 | return (JSIntn)0; | |
20128 | array->length = j + n; | |
20129 | ((void) 0); | |
20130 | while (j != i) { | |
20131 | --j; | |
20132 | array->vector[j + n] = array->vector[j]; | |
20133 | } | |
20134 | for (cursor = array->cursors; cursor; cursor = cursor->next) { | |
20135 | if (cursor->index > i) | |
20136 | cursor->index += n; | |
20137 | } | |
20138 | return (JSIntn)1; | |
20139 | } | |
20140 | static void * | |
20141 | XMLArrayDelete(JSContext *cx, JSXMLArray *array, uint32 index, JSBool compress) | |
20142 | { | |
20143 | uint32 length; | |
20144 | void **vector, *elt; | |
20145 | JSXMLArrayCursor *cursor; | |
20146 | length = array->length; | |
20147 | if (index >= length) | |
20148 | return __null; | |
20149 | vector = array->vector; | |
20150 | elt = vector[index]; | |
20151 | if (compress) { | |
20152 | while (++index < length) | |
20153 | vector[index-1] = vector[index]; | |
20154 | array->length = length - 1; | |
20155 | array->capacity = ((array)->capacity & (((JSUint32)1 << (31)) - 1)); | |
20156 | } else { | |
20157 | vector[index] = __null; | |
20158 | } | |
20159 | for (cursor = array->cursors; cursor; cursor = cursor->next) { | |
20160 | if (cursor->index > index) | |
20161 | --cursor->index; | |
20162 | } | |
20163 | return elt; | |
20164 | } | |
20165 | static void | |
20166 | XMLArrayTruncate(JSContext *cx, JSXMLArray *array, uint32 length) | |
20167 | { | |
20168 | void **vector; | |
20169 | ((void) 0); | |
20170 | if (length >= array->length) | |
20171 | return; | |
20172 | if (length == 0) { | |
20173 | if (array->vector) | |
20174 | cx->free(array->vector); | |
20175 | vector = __null; | |
20176 | } else { | |
20177 | vector = (void **) js_realloc(array->vector, length * sizeof(void *)); | |
20178 | if (!vector) | |
20179 | return; | |
20180 | } | |
20181 | if (array->length > length) | |
20182 | array->length = length; | |
20183 | array->capacity = length; | |
20184 | array->vector = vector; | |
20185 | } | |
20186 | static const char js_ignoreComments_str[] = "ignoreComments"; | |
20187 | static const char js_ignoreProcessingInstructions_str[] | |
20188 | = "ignoreProcessingInstructions"; | |
20189 | static const char js_ignoreWhitespace_str[] = "ignoreWhitespace"; | |
20190 | static const char js_prettyPrinting_str[] = "prettyPrinting"; | |
20191 | static const char js_prettyIndent_str[] = "prettyIndent"; | |
20192 | static JSPropertySpec xml_static_props[] = { | |
20193 | {js_ignoreComments_str, 0, 0x04, __null, __null}, | |
20194 | {js_ignoreProcessingInstructions_str, 0, 0x04, __null, __null}, | |
20195 | {js_ignoreWhitespace_str, 0, 0x04, __null, __null}, | |
20196 | {js_prettyPrinting_str, 0, 0x04, __null, __null}, | |
20197 | {js_prettyIndent_str, 0, 0x04, __null, __null}, | |
20198 | {0,0,0,0,0} | |
20199 | }; | |
20200 | static const char xml_namespace_str[] = "http://www.w3.org/XML/1998/namespace"; | |
20201 | static const char xmlns_namespace_str[] = "http://www.w3.org/2000/xmlns/"; | |
20202 | static JSObject * | |
20203 | ParseNodeToQName(Parser *parser, JSParseNode *pn, | |
20204 | JSXMLArray *inScopeNSes, JSBool isAttributeName) | |
20205 | { | |
20206 | JSContext *cx = parser->context; | |
20207 | JSLinearString *str, *uri, *prefix, *localName; | |
20208 | size_t length, offset; | |
20209 | const jschar *start, *limit, *colon; | |
20210 | uint32 n; | |
20211 | JSObject *ns; | |
20212 | JSLinearString *nsprefix; | |
20213 | ((void) 0); | |
20214 | str = pn->pn_u.name.atom; | |
20215 | start = str->chars(); | |
20216 | length = str->length(); | |
20217 | ((void) 0); | |
20218 | ((void) 0); | |
20219 | uri = cx->runtime->emptyString; | |
20220 | limit = start + length; | |
20221 | colon = js_strchr_limit(start, ':', limit); | |
20222 | if (colon) { | |
20223 | offset = colon - start; | |
20224 | prefix = js_NewDependentString(cx, str, 0, offset); | |
20225 | if (!prefix) | |
20226 | return __null; | |
20227 | if ((offset >= 3 && (((jschar) (((js_A[js_Y[(js_X[(uint16)((start)[0])>>6]<<6)|(((start)[0])&0x3F)]]) & 0x00200000) ? ((start)[0]) + ((int32)(js_A[js_Y[(js_X[(uint16)((start)[0])>>6]<<6)|(((start)[0])&0x3F)]]) >> 22) : ((start)[0]))) == 'x' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((start)[1])>>6]<<6)|(((start)[1])&0x3F)]]) & 0x00200000) ? ((start)[1]) + ((int32)(js_A[js_Y[(js_X[(uint16)((start)[1])>>6]<<6)|(((start)[1])&0x3F)]]) >> 22) : ((start)[1]))) == 'm' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((start)[2])>>6]<<6)|(((start)[2])&0x3F)]]) & 0x00200000) ? ((start)[2]) + ((int32)(js_A[js_Y[(js_X[(uint16)((start)[2])>>6]<<6)|(((start)[2])&0x3F)]]) >> 22) : ((start)[2]))) == 'l'))) { | |
20228 | if (offset == 3) { | |
20229 | uri = JS_ASSERT_STRING_IS_FLAT(JS_InternString(cx, xml_namespace_str)); | |
20230 | if (!uri) | |
20231 | return __null; | |
20232 | } else if (offset == 5 && (((jschar) (((js_A[js_Y[(js_X[(uint16)((start)[3])>>6]<<6)|(((start)[3])&0x3F)]]) & 0x00200000) ? ((start)[3]) + ((int32)(js_A[js_Y[(js_X[(uint16)((start)[3])>>6]<<6)|(((start)[3])&0x3F)]]) >> 22) : ((start)[3]))) == 'n' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((start)[4])>>6]<<6)|(((start)[4])&0x3F)]]) & 0x00200000) ? ((start)[4]) + ((int32)(js_A[js_Y[(js_X[(uint16)((start)[4])>>6]<<6)|(((start)[4])&0x3F)]]) >> 22) : ((start)[4]))) == 's')) { | |
20233 | uri = JS_ASSERT_STRING_IS_FLAT(JS_InternString(cx, xmlns_namespace_str)); | |
20234 | if (!uri) | |
20235 | return __null; | |
20236 | } else { | |
20237 | uri = __null; | |
20238 | } | |
20239 | } else { | |
20240 | uri = __null; | |
20241 | n = inScopeNSes->length; | |
20242 | while (n != 0) { | |
20243 | --n; | |
20244 | ns = (((n) < (inScopeNSes)->length) ? (JSObject *) (inScopeNSes)->vector[n] : __null); | |
20245 | nsprefix = ns->getNamePrefix(); | |
20246 | if (nsprefix && EqualStrings(nsprefix, prefix)) { | |
20247 | uri = ns->getNameURI(); | |
20248 | break; | |
20249 | } | |
20250 | } | |
20251 | } | |
20252 | if (!uri) { | |
20253 | Value v = StringValue(prefix); | |
20254 | JSAutoByteString bytes; | |
20255 | if (js_ValueToPrintable(parser->context, v, &bytes)) { | |
20256 | ReportCompileErrorNumber(parser->context, &parser->tokenStream, pn, | |
20257 | 0x0, JSMSG_BAD_XML_NAMESPACE, bytes.ptr()); | |
20258 | } | |
20259 | return __null; | |
20260 | } | |
20261 | localName = js_NewStringCopyN(parser->context, colon + 1, length - (offset + 1)); | |
20262 | if (!localName) | |
20263 | return __null; | |
20264 | } else { | |
20265 | if (isAttributeName) { | |
20266 | prefix = uri; | |
20267 | } else { | |
20268 | n = inScopeNSes->length; | |
20269 | while (n != 0) { | |
20270 | --n; | |
20271 | ns = (((n) < (inScopeNSes)->length) ? (JSObject *) (inScopeNSes)->vector[n] : __null); | |
20272 | nsprefix = ns->getNamePrefix(); | |
20273 | if (!nsprefix || nsprefix->empty()) { | |
20274 | uri = ns->getNameURI(); | |
20275 | break; | |
20276 | } | |
20277 | } | |
20278 | prefix = uri->empty() ? parser->context->runtime->emptyString : __null; | |
20279 | } | |
20280 | localName = str; | |
20281 | } | |
20282 | return NewXMLQName(parser->context, uri, prefix, localName); | |
20283 | } | |
20284 | static JSString * | |
20285 | ChompXMLWhitespace(JSContext *cx, JSString *str) | |
20286 | { | |
20287 | size_t length, newlength, offset; | |
20288 | const jschar *cp, *start, *end; | |
20289 | jschar c; | |
20290 | length = str->length(); | |
20291 | start = str->getChars(cx); | |
20292 | if (!start) | |
20293 | return __null; | |
20294 | for (cp = start, end = cp + length; cp < end; cp++) { | |
20295 | c = *cp; | |
20296 | if (!((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')) | |
20297 | break; | |
20298 | } | |
20299 | while (end > cp) { | |
20300 | c = end[-1]; | |
20301 | if (!((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')) | |
20302 | break; | |
20303 | --end; | |
20304 | } | |
20305 | newlength = end - cp; | |
20306 | if (newlength == length) | |
20307 | return str; | |
20308 | offset = cp - start; | |
20309 | return js_NewDependentString(cx, str, offset, newlength); | |
20310 | } | |
20311 | static JSXML * | |
20312 | ParseNodeToXML(Parser *parser, JSParseNode *pn, | |
20313 | JSXMLArray *inScopeNSes, uintN flags) | |
20314 | { | |
20315 | JSContext *cx = parser->context; | |
20316 | JSXML *xml, *kid, *attr, *attrj; | |
20317 | JSLinearString *str; | |
20318 | uint32 length, n, i, j; | |
20319 | JSParseNode *pn2, *pn3, *head, **pnp; | |
20320 | JSObject *ns; | |
20321 | JSObject *qn, *attrjqn; | |
20322 | JSXMLClass xml_class; | |
20323 | int stackDummy; | |
20324 | if (!((jsuword)(&stackDummy) > cx->stackLimit)) { | |
20325 | ReportCompileErrorNumber(cx, &parser->tokenStream, pn, 0x0, | |
20326 | JSMSG_OVER_RECURSED); | |
20327 | return __null; | |
20328 | } | |
20329 | xml = __null; | |
20330 | if (!js_EnterLocalRootScope(cx)) | |
20331 | return __null; | |
20332 | switch (pn->pn_type) { | |
20333 | case TOK_XMLELEM: | |
20334 | length = inScopeNSes->length; | |
20335 | pn2 = pn->pn_u.list.head; | |
20336 | xml = ParseNodeToXML(parser, pn2, inScopeNSes, flags); | |
20337 | if (!xml) | |
20338 | goto fail; | |
20339 | n = pn->pn_u.list.count; | |
20340 | ((void) 0); | |
20341 | n -= 2; | |
20342 | if (!xml->u.list.kids.setCapacity(cx, n)) | |
20343 | goto fail; | |
20344 | i = 0; | |
20345 | while ((pn2 = pn2->pn_next) != __null) { | |
20346 | if (!pn2->pn_next) { | |
20347 | ((void) 0); | |
20348 | break; | |
20349 | } | |
20350 | if ((flags & ((JSUint32)1 << (2))) && | |
20351 | n > 1 && pn2->pn_type == TOK_XMLSPACE) { | |
20352 | --n; | |
20353 | continue; | |
20354 | } | |
20355 | kid = ParseNodeToXML(parser, pn2, inScopeNSes, flags); | |
20356 | if (kid == ((JSXML *) 1)) { | |
20357 | --n; | |
20358 | continue; | |
20359 | } | |
20360 | if (!kid) | |
20361 | goto fail; | |
20362 | do { if ((&xml->u.list.kids)->length <= (i)) (&xml->u.list.kids)->length = (i) + 1; ((&xml->u.list.kids)->vector[i] = (void *)(kid)); } while (0); | |
20363 | kid->parent = xml; | |
20364 | ++i; | |
20365 | if ((flags & ((JSUint32)1 << (2))) && | |
20366 | n > 1 && kid->xml_class == JSXML_CLASS_TEXT) { | |
20367 | JSString *str = ChompXMLWhitespace(cx, kid->u.value); | |
20368 | if (!str) | |
20369 | goto fail; | |
20370 | kid->u.value = str; | |
20371 | } | |
20372 | } | |
20373 | ((void) 0); | |
20374 | if (n < pn->pn_u.list.count - 2) | |
20375 | xml->u.list.kids.trim(); | |
20376 | XMLArrayTruncate(cx, inScopeNSes, length); | |
20377 | break; | |
20378 | case TOK_XMLLIST: | |
20379 | xml = js_NewXML(cx, JSXML_CLASS_LIST); | |
20380 | if (!xml) | |
20381 | goto fail; | |
20382 | n = pn->pn_u.list.count; | |
20383 | if (!xml->u.list.kids.setCapacity(cx, n)) | |
20384 | goto fail; | |
20385 | i = 0; | |
20386 | for (pn2 = pn->pn_u.list.head; pn2; pn2 = pn2->pn_next) { | |
20387 | if (pn2->pn_type == TOK_XMLSPACE) { | |
20388 | --n; | |
20389 | continue; | |
20390 | } | |
20391 | kid = ParseNodeToXML(parser, pn2, inScopeNSes, flags); | |
20392 | if (kid == ((JSXML *) 1)) { | |
20393 | --n; | |
20394 | continue; | |
20395 | } | |
20396 | if (!kid) | |
20397 | goto fail; | |
20398 | do { if ((&xml->u.list.kids)->length <= (i)) (&xml->u.list.kids)->length = (i) + 1; ((&xml->u.list.kids)->vector[i] = (void *)(kid)); } while (0); | |
20399 | ++i; | |
20400 | } | |
20401 | if (n < pn->pn_u.list.count) | |
20402 | xml->u.list.kids.trim(); | |
20403 | break; | |
20404 | case TOK_XMLSTAGO: | |
20405 | case TOK_XMLPTAGC: | |
20406 | length = inScopeNSes->length; | |
20407 | pn2 = pn->pn_u.list.head; | |
20408 | ((void) 0); | |
20409 | if (pn2->pn_arity == PN_LIST) | |
20410 | goto syntax; | |
20411 | xml = js_NewXML(cx, JSXML_CLASS_ELEMENT); | |
20412 | if (!xml) | |
20413 | goto fail; | |
20414 | ((void) 0); | |
20415 | n = pn->pn_u.list.count - 1; | |
20416 | pnp = &pn2->pn_next; | |
20417 | head = *pnp; | |
20418 | while ((pn2 = *pnp) != __null) { | |
20419 | size_t length; | |
20420 | const jschar *chars; | |
20421 | if (pn2->pn_type != TOK_XMLNAME || pn2->pn_arity != PN_NULLARY) | |
20422 | goto syntax; | |
20423 | for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) { | |
20424 | if (pn3->pn_u.name.atom == pn2->pn_u.name.atom) { | |
20425 | Value v = StringValue((pn2->pn_u.name.atom)); | |
20426 | JSAutoByteString bytes; | |
20427 | if (js_ValueToPrintable(cx, v, &bytes)) { | |
20428 | ReportCompileErrorNumber(cx, &parser->tokenStream, pn2, | |
20429 | 0x0, JSMSG_DUPLICATE_XML_ATTR, | |
20430 | bytes.ptr()); | |
20431 | } | |
20432 | goto fail; | |
20433 | } | |
20434 | } | |
20435 | JSAtom *atom = pn2->pn_u.name.atom; | |
20436 | pn2 = pn2->pn_next; | |
20437 | ((void) 0); | |
20438 | if (pn2->pn_type != TOK_XMLATTR) | |
20439 | goto syntax; | |
20440 | chars = atom->chars(); | |
20441 | length = atom->length(); | |
20442 | if (length >= 5 && | |
20443 | ((((jschar) (((js_A[js_Y[(js_X[(uint16)((chars)[0])>>6]<<6)|(((chars)[0])&0x3F)]]) & 0x00200000) ? ((chars)[0]) + ((int32)(js_A[js_Y[(js_X[(uint16)((chars)[0])>>6]<<6)|(((chars)[0])&0x3F)]]) >> 22) : ((chars)[0]))) == 'x' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((chars)[1])>>6]<<6)|(((chars)[1])&0x3F)]]) & 0x00200000) ? ((chars)[1]) + ((int32)(js_A[js_Y[(js_X[(uint16)((chars)[1])>>6]<<6)|(((chars)[1])&0x3F)]]) >> 22) : ((chars)[1]))) == 'm' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((chars)[2])>>6]<<6)|(((chars)[2])&0x3F)]]) & 0x00200000) ? ((chars)[2]) + ((int32)(js_A[js_Y[(js_X[(uint16)((chars)[2])>>6]<<6)|(((chars)[2])&0x3F)]]) >> 22) : ((chars)[2]))) == 'l') && (((jschar) (((js_A[js_Y[(js_X[(uint16)((chars)[3])>>6]<<6)|(((chars)[3])&0x3F)]]) & 0x00200000) ? ((chars)[3]) + ((int32)(js_A[js_Y[(js_X[(uint16)((chars)[3])>>6]<<6)|(((chars)[3])&0x3F)]]) >> 22) : ((chars)[3]))) == 'n' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((chars)[4])>>6]<<6)|(((chars)[4])&0x3F)]]) & 0x00200000) ? ((chars)[4]) + ((int32)(js_A[js_Y[(js_X[(uint16)((chars)[4])>>6]<<6)|(((chars)[4])&0x3F)]]) >> 22) : ((chars)[4]))) == 's')) && | |
20444 | (length == 5 || chars[5] == ':')) { | |
20445 | JSLinearString *uri, *prefix; | |
20446 | uri = (pn2->pn_u.name.atom); | |
20447 | if (length == 5) { | |
20448 | prefix = cx->runtime->emptyString; | |
20449 | } else { | |
20450 | prefix = js_NewStringCopyN(cx, chars + 6, length - 6); | |
20451 | if (!prefix) | |
20452 | goto fail; | |
20453 | } | |
20454 | ns = NewXMLNamespace(cx, prefix, uri, (JSIntn)1); | |
20455 | if (!ns) | |
20456 | goto fail; | |
20457 | if (!(XMLArrayFindMember(inScopeNSes, (void *)(ns), namespace_identity) != ((uint32) -1))) { | |
20458 | if (!XMLArrayAddMember(cx, inScopeNSes, (inScopeNSes)->length, (void *)((ns))) || | |
20459 | !XMLArrayAddMember(cx, &xml->u.elem.namespaces, (&xml->u.elem.namespaces)->length, (void *)((ns)))) { | |
20460 | goto fail; | |
20461 | } | |
20462 | } | |
20463 | ((void) 0); | |
20464 | n -= 2; | |
20465 | *pnp = pn2->pn_next; | |
20466 | continue; | |
20467 | } | |
20468 | pnp = &pn2->pn_next; | |
20469 | } | |
20470 | xml->u.elem.namespaces.trim(); | |
20471 | pn2 = pn->pn_u.list.head; | |
20472 | qn = ParseNodeToQName(parser, pn2, inScopeNSes, (JSIntn)0); | |
20473 | if (!qn) | |
20474 | goto fail; | |
20475 | xml->name = qn; | |
20476 | ((void) 0); | |
20477 | n >>= 1; | |
20478 | if (!xml->u.elem.attrs.setCapacity(cx, n)) | |
20479 | goto fail; | |
20480 | for (i = 0; (pn2 = pn2->pn_next) != __null; i++) { | |
20481 | qn = ParseNodeToQName(parser, pn2, inScopeNSes, (JSIntn)1); | |
20482 | if (!qn) { | |
20483 | xml->u.elem.attrs.length = i; | |
20484 | goto fail; | |
20485 | } | |
20486 | for (j = 0; j < i; j++) { | |
20487 | attrj = (((j) < (&xml->u.elem.attrs)->length) ? (JSXML *) (&xml->u.elem.attrs)->vector[j] : __null); | |
20488 | attrjqn = attrj->name; | |
20489 | if (EqualStrings(attrjqn->getNameURI(), qn->getNameURI()) && | |
20490 | EqualStrings(attrjqn->getQNameLocalName(), qn->getQNameLocalName())) { | |
20491 | Value v = StringValue((pn2->pn_u.name.atom)); | |
20492 | JSAutoByteString bytes; | |
20493 | if (js_ValueToPrintable(cx, v, &bytes)) { | |
20494 | ReportCompileErrorNumber(cx, &parser->tokenStream, pn2, | |
20495 | 0x0, JSMSG_DUPLICATE_XML_ATTR, | |
20496 | bytes.ptr()); | |
20497 | } | |
20498 | goto fail; | |
20499 | } | |
20500 | } | |
20501 | pn2 = pn2->pn_next; | |
20502 | ((void) 0); | |
20503 | ((void) 0); | |
20504 | attr = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE); | |
20505 | if (!attr) | |
20506 | goto fail; | |
20507 | do { if ((&xml->u.elem.attrs)->length <= (i)) (&xml->u.elem.attrs)->length = (i) + 1; ((&xml->u.elem.attrs)->vector[i] = (void *)(attr)); } while (0); | |
20508 | attr->parent = xml; | |
20509 | attr->name = qn; | |
20510 | attr->u.value = (pn2->pn_u.name.atom); | |
20511 | } | |
20512 | if (pn->pn_type == TOK_XMLPTAGC) | |
20513 | XMLArrayTruncate(cx, inScopeNSes, length); | |
20514 | break; | |
20515 | case TOK_XMLSPACE: | |
20516 | case TOK_XMLTEXT: | |
20517 | case TOK_XMLCDATA: | |
20518 | case TOK_XMLCOMMENT: | |
20519 | case TOK_XMLPI: | |
20520 | str = (pn->pn_u.name.atom); | |
20521 | qn = __null; | |
20522 | if (pn->pn_type == TOK_XMLCOMMENT) { | |
20523 | if (flags & ((JSUint32)1 << (0))) | |
20524 | goto skip_child; | |
20525 | xml_class = JSXML_CLASS_COMMENT; | |
20526 | } else if (pn->pn_type == TOK_XMLPI) { | |
20527 | if ((str->length() == 3 && (((jschar) (((js_A[js_Y[(js_X[(uint16)((str->chars())[0])>>6]<<6)|(((str->chars())[0])&0x3F)]]) & 0x00200000) ? ((str->chars())[0]) + ((int32)(js_A[js_Y[(js_X[(uint16)((str->chars())[0])>>6]<<6)|(((str->chars())[0])&0x3F)]]) >> 22) : ((str->chars())[0]))) == 'x' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((str->chars())[1])>>6]<<6)|(((str->chars())[1])&0x3F)]]) & 0x00200000) ? ((str->chars())[1]) + ((int32)(js_A[js_Y[(js_X[(uint16)((str->chars())[1])>>6]<<6)|(((str->chars())[1])&0x3F)]]) >> 22) : ((str->chars())[1]))) == 'm' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((str->chars())[2])>>6]<<6)|(((str->chars())[2])&0x3F)]]) & 0x00200000) ? ((str->chars())[2]) + ((int32)(js_A[js_Y[(js_X[(uint16)((str->chars())[2])>>6]<<6)|(((str->chars())[2])&0x3F)]]) >> 22) : ((str->chars())[2]))) == 'l'))) { | |
20528 | Value v = StringValue(str); | |
20529 | JSAutoByteString bytes; | |
20530 | if (js_ValueToPrintable(cx, v, &bytes)) { | |
20531 | ReportCompileErrorNumber(cx, &parser->tokenStream, pn, | |
20532 | 0x0, JSMSG_RESERVED_ID, bytes.ptr()); | |
20533 | } | |
20534 | goto fail; | |
20535 | } | |
20536 | if (flags & ((JSUint32)1 << (1))) | |
20537 | goto skip_child; | |
20538 | qn = ParseNodeToQName(parser, pn, inScopeNSes, (JSIntn)0); | |
20539 | if (!qn) | |
20540 | goto fail; | |
20541 | str = pn->pn_u.apair.atom2 | |
20542 | ? (pn->pn_u.apair.atom2) | |
20543 | : cx->runtime->emptyString; | |
20544 | xml_class = JSXML_CLASS_PROCESSING_INSTRUCTION; | |
20545 | } else { | |
20546 | xml_class = JSXML_CLASS_TEXT; | |
20547 | } | |
20548 | xml = js_NewXML(cx, xml_class); | |
20549 | if (!xml) | |
20550 | goto fail; | |
20551 | xml->name = qn; | |
20552 | if (pn->pn_type == TOK_XMLSPACE) | |
20553 | xml->xml_flags |= 0x1; | |
20554 | xml->u.value = str; | |
20555 | break; | |
20556 | default: | |
20557 | goto syntax; | |
20558 | } | |
20559 | js_LeaveLocalRootScopeWithResult(cx, xml); | |
20560 | return xml; | |
20561 | skip_child: | |
20562 | js_LeaveLocalRootScope(cx); | |
20563 | return ((JSXML *) 1); | |
20564 | syntax: | |
20565 | ReportCompileErrorNumber(cx, &parser->tokenStream, pn, 0x0, JSMSG_BAD_XML_MARKUP); | |
20566 | fail: | |
20567 | js_LeaveLocalRootScope(cx); | |
20568 | return __null; | |
20569 | } | |
20570 | static JSBool | |
20571 | GetXMLSetting(JSContext *cx, const char *name, jsval *vp) | |
20572 | { | |
20573 | jsval v; | |
20574 | if (!js_FindClassObject(cx, __null, JSProto_XML, Valueify(&v))) | |
20575 | return (JSIntn)0; | |
20576 | if (!(!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction())) { | |
20577 | *vp = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
20578 | return (JSIntn)1; | |
20579 | } | |
20580 | return JS_GetProperty(cx, JSVAL_TO_OBJECT(v), name, vp); | |
20581 | } | |
20582 | static JSBool | |
20583 | GetBooleanXMLSetting(JSContext *cx, const char *name, JSBool *bp) | |
20584 | { | |
20585 | jsval v; | |
20586 | return GetXMLSetting(cx, name, &v) && JS_ValueToBoolean(cx, v, bp); | |
20587 | } | |
20588 | static JSBool | |
20589 | GetUint32XMLSetting(JSContext *cx, const char *name, uint32 *uip) | |
20590 | { | |
20591 | jsval v; | |
20592 | return GetXMLSetting(cx, name, &v) && JS_ValueToECMAUint32(cx, v, uip); | |
20593 | } | |
20594 | static JSBool | |
20595 | GetXMLSettingFlags(JSContext *cx, uintN *flagsp) | |
20596 | { | |
20597 | JSBool flag[4]; | |
20598 | if (!GetBooleanXMLSetting(cx, js_ignoreComments_str, &flag[0]) || | |
20599 | !GetBooleanXMLSetting(cx, js_ignoreProcessingInstructions_str, &flag[1]) || | |
20600 | !GetBooleanXMLSetting(cx, js_ignoreWhitespace_str, &flag[2]) || | |
20601 | !GetBooleanXMLSetting(cx, js_prettyPrinting_str, &flag[3])) { | |
20602 | return false; | |
20603 | } | |
20604 | *flagsp = 0; | |
20605 | for (size_t n = 0; n < 4; ++n) | |
20606 | if (flag[n]) | |
20607 | *flagsp |= ((JSUint32)1 << (n)); | |
20608 | return true; | |
20609 | } | |
20610 | static JSXML * | |
20611 | ParseXMLSource(JSContext *cx, JSString *src) | |
20612 | { | |
20613 | jsval nsval; | |
20614 | JSLinearString *uri; | |
20615 | size_t urilen, srclen, length, offset, dstlen; | |
20616 | jschar *chars; | |
20617 | const jschar *srcp, *endp; | |
20618 | JSXML *xml; | |
20619 | const char *filename; | |
20620 | uintN lineno; | |
20621 | JSOp op; | |
20622 | static const char prefix[] = "<parent xmlns=\""; | |
20623 | static const char middle[] = "\">"; | |
20624 | static const char suffix[] = "</parent>"; | |
20625 | if (!js_GetDefaultXMLNamespace(cx, &nsval)) | |
20626 | return __null; | |
20627 | uri = JSVAL_TO_OBJECT(nsval)->getNameURI(); | |
20628 | uri = js_EscapeAttributeValue(cx, uri, (JSIntn)0); | |
20629 | if (!uri) | |
20630 | return __null; | |
20631 | urilen = uri->length(); | |
20632 | srclen = src->length(); | |
20633 | length = (sizeof(prefix) - 1) + urilen + (sizeof(middle) - 1) + srclen + | |
20634 | (sizeof(suffix) - 1); | |
20635 | chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar)); | |
20636 | if (!chars) | |
20637 | return __null; | |
20638 | dstlen = length; | |
20639 | js_InflateStringToBuffer(cx, prefix, (sizeof(prefix) - 1), chars, &dstlen); | |
20640 | offset = dstlen; | |
20641 | memcpy((chars + offset), (uri->chars()), (urilen) * sizeof(jschar)); | |
20642 | offset += urilen; | |
20643 | dstlen = length - offset + 1; | |
20644 | js_InflateStringToBuffer(cx, middle, (sizeof(middle) - 1), chars + offset, | |
20645 | &dstlen); | |
20646 | offset += dstlen; | |
20647 | srcp = src->getChars(cx); | |
20648 | if (!srcp) { | |
20649 | cx->free(chars); | |
20650 | return __null; | |
20651 | } | |
20652 | memcpy((chars + offset), (srcp), (srclen) * sizeof(jschar)); | |
20653 | offset += srclen; | |
20654 | dstlen = length - offset + 1; | |
20655 | js_InflateStringToBuffer(cx, suffix, (sizeof(suffix) - 1), chars + offset, | |
20656 | &dstlen); | |
20657 | chars [offset + dstlen] = 0; | |
20658 | LeaveTrace(cx); | |
20659 | xml = __null; | |
20660 | FrameRegsIter i(cx); | |
20661 | for (; !i.done() && !i.pc(); ++i) | |
20662 | ((void) 0); | |
20663 | filename = __null; | |
20664 | lineno = 1; | |
20665 | if (!i.done()) { | |
20666 | JSStackFrame *fp = i.fp(); | |
20667 | op = (JSOp) *i.pc(); | |
20668 | if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) { | |
20669 | filename = fp->script()->filename; | |
20670 | lineno = js_FramePCToLineNumber(cx, fp); | |
20671 | for (endp = srcp + srclen; srcp < endp; srcp++) { | |
20672 | if (*srcp == '\n') | |
20673 | --lineno; | |
20674 | } | |
20675 | } | |
20676 | } | |
20677 | { | |
20678 | Parser parser(cx); | |
20679 | if (parser.init(chars, length, filename, lineno, cx->findVersion())) { | |
20680 | JSObject *scopeChain = GetScopeChain(cx); | |
20681 | if (!scopeChain) { | |
20682 | cx->free(chars); | |
20683 | return __null; | |
20684 | } | |
20685 | JSParseNode *pn = parser.parseXMLText(scopeChain, false); | |
20686 | uintN flags; | |
20687 | if (pn && GetXMLSettingFlags(cx, &flags)) { | |
20688 | AutoNamespaceArray namespaces(cx); | |
20689 | if (namespaces.array.setCapacity(cx, 1)) | |
20690 | xml = ParseNodeToXML(&parser, pn, &namespaces.array, flags); | |
20691 | } | |
20692 | } | |
20693 | } | |
20694 | cx->free(chars); | |
20695 | return xml; | |
20696 | } | |
20697 | static JSXML * | |
20698 | OrphanXMLChild(JSContext *cx, JSXML *xml, uint32 i) | |
20699 | { | |
20700 | JSObject *ns; | |
20701 | ns = (((0) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[0] : __null); | |
20702 | xml = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
20703 | if (!ns || !xml) | |
20704 | return xml; | |
20705 | if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
20706 | if (!XMLArrayAddMember(cx, &xml->u.elem.namespaces, (&xml->u.elem.namespaces)->length, (void *)((ns)))) | |
20707 | return __null; | |
20708 | ns->setNamespaceDeclared(((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0))); | |
20709 | } | |
20710 | xml->parent = __null; | |
20711 | return xml; | |
20712 | } | |
20713 | static JSObject * | |
20714 | ToXML(JSContext *cx, jsval v) | |
20715 | { | |
20716 | JSObject *obj; | |
20717 | JSXML *xml; | |
20718 | Class *clasp; | |
20719 | JSString *str; | |
20720 | uint32 length; | |
20721 | if (JSVAL_IS_PRIMITIVE(v)) { | |
20722 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) | |
20723 | goto bad; | |
20724 | } else { | |
20725 | obj = JSVAL_TO_OBJECT(v); | |
20726 | if (obj->isXML()) { | |
20727 | xml = (JSXML *) obj->getPrivate(); | |
20728 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
20729 | if (xml->u.list.kids.length != 1) | |
20730 | goto bad; | |
20731 | xml = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
20732 | if (xml) { | |
20733 | ((void) 0); | |
20734 | return js_GetXMLObject(cx, xml); | |
20735 | } | |
20736 | } | |
20737 | return obj; | |
20738 | } | |
20739 | clasp = obj->getClass(); | |
20740 | if (clasp->flags & (1<<7)) { | |
20741 | ((void) 0); | |
20742 | } | |
20743 | if (clasp != &js_StringClass && | |
20744 | clasp != &js_NumberClass && | |
20745 | clasp != &js_BooleanClass) { | |
20746 | goto bad; | |
20747 | } | |
20748 | } | |
20749 | str = js_ValueToString(cx, Valueify(v)); | |
20750 | if (!str) | |
20751 | return __null; | |
20752 | if (str->empty()) { | |
20753 | length = 0; | |
20754 | xml = __null; | |
20755 | } else { | |
20756 | xml = ParseXMLSource(cx, str); | |
20757 | if (!xml) | |
20758 | return __null; | |
20759 | length = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
20760 | } | |
20761 | if (length == 0) { | |
20762 | obj = js_NewXMLObject(cx, JSXML_CLASS_TEXT); | |
20763 | if (!obj) | |
20764 | return __null; | |
20765 | } else if (length == 1) { | |
20766 | xml = OrphanXMLChild(cx, xml, 0); | |
20767 | if (!xml) | |
20768 | return __null; | |
20769 | obj = js_GetXMLObject(cx, xml); | |
20770 | if (!obj) | |
20771 | return __null; | |
20772 | } else { | |
20773 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_SYNTAX_ERROR); | |
20774 | return __null; | |
20775 | } | |
20776 | return obj; | |
20777 | bad: | |
20778 | ((void)js_ReportValueErrorFlags(cx, 0x0, JSMSG_BAD_XML_CONVERSION, 0, Valueify(v), __null, __null, __null)) | |
20779 | ; | |
20780 | return __null; | |
20781 | } | |
20782 | static JSBool | |
20783 | Append(JSContext *cx, JSXML *list, JSXML *kid); | |
20784 | static JSObject * | |
20785 | ToXMLList(JSContext *cx, jsval v) | |
20786 | { | |
20787 | JSObject *obj, *listobj; | |
20788 | JSXML *xml, *list, *kid; | |
20789 | Class *clasp; | |
20790 | JSString *str; | |
20791 | uint32 i, length; | |
20792 | if (JSVAL_IS_PRIMITIVE(v)) { | |
20793 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) | |
20794 | goto bad; | |
20795 | } else { | |
20796 | obj = JSVAL_TO_OBJECT(v); | |
20797 | if (obj->isXML()) { | |
20798 | xml = (JSXML *) obj->getPrivate(); | |
20799 | if (xml->xml_class != JSXML_CLASS_LIST) { | |
20800 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
20801 | if (!listobj) | |
20802 | return __null; | |
20803 | list = (JSXML *) listobj->getPrivate(); | |
20804 | if (!Append(cx, list, xml)) | |
20805 | return __null; | |
20806 | return listobj; | |
20807 | } | |
20808 | return obj; | |
20809 | } | |
20810 | clasp = obj->getClass(); | |
20811 | if (clasp->flags & (1<<7)) { | |
20812 | ((void) 0); | |
20813 | } | |
20814 | if (clasp != &js_StringClass && | |
20815 | clasp != &js_NumberClass && | |
20816 | clasp != &js_BooleanClass) { | |
20817 | goto bad; | |
20818 | } | |
20819 | } | |
20820 | str = js_ValueToString(cx, Valueify(v)); | |
20821 | if (!str) | |
20822 | return __null; | |
20823 | if (str->empty()) { | |
20824 | xml = __null; | |
20825 | length = 0; | |
20826 | } else { | |
20827 | if (!js_EnterLocalRootScope(cx)) | |
20828 | return __null; | |
20829 | xml = ParseXMLSource(cx, str); | |
20830 | if (!xml) { | |
20831 | js_LeaveLocalRootScope(cx); | |
20832 | return __null; | |
20833 | } | |
20834 | length = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
20835 | } | |
20836 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
20837 | if (listobj) { | |
20838 | list = (JSXML *) listobj->getPrivate(); | |
20839 | for (i = 0; i < length; i++) { | |
20840 | kid = OrphanXMLChild(cx, xml, i); | |
20841 | if (!kid || !Append(cx, list, kid)) { | |
20842 | listobj = __null; | |
20843 | break; | |
20844 | } | |
20845 | } | |
20846 | } | |
20847 | if (xml) | |
20848 | js_LeaveLocalRootScopeWithResult(cx, listobj); | |
20849 | return listobj; | |
20850 | bad: | |
20851 | ((void)js_ReportValueErrorFlags(cx, 0x0, JSMSG_BAD_XMLLIST_CONVERSION, 0, Valueify(v), __null, __null, __null)) | |
20852 | ; | |
20853 | return __null; | |
20854 | } | |
20855 | static JSFlatString * | |
20856 | MakeXMLSpecialString(JSContext *cx, StringBuffer &sb, | |
20857 | JSString *str, JSString *str2, | |
20858 | const jschar *prefix, size_t prefixlength, | |
20859 | const jschar *suffix, size_t suffixlength) | |
20860 | { | |
20861 | if (!sb.append(prefix, prefixlength) || !sb.append(str)) | |
20862 | return __null; | |
20863 | if (str2 && !str2->empty()) { | |
20864 | if (!sb.append(' ') || !sb.append(str2)) | |
20865 | return __null; | |
20866 | } | |
20867 | if (!sb.append(suffix, suffixlength)) | |
20868 | return __null; | |
20869 | return sb.finishString(); | |
20870 | } | |
20871 | static JSFlatString * | |
20872 | MakeXMLCDATAString(JSContext *cx, StringBuffer &sb, JSString *str) | |
20873 | { | |
20874 | static const jschar cdata_prefix_ucNstr[] = {'<', '!', '[', | |
20875 | 'C', 'D', 'A', 'T', 'A', | |
20876 | '['}; | |
20877 | static const jschar cdata_suffix_ucNstr[] = {']', ']', '>'}; | |
20878 | return MakeXMLSpecialString(cx, sb, str, __null, | |
20879 | cdata_prefix_ucNstr, 9, | |
20880 | cdata_suffix_ucNstr, 3); | |
20881 | } | |
20882 | static JSFlatString * | |
20883 | MakeXMLCommentString(JSContext *cx, StringBuffer &sb, JSString *str) | |
20884 | { | |
20885 | static const jschar comment_prefix_ucNstr[] = {'<', '!', '-', '-'}; | |
20886 | static const jschar comment_suffix_ucNstr[] = {'-', '-', '>'}; | |
20887 | return MakeXMLSpecialString(cx, sb, str, __null, | |
20888 | comment_prefix_ucNstr, 4, | |
20889 | comment_suffix_ucNstr, 3); | |
20890 | } | |
20891 | static JSFlatString * | |
20892 | MakeXMLPIString(JSContext *cx, StringBuffer &sb, JSString *name, | |
20893 | JSString *value) | |
20894 | { | |
20895 | static const jschar pi_prefix_ucNstr[] = {'<', '?'}; | |
20896 | static const jschar pi_suffix_ucNstr[] = {'?', '>'}; | |
20897 | return MakeXMLSpecialString(cx, sb, name, value, | |
20898 | pi_prefix_ucNstr, 2, | |
20899 | pi_suffix_ucNstr, 2); | |
20900 | } | |
20901 | static | |
20902 | bool | |
20903 | AppendAttributeValue(JSContext *cx, StringBuffer &sb, JSString *valstr) | |
20904 | { | |
20905 | if (!sb.append('=')) | |
20906 | return false; | |
20907 | valstr = js_EscapeAttributeValue(cx, valstr, (JSIntn)1); | |
20908 | return valstr && sb.append(valstr); | |
20909 | } | |
20910 | static JSFlatString * | |
20911 | EscapeElementValue(JSContext *cx, StringBuffer &sb, JSString *str, uint32 toSourceFlag) | |
20912 | { | |
20913 | size_t length = str->length(); | |
20914 | const jschar *start = str->getChars(cx); | |
20915 | if (!start) | |
20916 | return __null; | |
20917 | for (const jschar *cp = start, *end = start + length; cp != end; ++cp) { | |
20918 | jschar c = *cp; | |
20919 | switch (*cp) { | |
20920 | case '<': | |
20921 | if (!sb.append(js_lt_entity_str)) | |
20922 | return __null; | |
20923 | break; | |
20924 | case '>': | |
20925 | if (!sb.append(js_gt_entity_str)) | |
20926 | return __null; | |
20927 | break; | |
20928 | case '&': | |
20929 | if (!sb.append(js_amp_entity_str)) | |
20930 | return __null; | |
20931 | break; | |
20932 | case '{': | |
20933 | if (toSourceFlag) { | |
20934 | if (!sb.append(js_leftcurly_entity_str)) | |
20935 | return __null; | |
20936 | break; | |
20937 | } | |
20938 | default: | |
20939 | if (!sb.append(c)) | |
20940 | return __null; | |
20941 | } | |
20942 | } | |
20943 | return sb.finishString(); | |
20944 | } | |
20945 | static JSFlatString * | |
20946 | EscapeAttributeValue(JSContext *cx, StringBuffer &sb, JSString *str, JSBool quote) | |
20947 | { | |
20948 | size_t length = str->length(); | |
20949 | const jschar *start = str->getChars(cx); | |
20950 | if (!start) | |
20951 | return __null; | |
20952 | if (quote && !sb.append('"')) | |
20953 | return __null; | |
20954 | for (const jschar *cp = start, *end = start + length; cp != end; ++cp) { | |
20955 | jschar c = *cp; | |
20956 | switch (c) { | |
20957 | case '"': | |
20958 | if (!sb.append(js_quot_entity_str)) | |
20959 | return __null; | |
20960 | break; | |
20961 | case '<': | |
20962 | if (!sb.append(js_lt_entity_str)) | |
20963 | return __null; | |
20964 | break; | |
20965 | case '&': | |
20966 | if (!sb.append(js_amp_entity_str)) | |
20967 | return __null; | |
20968 | break; | |
20969 | case '\n': | |
20970 | if (!sb.append("
")) | |
20971 | return __null; | |
20972 | break; | |
20973 | case '\r': | |
20974 | if (!sb.append("
")) | |
20975 | return __null; | |
20976 | break; | |
20977 | case '\t': | |
20978 | if (!sb.append("	")) | |
20979 | return __null; | |
20980 | break; | |
20981 | default: | |
20982 | if (!sb.append(c)) | |
20983 | return __null; | |
20984 | } | |
20985 | } | |
20986 | if (quote && !sb.append('"')) | |
20987 | return __null; | |
20988 | return sb.finishString(); | |
20989 | } | |
20990 | static JSObject * | |
20991 | GetNamespace(JSContext *cx, JSObject *qn, const JSXMLArray *inScopeNSes) | |
20992 | { | |
20993 | JSLinearString *uri, *prefix, *nsprefix; | |
20994 | JSObject *match, *ns; | |
20995 | uint32 i, n; | |
20996 | jsval argv[2]; | |
20997 | uri = qn->getNameURI(); | |
20998 | prefix = qn->getNamePrefix(); | |
20999 | ((void) 0); | |
21000 | if (!uri) { | |
21001 | JSAutoByteString bytes; | |
21002 | const char *s = !prefix ? | |
21003 | js_undefined_str | |
21004 | : js_ValueToPrintable(cx, StringValue(prefix), &bytes); | |
21005 | if (s) | |
21006 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_BAD_XML_NAMESPACE, s); | |
21007 | return __null; | |
21008 | } | |
21009 | match = __null; | |
21010 | if (inScopeNSes) { | |
21011 | for (i = 0, n = inScopeNSes->length; i < n; i++) { | |
21012 | ns = (((i) < (inScopeNSes)->length) ? (JSObject *) (inScopeNSes)->vector[i] : __null); | |
21013 | if (!ns) | |
21014 | continue; | |
21015 | if (EqualStrings(ns->getNameURI(), uri)) { | |
21016 | nsprefix = ns->getNamePrefix(); | |
21017 | if (nsprefix == prefix || | |
21018 | ((nsprefix && prefix) | |
21019 | ? EqualStrings(nsprefix, prefix) | |
21020 | : (nsprefix ? nsprefix : prefix)->empty())) { | |
21021 | match = ns; | |
21022 | break; | |
21023 | } | |
21024 | } | |
21025 | } | |
21026 | } | |
21027 | if (!match) { | |
21028 | argv[0] = prefix ? STRING_TO_JSVAL(prefix) : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
21029 | argv[1] = STRING_TO_JSVAL(uri); | |
21030 | ns = js_ConstructObject(cx, &js_NamespaceClass, __null, __null, | |
21031 | 2, Valueify(argv)); | |
21032 | if (!ns) | |
21033 | return __null; | |
21034 | match = ns; | |
21035 | } | |
21036 | return match; | |
21037 | } | |
21038 | static JSLinearString * | |
21039 | GeneratePrefix(JSContext *cx, JSLinearString *uri, JSXMLArray *decls) | |
21040 | { | |
21041 | const jschar *cp, *start, *end; | |
21042 | size_t length, newlength, offset; | |
21043 | uint32 i, n, m, serial; | |
21044 | jschar *bp, *dp; | |
21045 | JSBool done; | |
21046 | JSObject *ns; | |
21047 | JSLinearString *nsprefix, *prefix; | |
21048 | ((void) 0); | |
21049 | if (decls->length == 0) | |
21050 | return js_NewStringCopyZ(cx, "a"); | |
21051 | start = uri->chars(); | |
21052 | end = start + uri->length(); | |
21053 | cp = end; | |
21054 | while (--cp > start) { | |
21055 | if (*cp == '.' || *cp == '/' || *cp == ':') { | |
21056 | ++cp; | |
21057 | length = end - cp; | |
21058 | if (IsXMLName(cp, length) && !(length >= 3 && (((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[0])>>6]<<6)|(((cp)[0])&0x3F)]]) & 0x00200000) ? ((cp)[0]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[0])>>6]<<6)|(((cp)[0])&0x3F)]]) >> 22) : ((cp)[0]))) == 'x' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[1])>>6]<<6)|(((cp)[1])&0x3F)]]) & 0x00200000) ? ((cp)[1]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[1])>>6]<<6)|(((cp)[1])&0x3F)]]) >> 22) : ((cp)[1]))) == 'm' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[2])>>6]<<6)|(((cp)[2])&0x3F)]]) & 0x00200000) ? ((cp)[2]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[2])>>6]<<6)|(((cp)[2])&0x3F)]]) >> 22) : ((cp)[2]))) == 'l'))) | |
21059 | break; | |
21060 | end = --cp; | |
21061 | } | |
21062 | } | |
21063 | length = end - cp; | |
21064 | bp = (jschar *) cp; | |
21065 | newlength = length; | |
21066 | if ((length >= 3 && (((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[0])>>6]<<6)|(((cp)[0])&0x3F)]]) & 0x00200000) ? ((cp)[0]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[0])>>6]<<6)|(((cp)[0])&0x3F)]]) >> 22) : ((cp)[0]))) == 'x' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[1])>>6]<<6)|(((cp)[1])&0x3F)]]) & 0x00200000) ? ((cp)[1]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[1])>>6]<<6)|(((cp)[1])&0x3F)]]) >> 22) : ((cp)[1]))) == 'm' && ((jschar) (((js_A[js_Y[(js_X[(uint16)((cp)[2])>>6]<<6)|(((cp)[2])&0x3F)]]) & 0x00200000) ? ((cp)[2]) + ((int32)(js_A[js_Y[(js_X[(uint16)((cp)[2])>>6]<<6)|(((cp)[2])&0x3F)]]) >> 22) : ((cp)[2]))) == 'l')) || !IsXMLName(cp, length)) { | |
21067 | newlength = length + 2 + (size_t) log10((double) decls->length); | |
21068 | bp = (jschar *) | |
21069 | cx->malloc((newlength + 1) * sizeof(jschar)); | |
21070 | if (!bp) | |
21071 | return __null; | |
21072 | bp[newlength] = 0; | |
21073 | for (i = 0; i < newlength; i++) | |
21074 | bp[i] = 'a'; | |
21075 | } | |
21076 | serial = 0; | |
21077 | do { | |
21078 | done = (JSIntn)1; | |
21079 | for (i = 0, n = decls->length; i < n; i++) { | |
21080 | ns = (((i) < (decls)->length) ? (JSObject *) (decls)->vector[i] : __null); | |
21081 | if (ns && (nsprefix = ns->getNamePrefix()) && | |
21082 | nsprefix->length() == newlength && | |
21083 | !memcmp(nsprefix->chars(), bp, | |
21084 | newlength * sizeof(jschar))) { | |
21085 | if (bp == cp) { | |
21086 | newlength = length + 2 + (size_t) log10((double) n); | |
21087 | bp = (jschar *) | |
21088 | cx->malloc((newlength + 1) * sizeof(jschar)); | |
21089 | if (!bp) | |
21090 | return __null; | |
21091 | memcpy((bp), (cp), (length) * sizeof(jschar)); | |
21092 | } | |
21093 | ++serial; | |
21094 | ((void) 0); | |
21095 | dp = bp + length + 2 + (size_t) log10((double) serial); | |
21096 | *dp = 0; | |
21097 | for (m = serial; m != 0; m /= 10) | |
21098 | *--dp = (jschar)('0' + m % 10); | |
21099 | *--dp = '-'; | |
21100 | ((void) 0); | |
21101 | done = (JSIntn)0; | |
21102 | break; | |
21103 | } | |
21104 | } | |
21105 | } while (!done); | |
21106 | if (bp == cp) { | |
21107 | offset = cp - start; | |
21108 | prefix = js_NewDependentString(cx, uri, offset, length); | |
21109 | } else { | |
21110 | prefix = js_NewString(cx, bp, newlength); | |
21111 | if (!prefix) | |
21112 | cx->free(bp); | |
21113 | } | |
21114 | return prefix; | |
21115 | } | |
21116 | static JSBool | |
21117 | namespace_match(const void *a, const void *b) | |
21118 | { | |
21119 | const JSObject *nsa = (const JSObject *) a; | |
21120 | const JSObject *nsb = (const JSObject *) b; | |
21121 | JSLinearString *prefixa, *prefixb = nsb->getNamePrefix(); | |
21122 | if (prefixb) { | |
21123 | prefixa = nsa->getNamePrefix(); | |
21124 | return prefixa && EqualStrings(prefixa, prefixb); | |
21125 | } | |
21126 | return EqualStrings(nsa->getNameURI(), nsb->getNameURI()); | |
21127 | } | |
21128 | static JSString * | |
21129 | XMLToXMLString(JSContext *cx, JSXML *xml, const JSXMLArray *ancestorNSes, | |
21130 | uint32 indentLevel) | |
21131 | { | |
21132 | JSBool pretty, indentKids; | |
21133 | StringBuffer sb(cx); | |
21134 | JSString *str; | |
21135 | JSLinearString *prefix, *nsuri; | |
21136 | uint32 i, n, nextIndentLevel; | |
21137 | JSObject *ns, *ns2; | |
21138 | AutoNamespaceArray empty(cx), decls(cx), ancdecls(cx); | |
21139 | if (!GetBooleanXMLSetting(cx, js_prettyPrinting_str, &pretty)) | |
21140 | return __null; | |
21141 | if (pretty) { | |
21142 | if (!sb.appendN(' ', indentLevel & ~0x80000000)) | |
21143 | return __null; | |
21144 | } | |
21145 | str = __null; | |
21146 | switch (xml->xml_class) { | |
21147 | case JSXML_CLASS_TEXT: | |
21148 | if (pretty) { | |
21149 | str = ChompXMLWhitespace(cx, xml->u.value); | |
21150 | if (!str) | |
21151 | return __null; | |
21152 | } else { | |
21153 | str = xml->u.value; | |
21154 | } | |
21155 | return EscapeElementValue(cx, sb, str, indentLevel & 0x80000000); | |
21156 | case JSXML_CLASS_ATTRIBUTE: | |
21157 | return EscapeAttributeValue(cx, sb, xml->u.value, | |
21158 | (indentLevel & 0x80000000) != 0); | |
21159 | case JSXML_CLASS_COMMENT: | |
21160 | return MakeXMLCommentString(cx, sb, xml->u.value); | |
21161 | case JSXML_CLASS_PROCESSING_INSTRUCTION: | |
21162 | return MakeXMLPIString(cx, sb, xml->name->getQNameLocalName(), | |
21163 | xml->u.value); | |
21164 | case JSXML_CLASS_LIST: | |
21165 | { | |
21166 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
21167 | i = 0; | |
21168 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
21169 | if (pretty && i != 0) { | |
21170 | if (!sb.append('\n')) | |
21171 | return __null; | |
21172 | } | |
21173 | JSString *kidstr = XMLToXMLString(cx, kid, ancestorNSes, indentLevel); | |
21174 | if (!kidstr || !sb.append(kidstr)) | |
21175 | return __null; | |
21176 | ++i; | |
21177 | } | |
21178 | } | |
21179 | if (sb.empty()) | |
21180 | return cx->runtime->emptyString; | |
21181 | return sb.finishString(); | |
21182 | default:; | |
21183 | } | |
21184 | if (!js_EnterLocalRootScope(cx)) | |
21185 | return __null; | |
21186 | if (!ancestorNSes) | |
21187 | ancestorNSes = &empty.array; | |
21188 | { | |
21189 | JSXMLArrayCursor cursor(&xml->u.elem.namespaces); | |
21190 | while ((ns = (JSObject *) cursor.getNext()) != __null) { | |
21191 | if (!IsDeclared(ns)) | |
21192 | continue; | |
21193 | if (!(XMLArrayFindMember(ancestorNSes, (void *)(ns), namespace_identity) != ((uint32) -1))) { | |
21194 | ns2 = NewXMLNamespace(cx, ns->getNamePrefix(), ns->getNameURI(), (JSIntn)1); | |
21195 | if (!ns2 || !XMLArrayAddMember(cx, &decls.array, (&decls.array)->length, (void *)((ns2)))) | |
21196 | goto out; | |
21197 | } | |
21198 | } | |
21199 | } | |
21200 | if (!ancdecls.array.setCapacity(cx, ancestorNSes->length + decls.length())) | |
21201 | goto out; | |
21202 | for (i = 0, n = ancestorNSes->length; i < n; i++) { | |
21203 | ns2 = (((i) < (ancestorNSes)->length) ? (JSObject *) (ancestorNSes)->vector[i] : __null); | |
21204 | if (!ns2) | |
21205 | continue; | |
21206 | ((void) 0); | |
21207 | if (!XMLArrayAddMember(cx, &ancdecls.array, (&ancdecls.array)->length, (void *)((ns2)))) | |
21208 | goto out; | |
21209 | } | |
21210 | for (i = 0, n = decls.length(); i < n; i++) { | |
21211 | ns2 = (((i) < (&decls.array)->length) ? (JSObject *) (&decls.array)->vector[i] : __null); | |
21212 | if (!ns2) | |
21213 | continue; | |
21214 | ((void) 0); | |
21215 | if (!XMLArrayAddMember(cx, &ancdecls.array, (&ancdecls.array)->length, (void *)((ns2)))) | |
21216 | goto out; | |
21217 | } | |
21218 | ns = GetNamespace(cx, xml->name, &ancdecls.array); | |
21219 | if (!ns) | |
21220 | goto out; | |
21221 | prefix = ns->getNamePrefix(); | |
21222 | if (!prefix) { | |
21223 | nsuri = ns->getNameURI(); | |
21224 | if (!xml->name->getNamePrefix()) { | |
21225 | prefix = cx->runtime->emptyString; | |
21226 | } else { | |
21227 | prefix = GeneratePrefix(cx, nsuri, &ancdecls.array); | |
21228 | if (!prefix) | |
21229 | goto out; | |
21230 | } | |
21231 | ns = NewXMLNamespace(cx, prefix, nsuri, (JSIntn)1); | |
21232 | if (!ns) | |
21233 | goto out; | |
21234 | if (prefix->empty()) { | |
21235 | i = XMLArrayFindMember(&decls.array, ns, namespace_match); | |
21236 | if (i != ((uint32) -1)) | |
21237 | XMLArrayDelete(cx, &decls.array, i, (JSIntn)1); | |
21238 | } | |
21239 | if (!XMLArrayAddMember(cx, &ancdecls.array, (&ancdecls.array)->length, (void *)((ns))) || | |
21240 | !XMLArrayAddMember(cx, &decls.array, (&decls.array)->length, (void *)((ns)))) { | |
21241 | goto out; | |
21242 | } | |
21243 | } | |
21244 | if (!sb.append('<')) | |
21245 | goto out; | |
21246 | if (!prefix->empty()) { | |
21247 | if (!sb.append(prefix) || !sb.append(':')) | |
21248 | goto out; | |
21249 | } | |
21250 | if (!sb.append(xml->name->getQNameLocalName())) | |
21251 | goto out; | |
21252 | { | |
21253 | JSXMLArrayCursor cursor(&xml->u.elem.attrs); | |
21254 | while (JSXML *attr = (JSXML *) cursor.getNext()) { | |
21255 | if (!sb.append(' ')) | |
21256 | goto out; | |
21257 | ns2 = GetNamespace(cx, attr->name, &ancdecls.array); | |
21258 | if (!ns2) | |
21259 | goto out; | |
21260 | prefix = ns2->getNamePrefix(); | |
21261 | if (!prefix) { | |
21262 | prefix = GeneratePrefix(cx, ns2->getNameURI(), &ancdecls.array); | |
21263 | if (!prefix) | |
21264 | goto out; | |
21265 | ns2 = NewXMLNamespace(cx, prefix, ns2->getNameURI(), (JSIntn)1); | |
21266 | if (!ns2) | |
21267 | goto out; | |
21268 | if (!XMLArrayAddMember(cx, &ancdecls.array, (&ancdecls.array)->length, (void *)((ns2))) || | |
21269 | !XMLArrayAddMember(cx, &decls.array, (&decls.array)->length, (void *)((ns2)))) { | |
21270 | goto out; | |
21271 | } | |
21272 | } | |
21273 | if (!prefix->empty()) { | |
21274 | if (!sb.append(prefix) || !sb.append(':')) | |
21275 | goto out; | |
21276 | } | |
21277 | if (!sb.append(attr->name->getQNameLocalName())) | |
21278 | goto out; | |
21279 | if (!AppendAttributeValue(cx, sb, attr->u.value)) | |
21280 | goto out; | |
21281 | } | |
21282 | } | |
21283 | { | |
21284 | JSXMLArrayCursor cursor(&decls.array); | |
21285 | while (JSObject *ns3 = (JSObject *) cursor.getNext()) { | |
21286 | ((void) 0); | |
21287 | if (!sb.append(" xmlns")) | |
21288 | goto out; | |
21289 | prefix = ns3->getNamePrefix(); | |
21290 | if (!prefix) { | |
21291 | prefix = GeneratePrefix(cx, ns3->getNameURI(), &ancdecls.array); | |
21292 | if (!prefix) | |
21293 | goto out; | |
21294 | ns3->setNamePrefix(prefix); | |
21295 | } | |
21296 | if (!prefix->empty()) { | |
21297 | if (!sb.append(':') || !sb.append(prefix)) | |
21298 | goto out; | |
21299 | } | |
21300 | if (!AppendAttributeValue(cx, sb, ns3->getNameURI())) | |
21301 | goto out; | |
21302 | } | |
21303 | } | |
21304 | n = xml->u.list.kids.length; | |
21305 | if (n == 0) { | |
21306 | if (!sb.append("/>")) | |
21307 | goto out; | |
21308 | } else { | |
21309 | if (!sb.append('>')) | |
21310 | goto out; | |
21311 | { | |
21312 | JSXML *kid; | |
21313 | indentKids = n > 1 || | |
21314 | (n == 1 && | |
21315 | (kid = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null)) && | |
21316 | kid->xml_class != JSXML_CLASS_TEXT); | |
21317 | } | |
21318 | if (pretty && indentKids) { | |
21319 | if (!GetUint32XMLSetting(cx, js_prettyIndent_str, &i)) | |
21320 | goto out; | |
21321 | nextIndentLevel = indentLevel + i; | |
21322 | } else { | |
21323 | nextIndentLevel = indentLevel & 0x80000000; | |
21324 | } | |
21325 | { | |
21326 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
21327 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
21328 | if (pretty && indentKids) { | |
21329 | if (!sb.append('\n')) | |
21330 | goto out; | |
21331 | } | |
21332 | JSString *kidstr = XMLToXMLString(cx, kid, &ancdecls.array, nextIndentLevel); | |
21333 | if (!kidstr) | |
21334 | goto out; | |
21335 | if (!sb.append(kidstr)) | |
21336 | goto out; | |
21337 | } | |
21338 | } | |
21339 | if (pretty && indentKids) { | |
21340 | if (!sb.append('\n') || | |
21341 | !sb.appendN(' ', indentLevel & ~0x80000000)) | |
21342 | goto out; | |
21343 | } | |
21344 | if (!sb.append("</")) | |
21345 | goto out; | |
21346 | prefix = ns->getNamePrefix(); | |
21347 | if (prefix && !prefix->empty()) { | |
21348 | if (!sb.append(prefix) || !sb.append(':')) | |
21349 | goto out; | |
21350 | } | |
21351 | if (!sb.append(xml->name->getQNameLocalName()) || !sb.append('>')) | |
21352 | goto out; | |
21353 | } | |
21354 | str = sb.finishString(); | |
21355 | out: | |
21356 | js_LeaveLocalRootScopeWithResult(cx, str); | |
21357 | return str; | |
21358 | } | |
21359 | static JSString * | |
21360 | ToXMLString(JSContext *cx, jsval v, uint32 toSourceFlag) | |
21361 | { | |
21362 | JSObject *obj; | |
21363 | JSString *str; | |
21364 | JSXML *xml; | |
21365 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) { | |
21366 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, | |
21367 | JSMSG_BAD_XML_CONVERSION, | |
21368 | JSVAL_IS_NULL(v) ? js_null_str : js_undefined_str); | |
21369 | return __null; | |
21370 | } | |
21371 | if (JSVAL_IS_BOOLEAN(v) || JSVAL_IS_NUMBER(v)) | |
21372 | return js_ValueToString(cx, Valueify(v)); | |
21373 | if (JSVAL_IS_STRING(v)) { | |
21374 | StringBuffer sb(cx); | |
21375 | return EscapeElementValue(cx, sb, JSVAL_TO_STRING(v), toSourceFlag); | |
21376 | } | |
21377 | obj = JSVAL_TO_OBJECT(v); | |
21378 | if (!obj->isXML()) { | |
21379 | if (!DefaultValue(cx, obj, JSTYPE_STRING, Valueify(&v))) | |
21380 | return __null; | |
21381 | str = js_ValueToString(cx, Valueify(v)); | |
21382 | if (!str) | |
21383 | return __null; | |
21384 | StringBuffer sb(cx); | |
21385 | return EscapeElementValue(cx, sb, str, toSourceFlag); | |
21386 | } | |
21387 | xml = (JSXML *) obj->getPrivate(); | |
21388 | return XMLToXMLString(cx, xml, __null, toSourceFlag | 0); | |
21389 | } | |
21390 | static JSObject * | |
21391 | ToAttributeName(JSContext *cx, jsval v) | |
21392 | { | |
21393 | JSLinearString *name, *uri, *prefix; | |
21394 | JSObject *obj; | |
21395 | Class *clasp; | |
21396 | JSObject *qn; | |
21397 | if (JSVAL_IS_STRING(v)) { | |
21398 | name = JSVAL_TO_STRING(v)->ensureLinear(cx); | |
21399 | if (!name) | |
21400 | return __null; | |
21401 | uri = prefix = cx->runtime->emptyString; | |
21402 | } else { | |
21403 | if (JSVAL_IS_PRIMITIVE(v)) { | |
21404 | ((void)js_ReportValueErrorFlags(cx, 0x0, JSMSG_BAD_XML_ATTR_NAME, 0, Valueify(v), __null, __null, __null)) | |
21405 | ; | |
21406 | return __null; | |
21407 | } | |
21408 | obj = JSVAL_TO_OBJECT(v); | |
21409 | clasp = obj->getClass(); | |
21410 | if (clasp == &js_AttributeNameClass) | |
21411 | return obj; | |
21412 | if (clasp == &js_QNameClass) { | |
21413 | qn = obj; | |
21414 | uri = qn->getNameURI(); | |
21415 | prefix = qn->getNamePrefix(); | |
21416 | name = qn->getQNameLocalName(); | |
21417 | } else { | |
21418 | if (clasp == &js_AnyNameClass) { | |
21419 | name = (cx->runtime->atomState.starAtom); | |
21420 | } else { | |
21421 | JSString *str = js_ValueToString(cx, Valueify(v)); | |
21422 | if (!str) | |
21423 | return __null; | |
21424 | name = str->ensureLinear(cx); | |
21425 | if (!name) | |
21426 | return __null; | |
21427 | } | |
21428 | uri = prefix = cx->runtime->emptyString; | |
21429 | } | |
21430 | } | |
21431 | qn = NewXMLAttributeName(cx, uri, prefix, name); | |
21432 | if (!qn) | |
21433 | return __null; | |
21434 | return qn; | |
21435 | } | |
21436 | static void | |
21437 | ReportBadXMLName(JSContext *cx, const Value &idval) | |
21438 | { | |
21439 | ((void)js_ReportValueErrorFlags(cx, 0x0, JSMSG_BAD_XML_NAME, 0, idval, __null, __null, __null)); | |
21440 | } | |
21441 | static JSBool | |
21442 | IsFunctionQName(JSContext *cx, JSObject *qn, jsid *funidp) | |
21443 | { | |
21444 | JSAtom *atom; | |
21445 | JSLinearString *uri; | |
21446 | atom = cx->runtime->atomState.functionNamespaceURIAtom; | |
21447 | uri = qn->getNameURI(); | |
21448 | if (uri && | |
21449 | (uri == (atom) || | |
21450 | EqualStrings(uri, (atom)))) { | |
21451 | return JS_ValueToId(cx, STRING_TO_JSVAL(qn->getQNameLocalName()), funidp); | |
21452 | } | |
21453 | *funidp = ((jsid)0x2); | |
21454 | return (JSIntn)1; | |
21455 | } | |
21456 | JSBool | |
21457 | js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp) | |
21458 | { | |
21459 | if (obj->getClass() == &js_QNameClass) | |
21460 | return IsFunctionQName(cx, obj, funidp); | |
21461 | *funidp = ((jsid)0x2); | |
21462 | return (JSIntn)1; | |
21463 | } | |
21464 | static JSObject * | |
21465 | ToXMLName(JSContext *cx, jsval v, jsid *funidp) | |
21466 | { | |
21467 | JSAtom *atomizedName; | |
21468 | JSString *name; | |
21469 | JSObject *obj; | |
21470 | Class *clasp; | |
21471 | uint32 index; | |
21472 | if (JSVAL_IS_STRING(v)) { | |
21473 | name = JSVAL_TO_STRING(v); | |
21474 | } else { | |
21475 | if (JSVAL_IS_PRIMITIVE(v)) { | |
21476 | ReportBadXMLName(cx, Valueify(v)); | |
21477 | return __null; | |
21478 | } | |
21479 | obj = JSVAL_TO_OBJECT(v); | |
21480 | clasp = obj->getClass(); | |
21481 | if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass) | |
21482 | goto out; | |
21483 | if (clasp == &js_AnyNameClass) { | |
21484 | name = (cx->runtime->atomState.starAtom); | |
21485 | goto construct; | |
21486 | } | |
21487 | name = js_ValueToString(cx, Valueify(v)); | |
21488 | if (!name) | |
21489 | return __null; | |
21490 | } | |
21491 | atomizedName = js_AtomizeString(cx, name, 0); | |
21492 | if (!atomizedName) | |
21493 | return __null; | |
21494 | if (js_IdIsIndex(ATOM_TO_JSID(atomizedName), &index)) | |
21495 | goto bad; | |
21496 | if (*atomizedName->chars() == '@') { | |
21497 | name = js_NewDependentString(cx, name, 1, name->length() - 1); | |
21498 | if (!name) | |
21499 | return __null; | |
21500 | *funidp = ((jsid)0x2); | |
21501 | return ToAttributeName(cx, STRING_TO_JSVAL(name)); | |
21502 | } | |
21503 | construct: | |
21504 | v = STRING_TO_JSVAL(name); | |
21505 | obj = js_ConstructObject(cx, &js_QNameClass, __null, __null, 1, Valueify(&v)); | |
21506 | if (!obj) | |
21507 | return __null; | |
21508 | out: | |
21509 | if (!IsFunctionQName(cx, obj, funidp)) | |
21510 | return __null; | |
21511 | return obj; | |
21512 | bad: | |
21513 | JSAutoByteString bytes; | |
21514 | if (js_ValueToPrintable(cx, StringValue(name), &bytes)) | |
21515 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_BAD_XML_NAME, bytes.ptr()); | |
21516 | return __null; | |
21517 | } | |
21518 | static JSBool | |
21519 | AddInScopeNamespace(JSContext *cx, JSXML *xml, JSObject *ns) | |
21520 | { | |
21521 | JSLinearString *prefix, *prefix2; | |
21522 | JSObject *match, *ns2; | |
21523 | uint32 i, n, m; | |
21524 | if (xml->xml_class != JSXML_CLASS_ELEMENT) | |
21525 | return (JSIntn)1; | |
21526 | prefix = ns->getNamePrefix(); | |
21527 | if (!prefix) { | |
21528 | match = __null; | |
21529 | for (i = 0, n = xml->u.elem.namespaces.length; i < n; i++) { | |
21530 | ns2 = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
21531 | if (ns2 && EqualStrings(ns2->getNameURI(), ns->getNameURI())) { | |
21532 | match = ns2; | |
21533 | break; | |
21534 | } | |
21535 | } | |
21536 | if (!match && !XMLArrayAddMember(cx, &xml->u.elem.namespaces, n, (void *)(ns))) | |
21537 | return (JSIntn)0; | |
21538 | } else { | |
21539 | if (prefix->empty() && xml->name->getNameURI()->empty()) | |
21540 | return (JSIntn)1; | |
21541 | match = __null; | |
21542 | m = ((uint32) -1); | |
21543 | for (i = 0, n = xml->u.elem.namespaces.length; i < n; i++) { | |
21544 | ns2 = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
21545 | if (ns2 && (prefix2 = ns2->getNamePrefix()) && | |
21546 | EqualStrings(prefix2, prefix)) { | |
21547 | match = ns2; | |
21548 | m = i; | |
21549 | break; | |
21550 | } | |
21551 | } | |
21552 | if (match && !EqualStrings(match->getNameURI(), ns->getNameURI())) { | |
21553 | ns2 = ((JSObject *) XMLArrayDelete(cx, &xml->u.elem.namespaces, m, (JSIntn)1)) | |
21554 | ; | |
21555 | ((void) 0); | |
21556 | match->clearNamePrefix(); | |
21557 | if (!AddInScopeNamespace(cx, xml, match)) | |
21558 | return (JSIntn)0; | |
21559 | } | |
21560 | if (!XMLArrayAddMember(cx, &xml->u.elem.namespaces, (&xml->u.elem.namespaces)->length, (void *)((ns)))) | |
21561 | return (JSIntn)0; | |
21562 | } | |
21563 | return (JSIntn)1; | |
21564 | } | |
21565 | static JSBool | |
21566 | Append(JSContext *cx, JSXML *list, JSXML *xml) | |
21567 | { | |
21568 | uint32 i, j, k, n; | |
21569 | JSXML *kid; | |
21570 | ((void) 0); | |
21571 | i = list->u.list.kids.length; | |
21572 | n = 1; | |
21573 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
21574 | list->u.list.target = xml->u.list.target; | |
21575 | list->u.list.targetprop = xml->u.list.targetprop; | |
21576 | n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
21577 | k = i + n; | |
21578 | if (!list->u.list.kids.setCapacity(cx, k)) | |
21579 | return (JSIntn)0; | |
21580 | for (j = 0; j < n; j++) { | |
21581 | kid = (((j) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[j] : __null); | |
21582 | if (kid) | |
21583 | do { if ((&list->u.list.kids)->length <= (i + j)) (&list->u.list.kids)->length = (i + j) + 1; ((&list->u.list.kids)->vector[i + j] = (void *)(kid)); } while (0); | |
21584 | } | |
21585 | return (JSIntn)1; | |
21586 | } | |
21587 | list->u.list.target = xml->parent; | |
21588 | if (xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) | |
21589 | list->u.list.targetprop = __null; | |
21590 | else | |
21591 | list->u.list.targetprop = xml->name; | |
21592 | if (!XMLArrayAddMember(cx, &list->u.list.kids, i, (void *)(xml))) | |
21593 | return (JSIntn)0; | |
21594 | return (JSIntn)1; | |
21595 | } | |
21596 | static JSXML * | |
21597 | DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags); | |
21598 | static JSXML * | |
21599 | DeepCopy(JSContext *cx, JSXML *xml, JSObject *obj, uintN flags) | |
21600 | { | |
21601 | JSXML *copy; | |
21602 | if (!js_EnterLocalRootScope(cx)) | |
21603 | return __null; | |
21604 | copy = DeepCopyInLRS(cx, xml, flags); | |
21605 | if (copy) { | |
21606 | if (obj) { | |
21607 | obj->setPrivate(copy); | |
21608 | copy->object = obj; | |
21609 | } else if (!js_GetXMLObject(cx, copy)) { | |
21610 | copy = __null; | |
21611 | } | |
21612 | } | |
21613 | js_LeaveLocalRootScopeWithResult(cx, copy); | |
21614 | return copy; | |
21615 | } | |
21616 | static JSBool | |
21617 | DeepCopySetInLRS(JSContext *cx, JSXMLArray *from, JSXMLArray *to, JSXML *parent, | |
21618 | uintN flags) | |
21619 | { | |
21620 | uint32 j, n; | |
21621 | JSXML *kid2; | |
21622 | JSString *str; | |
21623 | n = from->length; | |
21624 | if (!to->setCapacity(cx, n)) | |
21625 | return (JSIntn)0; | |
21626 | JSXMLArrayCursor cursor(from); | |
21627 | j = 0; | |
21628 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
21629 | if ((flags & ((JSUint32)1 << (0))) && | |
21630 | kid->xml_class == JSXML_CLASS_COMMENT) { | |
21631 | continue; | |
21632 | } | |
21633 | if ((flags & ((JSUint32)1 << (1))) && | |
21634 | kid->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) { | |
21635 | continue; | |
21636 | } | |
21637 | if ((flags & ((JSUint32)1 << (2))) && | |
21638 | (kid->xml_flags & 0x1)) { | |
21639 | continue; | |
21640 | } | |
21641 | kid2 = DeepCopyInLRS(cx, kid, flags); | |
21642 | if (!kid2) { | |
21643 | to->length = j; | |
21644 | return (JSIntn)0; | |
21645 | } | |
21646 | if ((flags & ((JSUint32)1 << (2))) && | |
21647 | n > 1 && kid2->xml_class == JSXML_CLASS_TEXT) { | |
21648 | str = ChompXMLWhitespace(cx, kid2->u.value); | |
21649 | if (!str) { | |
21650 | to->length = j; | |
21651 | return (JSIntn)0; | |
21652 | } | |
21653 | kid2->u.value = str; | |
21654 | } | |
21655 | do { if ((to)->length <= (j)) (to)->length = (j) + 1; ((to)->vector[j] = (void *)(kid2)); } while (0); | |
21656 | ++j; | |
21657 | if (parent->xml_class != JSXML_CLASS_LIST) | |
21658 | kid2->parent = parent; | |
21659 | } | |
21660 | if (j < n) | |
21661 | to->trim(); | |
21662 | return (JSIntn)1; | |
21663 | } | |
21664 | static JSXML * | |
21665 | DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags) | |
21666 | { | |
21667 | JSXML *copy; | |
21668 | JSObject *qn; | |
21669 | JSBool ok; | |
21670 | uint32 i, n; | |
21671 | JSObject *ns, *ns2; | |
21672 | do { int stackDummy_; if (!((jsuword)(&stackDummy_) > cx->stackLimit)) { js_ReportOverRecursed(cx); return __null; } } while (0); | |
21673 | copy = js_NewXML(cx, JSXMLClass(xml->xml_class)); | |
21674 | if (!copy) | |
21675 | return __null; | |
21676 | qn = xml->name; | |
21677 | if (qn) { | |
21678 | qn = NewXMLQName(cx, qn->getNameURI(), qn->getNamePrefix(), qn->getQNameLocalName()); | |
21679 | if (!qn) { | |
21680 | ok = (JSIntn)0; | |
21681 | goto out; | |
21682 | } | |
21683 | } | |
21684 | copy->name = qn; | |
21685 | copy->xml_flags = xml->xml_flags; | |
21686 | if ((((xml)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) { | |
21687 | copy->u.value = xml->u.value; | |
21688 | ok = (JSIntn)1; | |
21689 | } else { | |
21690 | ok = DeepCopySetInLRS(cx, &xml->u.list.kids, ©->u.list.kids, copy, flags); | |
21691 | if (!ok) | |
21692 | goto out; | |
21693 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
21694 | copy->u.list.target = xml->u.list.target; | |
21695 | copy->u.list.targetprop = xml->u.list.targetprop; | |
21696 | } else { | |
21697 | n = xml->u.elem.namespaces.length; | |
21698 | ok = copy->u.elem.namespaces.setCapacity(cx, n); | |
21699 | if (!ok) | |
21700 | goto out; | |
21701 | for (i = 0; i < n; i++) { | |
21702 | ns = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
21703 | if (!ns) | |
21704 | continue; | |
21705 | ns2 = NewXMLNamespace(cx, ns->getNamePrefix(), ns->getNameURI(), | |
21706 | IsDeclared(ns)); | |
21707 | if (!ns2) { | |
21708 | copy->u.elem.namespaces.length = i; | |
21709 | ok = (JSIntn)0; | |
21710 | goto out; | |
21711 | } | |
21712 | do { if ((©->u.elem.namespaces)->length <= (i)) (©->u.elem.namespaces)->length = (i) + 1; ((©->u.elem.namespaces)->vector[i] = (void *)(ns2)); } while (0); | |
21713 | } | |
21714 | ok = DeepCopySetInLRS(cx, &xml->u.elem.attrs, ©->u.elem.attrs, copy, | |
21715 | 0); | |
21716 | if (!ok) | |
21717 | goto out; | |
21718 | } | |
21719 | } | |
21720 | out: | |
21721 | if (!ok) | |
21722 | return __null; | |
21723 | return copy; | |
21724 | } | |
21725 | static void | |
21726 | DeleteByIndex(JSContext *cx, JSXML *xml, uint32 index) | |
21727 | { | |
21728 | JSXML *kid; | |
21729 | if ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) && index < xml->u.list.kids.length) { | |
21730 | kid = (((index) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[index] : __null); | |
21731 | if (kid) | |
21732 | kid->parent = __null; | |
21733 | XMLArrayDelete(cx, &xml->u.list.kids, index, (JSIntn)1); | |
21734 | } | |
21735 | } | |
21736 | typedef JSBool (*JSXMLNameMatcher)(JSObject *nameqn, JSXML *xml); | |
21737 | static JSBool | |
21738 | MatchAttrName(JSObject *nameqn, JSXML *attr) | |
21739 | { | |
21740 | JSObject *attrqn = attr->name; | |
21741 | JSLinearString *localName = nameqn->getQNameLocalName(); | |
21742 | JSLinearString *uri; | |
21743 | return (((localName)->length() == 1 && *(localName)->chars() == '*') || | |
21744 | EqualStrings(attrqn->getQNameLocalName(), localName)) && | |
21745 | (!(uri = nameqn->getNameURI()) || | |
21746 | EqualStrings(attrqn->getNameURI(), uri)); | |
21747 | } | |
21748 | static JSBool | |
21749 | MatchElemName(JSObject *nameqn, JSXML *elem) | |
21750 | { | |
21751 | JSLinearString *localName = nameqn->getQNameLocalName(); | |
21752 | JSLinearString *uri; | |
21753 | return (((localName)->length() == 1 && *(localName)->chars() == '*') || | |
21754 | (elem->xml_class == JSXML_CLASS_ELEMENT && | |
21755 | EqualStrings(elem->name->getQNameLocalName(), localName))) && | |
21756 | (!(uri = nameqn->getNameURI()) || | |
21757 | (elem->xml_class == JSXML_CLASS_ELEMENT && | |
21758 | EqualStrings(elem->name->getNameURI(), uri))); | |
21759 | } | |
21760 | static JSBool | |
21761 | DescendantsHelper(JSContext *cx, JSXML *xml, JSObject *nameqn, JSXML *list) | |
21762 | { | |
21763 | uint32 i, n; | |
21764 | JSXML *attr, *kid; | |
21765 | do { int stackDummy_; if (!((jsuword)(&stackDummy_) > cx->stackLimit)) { js_ReportOverRecursed(cx); return (JSIntn)0; } } while (0); | |
21766 | if (xml->xml_class == JSXML_CLASS_ELEMENT && | |
21767 | nameqn->getClass() == &js_AttributeNameClass) { | |
21768 | for (i = 0, n = xml->u.elem.attrs.length; i < n; i++) { | |
21769 | attr = (((i) < (&xml->u.elem.attrs)->length) ? (JSXML *) (&xml->u.elem.attrs)->vector[i] : __null); | |
21770 | if (attr && MatchAttrName(nameqn, attr)) { | |
21771 | if (!Append(cx, list, attr)) | |
21772 | return (JSIntn)0; | |
21773 | } | |
21774 | } | |
21775 | } | |
21776 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
21777 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
21778 | if (!kid) | |
21779 | continue; | |
21780 | if (nameqn->getClass() != &js_AttributeNameClass && | |
21781 | MatchElemName(nameqn, kid)) { | |
21782 | if (!Append(cx, list, kid)) | |
21783 | return (JSIntn)0; | |
21784 | } | |
21785 | if (!DescendantsHelper(cx, kid, nameqn, list)) | |
21786 | return (JSIntn)0; | |
21787 | } | |
21788 | return (JSIntn)1; | |
21789 | } | |
21790 | static JSXML * | |
21791 | Descendants(JSContext *cx, JSXML *xml, jsval id) | |
21792 | { | |
21793 | jsid funid; | |
21794 | JSObject *nameqn; | |
21795 | JSObject *listobj; | |
21796 | JSXML *list, *kid; | |
21797 | uint32 i, n; | |
21798 | JSBool ok; | |
21799 | nameqn = ToXMLName(cx, id, &funid); | |
21800 | if (!nameqn) | |
21801 | return __null; | |
21802 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
21803 | if (!listobj) | |
21804 | return __null; | |
21805 | list = (JSXML *) listobj->getPrivate(); | |
21806 | if (!JSID_IS_VOID(funid)) | |
21807 | return list; | |
21808 | list->name = nameqn; | |
21809 | if (!js_EnterLocalRootScope(cx)) | |
21810 | return __null; | |
21811 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
21812 | ok = (JSIntn)1; | |
21813 | for (i = 0, n = xml->u.list.kids.length; i < n; i++) { | |
21814 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
21815 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
21816 | ok = DescendantsHelper(cx, kid, nameqn, list); | |
21817 | if (!ok) | |
21818 | break; | |
21819 | } | |
21820 | } | |
21821 | } else { | |
21822 | ok = DescendantsHelper(cx, xml, nameqn, list); | |
21823 | } | |
21824 | js_LeaveLocalRootScopeWithResult(cx, list); | |
21825 | if (!ok) | |
21826 | return __null; | |
21827 | list->name = __null; | |
21828 | return list; | |
21829 | } | |
21830 | static JSBool | |
21831 | XMLEquals(JSContext *cx, JSXML *xml, JSXML *vxml, JSBool *bp) | |
21832 | { | |
21833 | JSObject *qn, *vqn; | |
21834 | uint32 i, j, n; | |
21835 | JSXML *kid, *vkid, *attr, *vattr; | |
21836 | JSObject *xobj, *vobj; | |
21837 | retry: | |
21838 | if (xml->xml_class != vxml->xml_class) { | |
21839 | if (xml->xml_class == JSXML_CLASS_LIST && xml->u.list.kids.length == 1) { | |
21840 | xml = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
21841 | if (xml) | |
21842 | goto retry; | |
21843 | } | |
21844 | if (vxml->xml_class == JSXML_CLASS_LIST && vxml->u.list.kids.length == 1) { | |
21845 | vxml = (((0) < (&vxml->u.list.kids)->length) ? (JSXML *) (&vxml->u.list.kids)->vector[0] : __null); | |
21846 | if (vxml) | |
21847 | goto retry; | |
21848 | } | |
21849 | *bp = (JSIntn)0; | |
21850 | return (JSIntn)1; | |
21851 | } | |
21852 | qn = xml->name; | |
21853 | vqn = vxml->name; | |
21854 | if (qn) { | |
21855 | *bp = vqn && | |
21856 | EqualStrings(qn->getQNameLocalName(), vqn->getQNameLocalName()) && | |
21857 | EqualStrings(qn->getNameURI(), vqn->getNameURI()); | |
21858 | } else { | |
21859 | *bp = vqn == __null; | |
21860 | } | |
21861 | if (!*bp) | |
21862 | return (JSIntn)1; | |
21863 | if ((((xml)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) { | |
21864 | if (!EqualStrings(cx, xml->u.value, vxml->u.value, bp)) | |
21865 | return (JSIntn)0; | |
21866 | } else if (xml->u.list.kids.length != vxml->u.list.kids.length) { | |
21867 | *bp = (JSIntn)0; | |
21868 | } else { | |
21869 | { | |
21870 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
21871 | JSXMLArrayCursor vcursor(&vxml->u.list.kids); | |
21872 | for (;;) { | |
21873 | kid = (JSXML *) cursor.getNext(); | |
21874 | vkid = (JSXML *) vcursor.getNext(); | |
21875 | if (!kid || !vkid) { | |
21876 | *bp = !kid && !vkid; | |
21877 | break; | |
21878 | } | |
21879 | xobj = js_GetXMLObject(cx, kid); | |
21880 | vobj = js_GetXMLObject(cx, vkid); | |
21881 | if (!xobj || !vobj || | |
21882 | !js_TestXMLEquality(cx, ObjectValue(*xobj), ObjectValue(*vobj), bp)) | |
21883 | return (JSIntn)0; | |
21884 | if (!*bp) | |
21885 | break; | |
21886 | } | |
21887 | } | |
21888 | if (*bp && xml->xml_class == JSXML_CLASS_ELEMENT) { | |
21889 | n = xml->u.elem.attrs.length; | |
21890 | if (n != vxml->u.elem.attrs.length) | |
21891 | *bp = (JSIntn)0; | |
21892 | for (i = 0; *bp && i < n; i++) { | |
21893 | attr = (((i) < (&xml->u.elem.attrs)->length) ? (JSXML *) (&xml->u.elem.attrs)->vector[i] : __null); | |
21894 | if (!attr) | |
21895 | continue; | |
21896 | j = XMLArrayFindMember(&vxml->u.elem.attrs, (void *)(attr), attr_identity); | |
21897 | if (j == ((uint32) -1)) { | |
21898 | *bp = (JSIntn)0; | |
21899 | break; | |
21900 | } | |
21901 | vattr = (((j) < (&vxml->u.elem.attrs)->length) ? (JSXML *) (&vxml->u.elem.attrs)->vector[j] : __null); | |
21902 | if (!vattr) | |
21903 | continue; | |
21904 | if (!EqualStrings(cx, attr->u.value, vattr->u.value, bp)) | |
21905 | return (JSIntn)0; | |
21906 | } | |
21907 | } | |
21908 | } | |
21909 | return (JSIntn)1; | |
21910 | } | |
21911 | static JSBool | |
21912 | Equals(JSContext *cx, JSXML *xml, jsval v, JSBool *bp) | |
21913 | { | |
21914 | JSObject *vobj; | |
21915 | JSXML *vxml; | |
21916 | if (JSVAL_IS_PRIMITIVE(v)) { | |
21917 | *bp = (JSIntn)0; | |
21918 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
21919 | if (xml->u.list.kids.length == 1) { | |
21920 | vxml = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
21921 | if (!vxml) | |
21922 | return (JSIntn)1; | |
21923 | vobj = js_GetXMLObject(cx, vxml); | |
21924 | if (!vobj) | |
21925 | return (JSIntn)0; | |
21926 | return js_TestXMLEquality(cx, ObjectValue(*vobj), Valueify(v), bp); | |
21927 | } | |
21928 | if (JSVAL_IS_VOID(v) && xml->u.list.kids.length == 0) | |
21929 | *bp = (JSIntn)1; | |
21930 | } | |
21931 | } else { | |
21932 | vobj = JSVAL_TO_OBJECT(v); | |
21933 | if (!vobj->isXML()) { | |
21934 | *bp = (JSIntn)0; | |
21935 | } else { | |
21936 | vxml = (JSXML *) vobj->getPrivate(); | |
21937 | if (!XMLEquals(cx, xml, vxml, bp)) | |
21938 | return (JSIntn)0; | |
21939 | } | |
21940 | } | |
21941 | return (JSIntn)1; | |
21942 | } | |
21943 | static JSBool | |
21944 | CheckCycle(JSContext *cx, JSXML *xml, JSXML *kid) | |
21945 | { | |
21946 | ((void) 0); | |
21947 | do { | |
21948 | if (xml == kid) { | |
21949 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, | |
21950 | JSMSG_CYCLIC_VALUE, js_XML_str); | |
21951 | return (JSIntn)0; | |
21952 | } | |
21953 | } while ((xml = xml->parent) != __null); | |
21954 | return (JSIntn)1; | |
21955 | } | |
21956 | static JSBool | |
21957 | Insert(JSContext *cx, JSXML *xml, uint32 i, jsval v) | |
21958 | { | |
21959 | uint32 j, n; | |
21960 | JSXML *vxml, *kid; | |
21961 | JSObject *vobj; | |
21962 | JSString *str; | |
21963 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE)) | |
21964 | return (JSIntn)1; | |
21965 | n = 1; | |
21966 | vxml = __null; | |
21967 | if (!JSVAL_IS_PRIMITIVE(v)) { | |
21968 | vobj = JSVAL_TO_OBJECT(v); | |
21969 | if (vobj->isXML()) { | |
21970 | vxml = (JSXML *) vobj->getPrivate(); | |
21971 | if (vxml->xml_class == JSXML_CLASS_LIST) { | |
21972 | n = vxml->u.list.kids.length; | |
21973 | if (n == 0) | |
21974 | return (JSIntn)1; | |
21975 | for (j = 0; j < n; j++) { | |
21976 | kid = (((j) < (&vxml->u.list.kids)->length) ? (JSXML *) (&vxml->u.list.kids)->vector[j] : __null); | |
21977 | if (!kid) | |
21978 | continue; | |
21979 | if (!CheckCycle(cx, xml, kid)) | |
21980 | return (JSIntn)0; | |
21981 | } | |
21982 | } else if (vxml->xml_class == JSXML_CLASS_ELEMENT) { | |
21983 | if (!CheckCycle(cx, xml, vxml)) | |
21984 | return (JSIntn)0; | |
21985 | } | |
21986 | } | |
21987 | } | |
21988 | if (!vxml) { | |
21989 | str = js_ValueToString(cx, Valueify(v)); | |
21990 | if (!str) | |
21991 | return (JSIntn)0; | |
21992 | vxml = js_NewXML(cx, JSXML_CLASS_TEXT); | |
21993 | if (!vxml) | |
21994 | return (JSIntn)0; | |
21995 | vxml->u.value = str; | |
21996 | } | |
21997 | if (i > xml->u.list.kids.length) | |
21998 | i = xml->u.list.kids.length; | |
21999 | if (!XMLArrayInsert(cx, &xml->u.list.kids, i, n)) | |
22000 | return (JSIntn)0; | |
22001 | if (vxml->xml_class == JSXML_CLASS_LIST) { | |
22002 | for (j = 0; j < n; j++) { | |
22003 | kid = (((j) < (&vxml->u.list.kids)->length) ? (JSXML *) (&vxml->u.list.kids)->vector[j] : __null); | |
22004 | if (!kid) | |
22005 | continue; | |
22006 | kid->parent = xml; | |
22007 | do { if ((&xml->u.list.kids)->length <= (i + j)) (&xml->u.list.kids)->length = (i + j) + 1; ((&xml->u.list.kids)->vector[i + j] = (void *)(kid)); } while (0); | |
22008 | } | |
22009 | } else { | |
22010 | vxml->parent = xml; | |
22011 | do { if ((&xml->u.list.kids)->length <= (i)) (&xml->u.list.kids)->length = (i) + 1; ((&xml->u.list.kids)->vector[i] = (void *)(vxml)); } while (0); | |
22012 | } | |
22013 | return (JSIntn)1; | |
22014 | } | |
22015 | static JSBool | |
22016 | IndexToId(JSContext *cx, uint32 index, jsid *idp) | |
22017 | { | |
22018 | JSAtom *atom; | |
22019 | JSString *str; | |
22020 | if (index <= ((1 << 30) - 1)) { | |
22021 | *idp = INT_TO_JSID(index); | |
22022 | } else { | |
22023 | str = js_NumberToString(cx, (jsdouble) index); | |
22024 | if (!str) | |
22025 | return (JSIntn)0; | |
22026 | atom = js_AtomizeString(cx, str, 0); | |
22027 | if (!atom) | |
22028 | return (JSIntn)0; | |
22029 | *idp = ATOM_TO_JSID(atom); | |
22030 | } | |
22031 | return (JSIntn)1; | |
22032 | } | |
22033 | static JSBool | |
22034 | Replace(JSContext *cx, JSXML *xml, uint32 i, jsval v) | |
22035 | { | |
22036 | uint32 n; | |
22037 | JSXML *vxml, *kid; | |
22038 | JSObject *vobj; | |
22039 | JSString *str; | |
22040 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE)) | |
22041 | return (JSIntn)1; | |
22042 | n = xml->u.list.kids.length; | |
22043 | if (i > n) | |
22044 | i = n; | |
22045 | vxml = __null; | |
22046 | if (!JSVAL_IS_PRIMITIVE(v)) { | |
22047 | vobj = JSVAL_TO_OBJECT(v); | |
22048 | if (vobj->isXML()) | |
22049 | vxml = (JSXML *) vobj->getPrivate(); | |
22050 | } | |
22051 | switch (vxml ? JSXMLClass(vxml->xml_class) : JSXML_CLASS_LIMIT) { | |
22052 | case JSXML_CLASS_ELEMENT: | |
22053 | if (!CheckCycle(cx, xml, vxml)) | |
22054 | return (JSIntn)0; | |
22055 | case JSXML_CLASS_COMMENT: | |
22056 | case JSXML_CLASS_PROCESSING_INSTRUCTION: | |
22057 | case JSXML_CLASS_TEXT: | |
22058 | goto do_replace; | |
22059 | case JSXML_CLASS_LIST: | |
22060 | if (i < n) | |
22061 | DeleteByIndex(cx, xml, i); | |
22062 | if (!Insert(cx, xml, i, v)) | |
22063 | return (JSIntn)0; | |
22064 | break; | |
22065 | default: | |
22066 | str = js_ValueToString(cx, Valueify(v)); | |
22067 | if (!str) | |
22068 | return (JSIntn)0; | |
22069 | vxml = js_NewXML(cx, JSXML_CLASS_TEXT); | |
22070 | if (!vxml) | |
22071 | return (JSIntn)0; | |
22072 | vxml->u.value = str; | |
22073 | do_replace: | |
22074 | vxml->parent = xml; | |
22075 | if (i < n) { | |
22076 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
22077 | if (kid) | |
22078 | kid->parent = __null; | |
22079 | } | |
22080 | if (!XMLArrayAddMember(cx, &xml->u.list.kids, i, (void *)(vxml))) | |
22081 | return (JSIntn)0; | |
22082 | break; | |
22083 | } | |
22084 | return (JSIntn)1; | |
22085 | } | |
22086 | static void | |
22087 | DeleteNamedProperty(JSContext *cx, JSXML *xml, JSObject *nameqn, | |
22088 | JSBool attributes) | |
22089 | { | |
22090 | JSXMLArray *array; | |
22091 | uint32 index, deleteCount; | |
22092 | JSXML *kid; | |
22093 | JSXMLNameMatcher matcher; | |
22094 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
22095 | array = &xml->u.list.kids; | |
22096 | for (index = 0; index < array->length; index++) { | |
22097 | kid = (((index) < (array)->length) ? (JSXML *) (array)->vector[index] : __null); | |
22098 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) | |
22099 | DeleteNamedProperty(cx, kid, nameqn, attributes); | |
22100 | } | |
22101 | } else if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
22102 | if (attributes) { | |
22103 | array = &xml->u.elem.attrs; | |
22104 | matcher = MatchAttrName; | |
22105 | } else { | |
22106 | array = &xml->u.list.kids; | |
22107 | matcher = MatchElemName; | |
22108 | } | |
22109 | deleteCount = 0; | |
22110 | for (index = 0; index < array->length; index++) { | |
22111 | kid = (((index) < (array)->length) ? (JSXML *) (array)->vector[index] : __null); | |
22112 | if (kid && matcher(nameqn, kid)) { | |
22113 | kid->parent = __null; | |
22114 | XMLArrayDelete(cx, array, index, (JSIntn)0); | |
22115 | ++deleteCount; | |
22116 | } else if (deleteCount != 0) { | |
22117 | do { if ((array)->length <= (index - deleteCount)) (array)->length = (index - deleteCount) + 1; ((array)->vector[index - deleteCount] = (void *)(array->vector[index])); } while (0) | |
22118 | ; | |
22119 | } | |
22120 | } | |
22121 | array->length -= deleteCount; | |
22122 | } | |
22123 | } | |
22124 | static void | |
22125 | DeleteListElement(JSContext *cx, JSXML *xml, uint32 index) | |
22126 | { | |
22127 | JSXML *kid, *parent; | |
22128 | uint32 kidIndex; | |
22129 | ((void) 0); | |
22130 | if (index < xml->u.list.kids.length) { | |
22131 | kid = (((index) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[index] : __null); | |
22132 | if (kid) { | |
22133 | parent = kid->parent; | |
22134 | if (parent) { | |
22135 | ((void) 0); | |
22136 | ((void) 0); | |
22137 | if (kid->xml_class == JSXML_CLASS_ATTRIBUTE) { | |
22138 | DeleteNamedProperty(cx, parent, kid->name, (JSIntn)1); | |
22139 | } else { | |
22140 | kidIndex = XMLArrayFindMember(&parent->u.list.kids, (void *)(kid), __null) | |
22141 | ; | |
22142 | ((void) 0); | |
22143 | DeleteByIndex(cx, parent, kidIndex); | |
22144 | } | |
22145 | } | |
22146 | XMLArrayDelete(cx, &xml->u.list.kids, index, (JSIntn)1); | |
22147 | } | |
22148 | } | |
22149 | } | |
22150 | static JSBool | |
22151 | SyncInScopeNamespaces(JSContext *cx, JSXML *xml) | |
22152 | { | |
22153 | JSXMLArray *nsarray; | |
22154 | uint32 i, n; | |
22155 | JSObject *ns; | |
22156 | nsarray = &xml->u.elem.namespaces; | |
22157 | while ((xml = xml->parent) != __null) { | |
22158 | for (i = 0, n = xml->u.elem.namespaces.length; i < n; i++) { | |
22159 | ns = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
22160 | if (ns && !(XMLArrayFindMember(nsarray, (void *)(ns), namespace_identity) != ((uint32) -1))) { | |
22161 | if (!XMLArrayAddMember(cx, nsarray, (nsarray)->length, (void *)((ns)))) | |
22162 | return (JSIntn)0; | |
22163 | } | |
22164 | } | |
22165 | } | |
22166 | return (JSIntn)1; | |
22167 | } | |
22168 | static JSBool | |
22169 | GetNamedProperty(JSContext *cx, JSXML *xml, JSObject* nameqn, JSXML *list) | |
22170 | { | |
22171 | JSXMLArray *array; | |
22172 | JSXMLNameMatcher matcher; | |
22173 | JSBool attrs; | |
22174 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
22175 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
22176 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
22177 | if (kid->xml_class == JSXML_CLASS_ELEMENT && | |
22178 | !GetNamedProperty(cx, kid, nameqn, list)) { | |
22179 | return (JSIntn)0; | |
22180 | } | |
22181 | } | |
22182 | } else if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
22183 | attrs = (nameqn->getClass() == &js_AttributeNameClass); | |
22184 | if (attrs) { | |
22185 | array = &xml->u.elem.attrs; | |
22186 | matcher = MatchAttrName; | |
22187 | } else { | |
22188 | array = &xml->u.list.kids; | |
22189 | matcher = MatchElemName; | |
22190 | } | |
22191 | JSXMLArrayCursor cursor(array); | |
22192 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
22193 | if (matcher(nameqn, kid)) { | |
22194 | if (!attrs && | |
22195 | kid->xml_class == JSXML_CLASS_ELEMENT && | |
22196 | !SyncInScopeNamespaces(cx, kid)) { | |
22197 | return (JSIntn)0; | |
22198 | } | |
22199 | if (!Append(cx, list, kid)) | |
22200 | return (JSIntn)0; | |
22201 | } | |
22202 | } | |
22203 | } | |
22204 | return (JSIntn)1; | |
22205 | } | |
22206 | static JSBool | |
22207 | GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) | |
22208 | { | |
22209 | JSXML *xml, *list, *kid; | |
22210 | uint32 index; | |
22211 | JSObject *kidobj, *listobj; | |
22212 | JSObject *nameqn; | |
22213 | jsid funid; | |
22214 | xml = (JSXML *) GetInstancePrivate(cx, obj, &js_XMLClass, __null); | |
22215 | if (!xml) | |
22216 | return true; | |
22217 | if (js_IdIsIndex(id, &index)) { | |
22218 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE)) { | |
22219 | *vp = (index == 0) ? OBJECT_TO_JSVAL(obj) : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
22220 | } else { | |
22221 | if (index < xml->u.list.kids.length) { | |
22222 | kid = (((index) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[index] : __null); | |
22223 | if (!kid) { | |
22224 | *vp = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
22225 | return true; | |
22226 | } | |
22227 | kidobj = js_GetXMLObject(cx, kid); | |
22228 | if (!kidobj) | |
22229 | return false; | |
22230 | *vp = OBJECT_TO_JSVAL(kidobj); | |
22231 | } else { | |
22232 | *vp = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
22233 | } | |
22234 | } | |
22235 | return true; | |
22236 | } | |
22237 | nameqn = ToXMLName(cx, IdToJsval(id), &funid); | |
22238 | if (!nameqn) | |
22239 | return false; | |
22240 | if (!JSID_IS_VOID(funid)) | |
22241 | return GetXMLFunction(cx, obj, funid, vp); | |
22242 | jsval roots[2] = { OBJECT_TO_JSVAL(nameqn), ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)) }; | |
22243 | AutoArrayRooter tvr(cx, (sizeof (roots) / sizeof (roots)[0]), Valueify(roots)); | |
22244 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
22245 | if (!listobj) | |
22246 | return false; | |
22247 | roots[1] = OBJECT_TO_JSVAL(listobj); | |
22248 | list = (JSXML *) listobj->getPrivate(); | |
22249 | if (!GetNamedProperty(cx, xml, nameqn, list)) | |
22250 | return false; | |
22251 | list->u.list.target = xml; | |
22252 | list->u.list.targetprop = nameqn; | |
22253 | *vp = OBJECT_TO_JSVAL(listobj); | |
22254 | return true; | |
22255 | } | |
22256 | static JSXML * | |
22257 | CopyOnWrite(JSContext *cx, JSXML *xml, JSObject *obj) | |
22258 | { | |
22259 | ((void) 0); | |
22260 | xml = DeepCopy(cx, xml, obj, 0); | |
22261 | if (!xml) | |
22262 | return __null; | |
22263 | ((void) 0); | |
22264 | return xml; | |
22265 | } | |
22266 | static JSString * | |
22267 | KidToString(JSContext *cx, JSXML *xml, uint32 index) | |
22268 | { | |
22269 | JSXML *kid; | |
22270 | JSObject *kidobj; | |
22271 | kid = (((index) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[index] : __null); | |
22272 | if (!kid) | |
22273 | return cx->runtime->emptyString; | |
22274 | kidobj = js_GetXMLObject(cx, kid); | |
22275 | if (!kidobj) | |
22276 | return __null; | |
22277 | return js_ValueToString(cx, ObjectValue(*kidobj)); | |
22278 | } | |
22279 | static JSBool | |
22280 | ResolveValue(JSContext *cx, JSXML *list, JSXML **result); | |
22281 | static JSBool | |
22282 | PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) | |
22283 | { | |
22284 | JSBool ok, primitiveAssign; | |
22285 | enum { OBJ_ROOT, ID_ROOT, VAL_ROOT }; | |
22286 | JSXML *xml, *vxml, *rxml, *kid, *attr, *parent, *copy, *kid2, *match; | |
22287 | JSObject *vobj, *nameobj, *attrobj, *parentobj, *kidobj, *copyobj; | |
22288 | JSObject *targetprop, *nameqn, *attrqn; | |
22289 | uint32 index, i, j, k, n, q, matchIndex; | |
22290 | jsval attrval, nsval; | |
22291 | jsid funid; | |
22292 | JSObject *ns; | |
22293 | xml = (JSXML *) GetInstancePrivate(cx, obj, &js_XMLClass, __null); | |
22294 | if (!xml) | |
22295 | return (JSIntn)1; | |
22296 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
22297 | if (!xml) | |
22298 | return (JSIntn)0; | |
22299 | vxml = __null; | |
22300 | if (!JSVAL_IS_PRIMITIVE(*vp)) { | |
22301 | vobj = JSVAL_TO_OBJECT(*vp); | |
22302 | if (vobj->isXML()) | |
22303 | vxml = (JSXML *) vobj->getPrivate(); | |
22304 | } | |
22305 | ok = js_EnterLocalRootScope(cx); | |
22306 | if (!ok) | |
22307 | return (JSIntn)0; | |
22308 | ((void) 0); | |
22309 | jsval roots[3]; | |
22310 | roots[OBJ_ROOT] = OBJECT_TO_JSVAL(obj); | |
22311 | roots[ID_ROOT] = IdToJsval(id); | |
22312 | roots[VAL_ROOT] = *vp; | |
22313 | AutoArrayRooter tvr(cx, (sizeof (roots) / sizeof (roots)[0]), Valueify(roots)); | |
22314 | if (js_IdIsIndex(id, &index)) { | |
22315 | if (xml->xml_class != JSXML_CLASS_LIST) { | |
22316 | ReportBadXMLName(cx, IdToValue(id)); | |
22317 | goto bad; | |
22318 | } | |
22319 | i = index; | |
22320 | if (xml->u.list.target) { | |
22321 | ok = ResolveValue(cx, xml->u.list.target, &rxml); | |
22322 | if (!ok) | |
22323 | goto out; | |
22324 | if (!rxml) | |
22325 | goto out; | |
22326 | ((void) 0); | |
22327 | } else { | |
22328 | rxml = __null; | |
22329 | } | |
22330 | if (index >= xml->u.list.kids.length) { | |
22331 | if (rxml) { | |
22332 | if (rxml->xml_class == JSXML_CLASS_LIST) { | |
22333 | if (rxml->u.list.kids.length != 1) | |
22334 | goto out; | |
22335 | rxml = (((0) < (&rxml->u.list.kids)->length) ? (JSXML *) (&rxml->u.list.kids)->vector[0] : __null); | |
22336 | if (!rxml) | |
22337 | goto out; | |
22338 | ok = js_GetXMLObject(cx, rxml) != __null; | |
22339 | if (!ok) | |
22340 | goto out; | |
22341 | } | |
22342 | if (!(((rxml)->xml_class) < JSXML_CLASS_ATTRIBUTE)) | |
22343 | goto out; | |
22344 | } | |
22345 | targetprop = xml->u.list.targetprop; | |
22346 | if (!targetprop || ((targetprop->getQNameLocalName())->length() == 1 && *(targetprop->getQNameLocalName())->chars() == '*')) { | |
22347 | kid = js_NewXML(cx, JSXML_CLASS_TEXT); | |
22348 | if (!kid) | |
22349 | goto bad; | |
22350 | } else { | |
22351 | nameobj = targetprop; | |
22352 | if (nameobj->getClass() == &js_AttributeNameClass) { | |
22353 | ok = GetProperty(cx, rxml->object, id, &attrval); | |
22354 | if (!ok) | |
22355 | goto out; | |
22356 | if (JSVAL_IS_PRIMITIVE(attrval)) | |
22357 | goto out; | |
22358 | attrobj = JSVAL_TO_OBJECT(attrval); | |
22359 | attr = (JSXML *) attrobj->getPrivate(); | |
22360 | if (((((attr)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (attr)->u.list.kids.length : 0) != 0) | |
22361 | goto out; | |
22362 | kid = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE); | |
22363 | } else { | |
22364 | kid = js_NewXML(cx, JSXML_CLASS_ELEMENT); | |
22365 | } | |
22366 | if (!kid) | |
22367 | goto bad; | |
22368 | kid->name = targetprop; | |
22369 | } | |
22370 | kid->parent = rxml; | |
22371 | i = xml->u.list.kids.length; | |
22372 | if (kid->xml_class != JSXML_CLASS_ATTRIBUTE) { | |
22373 | if (rxml) { | |
22374 | ((void) 0); | |
22375 | n = rxml->u.list.kids.length; | |
22376 | j = n - 1; | |
22377 | if (n != 0 && i != 0) { | |
22378 | for (n = j, j = 0; j < n; j++) { | |
22379 | if (rxml->u.list.kids.vector[j] == | |
22380 | xml->u.list.kids.vector[i-1]) { | |
22381 | break; | |
22382 | } | |
22383 | } | |
22384 | } | |
22385 | kidobj = js_GetXMLObject(cx, kid); | |
22386 | if (!kidobj) | |
22387 | goto bad; | |
22388 | ok = Insert(cx, rxml, j + 1, OBJECT_TO_JSVAL(kidobj)); | |
22389 | if (!ok) | |
22390 | goto out; | |
22391 | } | |
22392 | if (vxml) { | |
22393 | kid->name = (vxml->xml_class == JSXML_CLASS_LIST) | |
22394 | ? vxml->u.list.targetprop | |
22395 | : vxml->name; | |
22396 | } | |
22397 | } | |
22398 | ok = Append(cx, xml, kid); | |
22399 | if (!ok) | |
22400 | goto out; | |
22401 | } | |
22402 | if (!vxml || | |
22403 | vxml->xml_class == JSXML_CLASS_TEXT || | |
22404 | vxml->xml_class == JSXML_CLASS_ATTRIBUTE) { | |
22405 | ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp); | |
22406 | if (!ok) | |
22407 | goto out; | |
22408 | roots[VAL_ROOT] = *vp; | |
22409 | } | |
22410 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
22411 | if (!kid) | |
22412 | goto out; | |
22413 | parent = kid->parent; | |
22414 | if (kid->xml_class == JSXML_CLASS_ATTRIBUTE) { | |
22415 | nameobj = kid->name; | |
22416 | if (nameobj->getClass() != &js_AttributeNameClass) { | |
22417 | nameobj = NewXMLAttributeName(cx, nameobj->getNameURI(), nameobj->getNamePrefix(), | |
22418 | nameobj->getQNameLocalName()); | |
22419 | if (!nameobj) | |
22420 | goto bad; | |
22421 | } | |
22422 | id = OBJECT_TO_JSID(nameobj); | |
22423 | if (parent) { | |
22424 | parentobj = js_GetXMLObject(cx, parent); | |
22425 | if (!parentobj) | |
22426 | goto bad; | |
22427 | ok = PutProperty(cx, parentobj, id, strict, vp); | |
22428 | if (!ok) | |
22429 | goto out; | |
22430 | ok = GetProperty(cx, parentobj, id, vp); | |
22431 | if (!ok) | |
22432 | goto out; | |
22433 | attr = (JSXML *) JSVAL_TO_OBJECT(*vp)->getPrivate(); | |
22434 | if (attr->u.list.kids.length != 0) | |
22435 | xml->u.list.kids.vector[i] = attr->u.list.kids.vector[0]; | |
22436 | } | |
22437 | } | |
22438 | else if (vxml && vxml->xml_class == JSXML_CLASS_LIST) { | |
22439 | copy = DeepCopyInLRS(cx, vxml, 0); | |
22440 | if (!copy) | |
22441 | goto bad; | |
22442 | copyobj = js_GetXMLObject(cx, copy); | |
22443 | if (!copyobj) | |
22444 | goto bad; | |
22445 | ((void) 0); | |
22446 | if (parent) { | |
22447 | q = XMLArrayFindMember(&parent->u.list.kids, (void *)(kid), __null); | |
22448 | ((void) 0); | |
22449 | ok = Replace(cx, parent, q, OBJECT_TO_JSVAL(copyobj)); | |
22450 | if (!ok) | |
22451 | goto out; | |
22452 | } | |
22453 | n = copy->u.list.kids.length; | |
22454 | if (n == 0) { | |
22455 | XMLArrayDelete(cx, &xml->u.list.kids, i, (JSIntn)1); | |
22456 | } else { | |
22457 | ok = XMLArrayInsert(cx, &xml->u.list.kids, i + 1, n - 1); | |
22458 | if (!ok) | |
22459 | goto out; | |
22460 | for (j = 0; j < n; j++) | |
22461 | xml->u.list.kids.vector[i + j] = copy->u.list.kids.vector[j]; | |
22462 | } | |
22463 | } | |
22464 | else if (vxml || (((kid)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) { | |
22465 | if (parent) { | |
22466 | q = XMLArrayFindMember(&parent->u.list.kids, (void *)(kid), __null); | |
22467 | ((void) 0); | |
22468 | ok = Replace(cx, parent, q, *vp); | |
22469 | if (!ok) | |
22470 | goto out; | |
22471 | vxml = (((q) < (&parent->u.list.kids)->length) ? (JSXML *) (&parent->u.list.kids)->vector[q] : __null); | |
22472 | if (!vxml) | |
22473 | goto out; | |
22474 | roots[VAL_ROOT] = *vp = OBJECT_TO_JSVAL(vxml->object); | |
22475 | } | |
22476 | if (!vxml) { | |
22477 | ((void) 0); | |
22478 | vobj = ToXML(cx, *vp); | |
22479 | if (!vobj) | |
22480 | goto bad; | |
22481 | roots[VAL_ROOT] = *vp = OBJECT_TO_JSVAL(vobj); | |
22482 | vxml = (JSXML *) vobj->getPrivate(); | |
22483 | } | |
22484 | do { if ((&xml->u.list.kids)->length <= (i)) (&xml->u.list.kids)->length = (i) + 1; ((&xml->u.list.kids)->vector[i] = (void *)(vxml)); } while (0); | |
22485 | } | |
22486 | else { | |
22487 | kidobj = js_GetXMLObject(cx, kid); | |
22488 | if (!kidobj) | |
22489 | goto bad; | |
22490 | id = ATOM_TO_JSID(cx->runtime->atomState.starAtom); | |
22491 | ok = PutProperty(cx, kidobj, id, strict, vp); | |
22492 | if (!ok) | |
22493 | goto out; | |
22494 | } | |
22495 | } else { | |
22496 | nameqn = ToXMLName(cx, IdToJsval(id), &funid); | |
22497 | if (!nameqn) | |
22498 | goto bad; | |
22499 | if (!JSID_IS_VOID(funid)) { | |
22500 | ok = js_SetProperty(cx, obj, funid, Valueify(vp), false); | |
22501 | goto out; | |
22502 | } | |
22503 | nameobj = nameqn; | |
22504 | roots[ID_ROOT] = OBJECT_TO_JSVAL(nameobj); | |
22505 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
22506 | n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
22507 | if (n > 1) | |
22508 | goto type_error; | |
22509 | if (n == 0) { | |
22510 | ok = ResolveValue(cx, xml, &rxml); | |
22511 | if (!ok) | |
22512 | goto out; | |
22513 | if (!rxml || ((((rxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (rxml)->u.list.kids.length : 0) != 1) | |
22514 | goto type_error; | |
22515 | ok = Append(cx, xml, rxml); | |
22516 | if (!ok) | |
22517 | goto out; | |
22518 | } | |
22519 | ((void) 0); | |
22520 | xml = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
22521 | if (!xml) | |
22522 | goto out; | |
22523 | ((void) 0); | |
22524 | obj = js_GetXMLObject(cx, xml); | |
22525 | if (!obj) | |
22526 | goto bad; | |
22527 | roots[OBJ_ROOT] = OBJECT_TO_JSVAL(obj); | |
22528 | } | |
22529 | if ((((xml)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) | |
22530 | goto out; | |
22531 | if (!vxml || | |
22532 | vxml->xml_class == JSXML_CLASS_TEXT || | |
22533 | vxml->xml_class == JSXML_CLASS_ATTRIBUTE) { | |
22534 | ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp); | |
22535 | if (!ok) | |
22536 | goto out; | |
22537 | } else { | |
22538 | rxml = DeepCopyInLRS(cx, vxml, 0); | |
22539 | if (!rxml || !js_GetXMLObject(cx, rxml)) | |
22540 | goto bad; | |
22541 | vxml = rxml; | |
22542 | *vp = OBJECT_TO_JSVAL(vxml->object); | |
22543 | } | |
22544 | roots[VAL_ROOT] = *vp; | |
22545 | ok = js_GetDefaultXMLNamespace(cx, &nsval); | |
22546 | if (!ok) | |
22547 | goto out; | |
22548 | if (nameobj->getClass() == &js_AttributeNameClass) { | |
22549 | if (!js_IsXMLName(cx, OBJECT_TO_JSVAL(nameobj))) | |
22550 | goto out; | |
22551 | if (vxml && vxml->xml_class == JSXML_CLASS_LIST) { | |
22552 | n = vxml->u.list.kids.length; | |
22553 | if (n == 0) { | |
22554 | *vp = STRING_TO_JSVAL(cx->runtime->emptyString); | |
22555 | } else { | |
22556 | JSString *left = KidToString(cx, vxml, 0); | |
22557 | if (!left) | |
22558 | goto bad; | |
22559 | JSString *space = cx->runtime->atomState.spaceAtom; | |
22560 | for (i = 1; i < n; i++) { | |
22561 | left = js_ConcatStrings(cx, left, space); | |
22562 | if (!left) | |
22563 | goto bad; | |
22564 | JSString *right = KidToString(cx, vxml, i); | |
22565 | if (!right) | |
22566 | goto bad; | |
22567 | left = js_ConcatStrings(cx, left, right); | |
22568 | if (!left) | |
22569 | goto bad; | |
22570 | } | |
22571 | roots[VAL_ROOT] = *vp = STRING_TO_JSVAL(left); | |
22572 | } | |
22573 | } else { | |
22574 | ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp); | |
22575 | if (!ok) | |
22576 | goto out; | |
22577 | roots[VAL_ROOT] = *vp; | |
22578 | } | |
22579 | match = __null; | |
22580 | for (i = 0, n = xml->u.elem.attrs.length; i < n; i++) { | |
22581 | attr = (((i) < (&xml->u.elem.attrs)->length) ? (JSXML *) (&xml->u.elem.attrs)->vector[i] : __null); | |
22582 | if (!attr) | |
22583 | continue; | |
22584 | attrqn = attr->name; | |
22585 | if (EqualStrings(attrqn->getQNameLocalName(), nameqn->getQNameLocalName())) { | |
22586 | JSLinearString *uri = nameqn->getNameURI(); | |
22587 | if (!uri || EqualStrings(attrqn->getNameURI(), uri)) { | |
22588 | if (!match) { | |
22589 | match = attr; | |
22590 | } else { | |
22591 | DeleteNamedProperty(cx, xml, attrqn, (JSIntn)1); | |
22592 | --i; | |
22593 | } | |
22594 | } | |
22595 | } | |
22596 | } | |
22597 | attr = match; | |
22598 | if (!attr) { | |
22599 | JSLinearString *uri = nameqn->getNameURI(); | |
22600 | JSLinearString *left, *right; | |
22601 | if (!uri) { | |
22602 | left = right = cx->runtime->emptyString; | |
22603 | } else { | |
22604 | left = uri; | |
22605 | right = nameqn->getNamePrefix(); | |
22606 | } | |
22607 | nameqn = NewXMLQName(cx, left, right, nameqn->getQNameLocalName()); | |
22608 | if (!nameqn) | |
22609 | goto bad; | |
22610 | attr = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE); | |
22611 | if (!attr) | |
22612 | goto bad; | |
22613 | attr->parent = xml; | |
22614 | attr->name = nameqn; | |
22615 | ok = XMLArrayAddMember(cx, &xml->u.elem.attrs, n, (void *)(attr)); | |
22616 | if (!ok) | |
22617 | goto out; | |
22618 | ns = GetNamespace(cx, nameqn, __null); | |
22619 | if (!ns) | |
22620 | goto bad; | |
22621 | ok = AddInScopeNamespace(cx, xml, ns); | |
22622 | if (!ok) | |
22623 | goto out; | |
22624 | } | |
22625 | attr->u.value = JSVAL_TO_STRING(*vp); | |
22626 | goto out; | |
22627 | } | |
22628 | if (!js_IsXMLName(cx, OBJECT_TO_JSVAL(nameobj)) && | |
22629 | !((nameqn->getQNameLocalName())->length() == 1 && *(nameqn->getQNameLocalName())->chars() == '*')) { | |
22630 | goto out; | |
22631 | } | |
22632 | id = ((jsid)0x2); | |
22633 | primitiveAssign = !vxml && !((nameqn->getQNameLocalName())->length() == 1 && *(nameqn->getQNameLocalName())->chars() == '*'); | |
22634 | k = n = xml->u.list.kids.length; | |
22635 | matchIndex = ((uint32) -1); | |
22636 | kid2 = __null; | |
22637 | while (k != 0) { | |
22638 | --k; | |
22639 | kid = (((k) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[k] : __null); | |
22640 | if (kid && MatchElemName(nameqn, kid)) { | |
22641 | if (matchIndex != ((uint32) -1)) | |
22642 | DeleteByIndex(cx, xml, matchIndex); | |
22643 | matchIndex = k; | |
22644 | kid2 = kid; | |
22645 | } | |
22646 | } | |
22647 | if (kid2) { | |
22648 | ((void) 0); | |
22649 | if (!kid2->parent) | |
22650 | kid2->parent = xml; | |
22651 | } | |
22652 | if (matchIndex == ((uint32) -1)) { | |
22653 | matchIndex = n; | |
22654 | if (primitiveAssign) { | |
22655 | JSLinearString *uri = nameqn->getNameURI(); | |
22656 | JSLinearString *left, *right; | |
22657 | if (!uri) { | |
22658 | ns = JSVAL_TO_OBJECT(nsval); | |
22659 | left = ns->getNameURI(); | |
22660 | right = ns->getNamePrefix(); | |
22661 | } else { | |
22662 | left = uri; | |
22663 | right = nameqn->getNamePrefix(); | |
22664 | } | |
22665 | nameqn = NewXMLQName(cx, left, right, nameqn->getQNameLocalName()); | |
22666 | if (!nameqn) | |
22667 | goto bad; | |
22668 | vobj = js_NewXMLObject(cx, JSXML_CLASS_ELEMENT); | |
22669 | if (!vobj) | |
22670 | goto bad; | |
22671 | vxml = (JSXML *) vobj->getPrivate(); | |
22672 | vxml->parent = xml; | |
22673 | vxml->name = nameqn; | |
22674 | ns = GetNamespace(cx, nameqn, __null); | |
22675 | if (!ns) | |
22676 | goto bad; | |
22677 | ok = Replace(cx, xml, matchIndex, OBJECT_TO_JSVAL(vobj)); | |
22678 | if (!ok) | |
22679 | goto out; | |
22680 | ok = AddInScopeNamespace(cx, vxml, ns); | |
22681 | if (!ok) | |
22682 | goto out; | |
22683 | } | |
22684 | } | |
22685 | if (primitiveAssign) { | |
22686 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
22687 | cursor.index = matchIndex; | |
22688 | kid = (JSXML *) cursor.getCurrent(); | |
22689 | if ((((kid)->xml_class) < JSXML_CLASS_ATTRIBUTE)) { | |
22690 | kid->u.list.kids.finish(cx); | |
22691 | kid->u.list.kids.init(); | |
22692 | ok = kid->u.list.kids.setCapacity(cx, 1); | |
22693 | } | |
22694 | if (ok) { | |
22695 | ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp); | |
22696 | if (ok && !JSVAL_TO_STRING(*vp)->empty()) { | |
22697 | roots[VAL_ROOT] = *vp; | |
22698 | if ((JSXML *) cursor.getCurrent() == kid) | |
22699 | ok = Replace(cx, kid, 0, *vp); | |
22700 | } | |
22701 | } | |
22702 | } else { | |
22703 | ok = Replace(cx, xml, matchIndex, *vp); | |
22704 | } | |
22705 | } | |
22706 | out: | |
22707 | js_LeaveLocalRootScope(cx); | |
22708 | return ok; | |
22709 | type_error: | |
22710 | { | |
22711 | JSAutoByteString bytes; | |
22712 | if (js_ValueToPrintable(cx, IdToValue(id), &bytes)) | |
22713 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_BAD_XMLLIST_PUT, bytes.ptr()); | |
22714 | } | |
22715 | bad: | |
22716 | ok = (JSIntn)0; | |
22717 | goto out; | |
22718 | } | |
22719 | static JSBool | |
22720 | ResolveValue(JSContext *cx, JSXML *list, JSXML **result) | |
22721 | { | |
22722 | JSXML *target, *base; | |
22723 | JSObject *targetprop; | |
22724 | jsid id; | |
22725 | jsval tv; | |
22726 | if (list->xml_class != JSXML_CLASS_LIST || list->u.list.kids.length != 0) { | |
22727 | if (!js_GetXMLObject(cx, list)) | |
22728 | return (JSIntn)0; | |
22729 | *result = list; | |
22730 | return (JSIntn)1; | |
22731 | } | |
22732 | target = list->u.list.target; | |
22733 | targetprop = list->u.list.targetprop; | |
22734 | if (!target || !targetprop || ((targetprop->getQNameLocalName())->length() == 1 && *(targetprop->getQNameLocalName())->chars() == '*')) { | |
22735 | *result = __null; | |
22736 | return (JSIntn)1; | |
22737 | } | |
22738 | if (targetprop->getClass() == &js_AttributeNameClass) { | |
22739 | *result = __null; | |
22740 | return (JSIntn)1; | |
22741 | } | |
22742 | if (!ResolveValue(cx, target, &base)) | |
22743 | return (JSIntn)0; | |
22744 | if (!base) { | |
22745 | *result = __null; | |
22746 | return (JSIntn)1; | |
22747 | } | |
22748 | if (!js_GetXMLObject(cx, base)) | |
22749 | return (JSIntn)0; | |
22750 | id = OBJECT_TO_JSID(targetprop); | |
22751 | if (!GetProperty(cx, base->object, id, &tv)) | |
22752 | return (JSIntn)0; | |
22753 | target = (JSXML *) JSVAL_TO_OBJECT(tv)->getPrivate(); | |
22754 | if (((((target)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (target)->u.list.kids.length : 0) == 0) { | |
22755 | if (base->xml_class == JSXML_CLASS_LIST && ((((base)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (base)->u.list.kids.length : 0) > 1) { | |
22756 | *result = __null; | |
22757 | return (JSIntn)1; | |
22758 | } | |
22759 | tv = STRING_TO_JSVAL(cx->runtime->emptyString); | |
22760 | if (!PutProperty(cx, base->object, id, false, &tv)) | |
22761 | return (JSIntn)0; | |
22762 | if (!GetProperty(cx, base->object, id, &tv)) | |
22763 | return (JSIntn)0; | |
22764 | target = (JSXML *) JSVAL_TO_OBJECT(tv)->getPrivate(); | |
22765 | } | |
22766 | *result = target; | |
22767 | return (JSIntn)1; | |
22768 | } | |
22769 | static JSBool | |
22770 | HasNamedProperty(JSXML *xml, JSObject *nameqn) | |
22771 | { | |
22772 | JSBool found; | |
22773 | JSXMLArray *array; | |
22774 | JSXMLNameMatcher matcher; | |
22775 | uint32 i, n; | |
22776 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
22777 | found = (JSIntn)0; | |
22778 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
22779 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
22780 | found = HasNamedProperty(kid, nameqn); | |
22781 | if (found) | |
22782 | break; | |
22783 | } | |
22784 | return found; | |
22785 | } | |
22786 | if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
22787 | if (nameqn->getClass() == &js_AttributeNameClass) { | |
22788 | array = &xml->u.elem.attrs; | |
22789 | matcher = MatchAttrName; | |
22790 | } else { | |
22791 | array = &xml->u.list.kids; | |
22792 | matcher = MatchElemName; | |
22793 | } | |
22794 | for (i = 0, n = array->length; i < n; i++) { | |
22795 | JSXML *kid = (((i) < (array)->length) ? (JSXML *) (array)->vector[i] : __null); | |
22796 | if (kid && matcher(nameqn, kid)) | |
22797 | return (JSIntn)1; | |
22798 | } | |
22799 | } | |
22800 | return (JSIntn)0; | |
22801 | } | |
22802 | static JSBool | |
22803 | HasIndexedProperty(JSXML *xml, uint32 i) | |
22804 | { | |
22805 | if (xml->xml_class == JSXML_CLASS_LIST) | |
22806 | return i < ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
22807 | if (xml->xml_class == JSXML_CLASS_ELEMENT) | |
22808 | return i == 0; | |
22809 | return (JSIntn)0; | |
22810 | } | |
22811 | static JSBool | |
22812 | HasSimpleContent(JSXML *xml); | |
22813 | static JSBool | |
22814 | HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid, JSBool *found) | |
22815 | { | |
22816 | JSObject *pobj; | |
22817 | JSProperty *prop; | |
22818 | JSXML *xml; | |
22819 | ((void) 0); | |
22820 | if (!js_LookupProperty(cx, obj, funid, &pobj, &prop)) | |
22821 | return false; | |
22822 | if (!prop) { | |
22823 | xml = (JSXML *) obj->getPrivate(); | |
22824 | if (HasSimpleContent(xml)) { | |
22825 | AutoObjectRooter tvr(cx); | |
22826 | if (!js_GetClassPrototype(cx, __null, JSProto_String, tvr.addr())) | |
22827 | return false; | |
22828 | ((void) 0); | |
22829 | if (!js_LookupProperty(cx, tvr.object(), funid, &pobj, &prop)) | |
22830 | return false; | |
22831 | } | |
22832 | } | |
22833 | *found = (prop != __null); | |
22834 | return true; | |
22835 | } | |
22836 | static JSBool | |
22837 | HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found) | |
22838 | { | |
22839 | JSXML *xml; | |
22840 | bool isIndex; | |
22841 | uint32 i; | |
22842 | JSObject *qn; | |
22843 | jsid funid; | |
22844 | xml = (JSXML *) obj->getPrivate(); | |
22845 | if (!js_IdValIsIndex(cx, id, &i, &isIndex)) | |
22846 | return (JSIntn)0; | |
22847 | if (isIndex) { | |
22848 | *found = HasIndexedProperty(xml, i); | |
22849 | } else { | |
22850 | qn = ToXMLName(cx, id, &funid); | |
22851 | if (!qn) | |
22852 | return (JSIntn)0; | |
22853 | if (!JSID_IS_VOID(funid)) { | |
22854 | if (!HasFunctionProperty(cx, obj, funid, found)) | |
22855 | return (JSIntn)0; | |
22856 | } else { | |
22857 | *found = HasNamedProperty(xml, qn); | |
22858 | } | |
22859 | } | |
22860 | return (JSIntn)1; | |
22861 | } | |
22862 | static void | |
22863 | xml_finalize(JSContext *cx, JSObject *obj) | |
22864 | { | |
22865 | JSXML *xml = (JSXML *) obj->getPrivate(); | |
22866 | if (!xml) | |
22867 | return; | |
22868 | if (xml->object == obj) | |
22869 | xml->object = __null; | |
22870 | } | |
22871 | static void | |
22872 | xml_trace_vector(JSTracer *trc, JSXML **vec, uint32 len) | |
22873 | { | |
22874 | uint32 i; | |
22875 | JSXML *xml; | |
22876 | for (i = 0; i < len; i++) { | |
22877 | xml = vec[i]; | |
22878 | if (xml) { | |
22879 | do { } while (0); | |
22880 | Mark(trc, xml); | |
22881 | } | |
22882 | } | |
22883 | } | |
22884 | static JSBool | |
22885 | xml_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |
22886 | JSProperty **propp) | |
22887 | { | |
22888 | JSBool found; | |
22889 | JSXML *xml; | |
22890 | uint32 i; | |
22891 | JSObject *qn; | |
22892 | jsid funid; | |
22893 | xml = (JSXML *) obj->getPrivate(); | |
22894 | if (js_IdIsIndex(id, &i)) { | |
22895 | found = HasIndexedProperty(xml, i); | |
22896 | } else { | |
22897 | qn = ToXMLName(cx, IdToJsval(id), &funid); | |
22898 | if (!qn) | |
22899 | return (JSIntn)0; | |
22900 | if (!JSID_IS_VOID(funid)) | |
22901 | return js_LookupProperty(cx, obj, funid, objp, propp); | |
22902 | found = HasNamedProperty(xml, qn); | |
22903 | } | |
22904 | if (!found) { | |
22905 | *objp = __null; | |
22906 | *propp = __null; | |
22907 | } else { | |
22908 | const Shape *shape = | |
22909 | js_AddNativeProperty(cx, obj, id, | |
22910 | Valueify(GetProperty), Valueify(PutProperty), | |
22911 | 0xffffffff, 0x01, | |
22912 | 0, 0); | |
22913 | if (!shape) | |
22914 | return (JSIntn)0; | |
22915 | *objp = obj; | |
22916 | *propp = (JSProperty *) shape; | |
22917 | } | |
22918 | return (JSIntn)1; | |
22919 | } | |
22920 | static JSBool | |
22921 | xml_defineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *v, | |
22922 | PropertyOp getter, StrictPropertyOp setter, uintN attrs) | |
22923 | { | |
22924 | if (IsFunctionObject(*v) || getter || setter || | |
22925 | (attrs & 0x01) == 0 || | |
22926 | (attrs & (0x02 | 0x04 | 0x40))) { | |
22927 | return js_DefineProperty(cx, obj, id, v, getter, setter, attrs); | |
22928 | } | |
22929 | jsval tmp = Jsvalify(*v); | |
22930 | return PutProperty(cx, obj, id, false, &tmp); | |
22931 | } | |
22932 | static JSBool | |
22933 | xml_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp) | |
22934 | { | |
22935 | if (JSID_IS_DEFAULT_XML_NAMESPACE(id)) { | |
22936 | vp->setUndefined(); | |
22937 | return (JSIntn)1; | |
22938 | } | |
22939 | return GetProperty(cx, obj, id, Jsvalify(vp)); | |
22940 | } | |
22941 | static JSBool | |
22942 | xml_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict) | |
22943 | { | |
22944 | return PutProperty(cx, obj, id, strict, Jsvalify(vp)); | |
22945 | } | |
22946 | static JSBool | |
22947 | xml_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp) | |
22948 | { | |
22949 | JSBool found; | |
22950 | if (!HasProperty(cx, obj, IdToJsval(id), &found)) | |
22951 | return false; | |
22952 | *attrsp = found ? 0x01 : 0; | |
22953 | return (JSIntn)1; | |
22954 | } | |
22955 | static JSBool | |
22956 | xml_setAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp) | |
22957 | { | |
22958 | JSBool found; | |
22959 | if (!HasProperty(cx, obj, IdToJsval(id), &found)) | |
22960 | return false; | |
22961 | if (found) { | |
22962 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, | |
22963 | JSMSG_CANT_SET_XML_ATTRS); | |
22964 | return false; | |
22965 | } | |
22966 | return true; | |
22967 | } | |
22968 | static JSBool | |
22969 | xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict) | |
22970 | { | |
22971 | JSXML *xml; | |
22972 | jsval idval; | |
22973 | uint32 index; | |
22974 | JSObject *nameqn; | |
22975 | jsid funid; | |
22976 | idval = IdToJsval(id); | |
22977 | xml = (JSXML *) obj->getPrivate(); | |
22978 | if (js_IdIsIndex(id, &index)) { | |
22979 | if (xml->xml_class != JSXML_CLASS_LIST) { | |
22980 | ReportBadXMLName(cx, IdToValue(id)); | |
22981 | return false; | |
22982 | } | |
22983 | DeleteListElement(cx, xml, index); | |
22984 | } else { | |
22985 | nameqn = ToXMLName(cx, idval, &funid); | |
22986 | if (!nameqn) | |
22987 | return false; | |
22988 | if (!JSID_IS_VOID(funid)) | |
22989 | return js_DeleteProperty(cx, obj, funid, rval, false); | |
22990 | DeleteNamedProperty(cx, xml, nameqn, | |
22991 | nameqn->getClass() == &js_AttributeNameClass); | |
22992 | } | |
22993 | if (!obj->nativeEmpty() && !js_DeleteProperty(cx, obj, id, rval, false)) | |
22994 | return false; | |
22995 | rval->setBoolean(true); | |
22996 | return true; | |
22997 | } | |
22998 | JSBool | |
22999 | xml_convert(JSContext *cx, JSObject *obj, JSType type, Value *rval) | |
23000 | { | |
23001 | return js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, __null, rval); | |
23002 | } | |
23003 | static JSBool | |
23004 | xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep, jsid *idp) | |
23005 | { | |
23006 | JSXML *xml; | |
23007 | uint32 length, index; | |
23008 | JSXMLArrayCursor *cursor; | |
23009 | xml = (JSXML *)obj->getPrivate(); | |
23010 | length = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); | |
23011 | switch (enum_op) { | |
23012 | case JSENUMERATE_INIT: | |
23013 | case JSENUMERATE_INIT_ALL: | |
23014 | if (length == 0) { | |
23015 | statep->setInt32(0); | |
23016 | } else { | |
23017 | cursor = cx->create<JSXMLArrayCursor>(&xml->u.list.kids); | |
23018 | if (!cursor) | |
23019 | return (JSIntn)0; | |
23020 | statep->setPrivate(cursor); | |
23021 | } | |
23022 | if (idp) | |
23023 | *idp = INT_TO_JSID(length); | |
23024 | break; | |
23025 | case JSENUMERATE_NEXT: | |
23026 | if (statep->isInt32(0)) { | |
23027 | statep->setNull(); | |
23028 | break; | |
23029 | } | |
23030 | cursor = (JSXMLArrayCursor *) statep->toPrivate(); | |
23031 | if (cursor && cursor->array && (index = cursor->index) < length) { | |
23032 | *idp = INT_TO_JSID(index); | |
23033 | cursor->index = index + 1; | |
23034 | break; | |
23035 | } | |
23036 | case JSENUMERATE_DESTROY: | |
23037 | if (!statep->isInt32(0)) { | |
23038 | cursor = (JSXMLArrayCursor *) statep->toPrivate(); | |
23039 | if (cursor) | |
23040 | cx->destroy(cursor); | |
23041 | } | |
23042 | statep->setNull(); | |
23043 | break; | |
23044 | } | |
23045 | return (JSIntn)1; | |
23046 | } | |
23047 | static JSType | |
23048 | xml_typeOf(JSContext *cx, JSObject *obj) | |
23049 | { | |
23050 | return JSTYPE_XML; | |
23051 | } | |
23052 | static JSBool | |
23053 | xml_hasInstance(JSContext *cx, JSObject *obj, const Value *, JSBool *bp) | |
23054 | { | |
23055 | return (JSIntn)1; | |
23056 | } | |
23057 | static void | |
23058 | xml_trace(JSTracer *trc, JSObject *obj) | |
23059 | { | |
23060 | JSXML *xml = (JSXML *) obj->getPrivate(); | |
23061 | if (xml) | |
23062 | do { do { } while (0); JS_CallTracer((trc), (xml), (2)); } while (0); | |
23063 | } | |
23064 | static JSBool | |
23065 | xml_fix(JSContext *cx, JSObject *obj, bool *success, AutoIdVector *props) | |
23066 | { | |
23067 | ((void) 0); | |
23068 | *success = false; | |
23069 | return true; | |
23070 | } | |
23071 | static void | |
23072 | xml_clear(JSContext *cx, JSObject *obj) | |
23073 | { | |
23074 | } | |
23075 | static JSBool | |
23076 | HasSimpleContent(JSXML *xml) | |
23077 | { | |
23078 | JSXML *kid; | |
23079 | JSBool simple; | |
23080 | uint32 i, n; | |
23081 | again: | |
23082 | switch (xml->xml_class) { | |
23083 | case JSXML_CLASS_COMMENT: | |
23084 | case JSXML_CLASS_PROCESSING_INSTRUCTION: | |
23085 | return (JSIntn)0; | |
23086 | case JSXML_CLASS_LIST: | |
23087 | if (xml->u.list.kids.length == 0) | |
23088 | return (JSIntn)1; | |
23089 | if (xml->u.list.kids.length == 1) { | |
23090 | kid = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
23091 | if (kid) { | |
23092 | xml = kid; | |
23093 | goto again; | |
23094 | } | |
23095 | } | |
23096 | default: | |
23097 | simple = (JSIntn)1; | |
23098 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
23099 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
23100 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
23101 | simple = (JSIntn)0; | |
23102 | break; | |
23103 | } | |
23104 | } | |
23105 | return simple; | |
23106 | } | |
23107 | } | |
23108 | JSBool | |
23109 | js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp) | |
23110 | { | |
23111 | ((void) 0); | |
23112 | if (JSID_IS_OBJECT(id)) { | |
23113 | jsid funid; | |
23114 | if (!js_IsFunctionQName(cx, JSID_TO_OBJECT(id), &funid)) | |
23115 | return (JSIntn)0; | |
23116 | if (!JSID_IS_VOID(funid)) | |
23117 | id = funid; | |
23118 | } | |
23119 | AutoValueRooter tvr(cx); | |
23120 | JSBool ok = GetXMLFunction(cx, obj, id, Jsvalify(tvr.addr())); | |
23121 | *vp = tvr.value(); | |
23122 | return ok; | |
23123 | } | |
23124 | JSBool | |
23125 | js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp) | |
23126 | { | |
23127 | JSXML *xml, *vxml; | |
23128 | JSObject *vobj; | |
23129 | JSBool ok; | |
23130 | JSString *str, *vstr; | |
23131 | jsdouble d, d2; | |
23132 | JSObject *obj; | |
23133 | jsval v; | |
23134 | if (v1.isObject() && v1.toObject().isXML()) { | |
23135 | obj = &v1.toObject(); | |
23136 | v = Jsvalify(v2); | |
23137 | } else { | |
23138 | v = Jsvalify(v1); | |
23139 | obj = &v2.toObject(); | |
23140 | } | |
23141 | ((void) 0); | |
23142 | xml = (JSXML *) obj->getPrivate(); | |
23143 | vxml = __null; | |
23144 | if (!JSVAL_IS_PRIMITIVE(v)) { | |
23145 | vobj = JSVAL_TO_OBJECT(v); | |
23146 | if (vobj->isXML()) | |
23147 | vxml = (JSXML *) vobj->getPrivate(); | |
23148 | } | |
23149 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
23150 | ok = Equals(cx, xml, v, bp); | |
23151 | } else if (vxml) { | |
23152 | if (vxml->xml_class == JSXML_CLASS_LIST) { | |
23153 | ok = Equals(cx, vxml, OBJECT_TO_JSVAL(obj), bp); | |
23154 | } else { | |
23155 | if (((xml->xml_class == JSXML_CLASS_TEXT || | |
23156 | xml->xml_class == JSXML_CLASS_ATTRIBUTE) && | |
23157 | HasSimpleContent(vxml)) || | |
23158 | ((vxml->xml_class == JSXML_CLASS_TEXT || | |
23159 | vxml->xml_class == JSXML_CLASS_ATTRIBUTE) && | |
23160 | HasSimpleContent(xml))) { | |
23161 | ok = js_EnterLocalRootScope(cx); | |
23162 | if (ok) { | |
23163 | ok = (str = js_ValueToString(cx, ObjectValue(*obj))) && | |
23164 | (vstr = js_ValueToString(cx, Valueify(v))); | |
23165 | if (ok) | |
23166 | ok = EqualStrings(cx, str, vstr, bp); | |
23167 | js_LeaveLocalRootScope(cx); | |
23168 | } | |
23169 | } else { | |
23170 | ok = XMLEquals(cx, xml, vxml, bp); | |
23171 | } | |
23172 | } | |
23173 | } else { | |
23174 | ok = js_EnterLocalRootScope(cx); | |
23175 | if (ok) { | |
23176 | if (HasSimpleContent(xml)) { | |
23177 | ok = (str = js_ValueToString(cx, ObjectValue(*obj))) && | |
23178 | (vstr = js_ValueToString(cx, Valueify(v))); | |
23179 | if (ok) | |
23180 | ok = EqualStrings(cx, str, vstr, bp); | |
23181 | } else if (JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v)) { | |
23182 | str = js_ValueToString(cx, ObjectValue(*obj)); | |
23183 | if (!str) { | |
23184 | ok = (JSIntn)0; | |
23185 | } else if (JSVAL_IS_STRING(v)) { | |
23186 | ok = EqualStrings(cx, str, JSVAL_TO_STRING(v), bp); | |
23187 | } else { | |
23188 | ok = JS_ValueToNumber(cx, STRING_TO_JSVAL(str), &d); | |
23189 | if (ok) { | |
23190 | d2 = JSVAL_IS_INT(v) ? JSVAL_TO_INT(v) | |
23191 | : JSVAL_TO_DOUBLE(v); | |
23192 | *bp = ((d) == (d2)); | |
23193 | } | |
23194 | } | |
23195 | } else { | |
23196 | *bp = (JSIntn)0; | |
23197 | } | |
23198 | js_LeaveLocalRootScope(cx); | |
23199 | } | |
23200 | } | |
23201 | return ok; | |
23202 | } | |
23203 | JSBool | |
23204 | js_ConcatenateXML(JSContext *cx, JSObject *obj, JSObject *robj, Value *vp) | |
23205 | { | |
23206 | JSBool ok; | |
23207 | JSObject *listobj; | |
23208 | JSXML *list, *lxml, *rxml; | |
23209 | ((void) 0); | |
23210 | ok = js_EnterLocalRootScope(cx); | |
23211 | if (!ok) | |
23212 | return (JSIntn)0; | |
23213 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
23214 | if (!listobj) { | |
23215 | ok = (JSIntn)0; | |
23216 | goto out; | |
23217 | } | |
23218 | list = (JSXML *) listobj->getPrivate(); | |
23219 | lxml = (JSXML *) obj->getPrivate(); | |
23220 | ok = Append(cx, list, lxml); | |
23221 | if (!ok) | |
23222 | goto out; | |
23223 | ((void) 0); | |
23224 | rxml = (JSXML *) robj->getPrivate(); | |
23225 | ok = Append(cx, list, rxml); | |
23226 | if (!ok) | |
23227 | goto out; | |
23228 | vp->setObject(*listobj); | |
23229 | out: | |
23230 | js_LeaveLocalRootScopeWithResult(cx, *vp); | |
23231 | return ok; | |
23232 | } | |
23233 | __attribute__((visibility ("default"))) Class js_XMLClass = { | |
23234 | js_XML_str, | |
23235 | (1<<0) | (1<<((8 + 8)+3)) | | |
23236 | ((JSProto_XML) << ((8 + 8) + 8)), | |
23237 | PropertyStub, | |
23238 | PropertyStub, | |
23239 | PropertyStub, | |
23240 | StrictPropertyStub, | |
23241 | EnumerateStub, | |
23242 | ResolveStub, | |
23243 | xml_convert, | |
23244 | xml_finalize, | |
23245 | __null, | |
23246 | __null, | |
23247 | __null, | |
23248 | __null, | |
23249 | __null, | |
23250 | xml_hasInstance, | |
23251 | ((JSMarkOp)(xml_trace)), | |
23252 | {__null,__null,__null,__null,__null}, | |
23253 | { | |
23254 | xml_lookupProperty, | |
23255 | xml_defineProperty, | |
23256 | xml_getProperty, | |
23257 | xml_setProperty, | |
23258 | xml_getAttributes, | |
23259 | xml_setAttributes, | |
23260 | xml_deleteProperty, | |
23261 | xml_enumerate, | |
23262 | xml_typeOf, | |
23263 | __null, | |
23264 | xml_fix, | |
23265 | __null, | |
23266 | xml_clear | |
23267 | } | |
23268 | }; | |
23269 | static JSXML * | |
23270 | StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp) | |
23271 | { | |
23272 | JSXML *xml; | |
23273 | JSFunction *fun; | |
23274 | char numBuf[12]; | |
23275 | ((void) 0); | |
23276 | *objp = ToObject(cx, Valueify(&vp[1])); | |
23277 | if (!*objp) | |
23278 | return __null; | |
23279 | xml = (JSXML *) GetInstancePrivate(cx, *objp, &js_XMLClass, Valueify(vp + 2)); | |
23280 | if (!xml || xml->xml_class != JSXML_CLASS_LIST) | |
23281 | return xml; | |
23282 | if (xml->u.list.kids.length == 1) { | |
23283 | xml = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
23284 | if (xml) { | |
23285 | *objp = js_GetXMLObject(cx, xml); | |
23286 | if (!*objp) | |
23287 | return __null; | |
23288 | vp[1] = OBJECT_TO_JSVAL(*objp); | |
23289 | return xml; | |
23290 | } | |
23291 | } | |
23292 | fun = (((void) 0), (JSFunction *) (JSVAL_TO_OBJECT(*vp))->getPrivate()); | |
23293 | JS_snprintf(numBuf, sizeof numBuf, "%u", xml->u.list.kids.length); | |
23294 | JSAutoByteString funNameBytes; | |
23295 | if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) { | |
23296 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, JSMSG_NON_LIST_XML_METHOD, | |
23297 | funName, numBuf); | |
23298 | } | |
23299 | return __null; | |
23300 | } | |
23301 | static JSBool | |
23302 | xml_addNamespace(JSContext *cx, uintN argc, jsval *vp) | |
23303 | { | |
23304 | JSObject *ns; | |
23305 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23306 | if (xml->xml_class != JSXML_CLASS_ELEMENT) | |
23307 | goto done; | |
23308 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
23309 | if (!xml) | |
23310 | return (JSIntn)0; | |
23311 | if (!NamespaceHelper(cx, __null, argc == 0 ? -1 : 1, vp + 2, vp)) | |
23312 | return (JSIntn)0; | |
23313 | ((void) 0); | |
23314 | ns = JSVAL_TO_OBJECT(*vp); | |
23315 | if (!AddInScopeNamespace(cx, xml, ns)) | |
23316 | return (JSIntn)0; | |
23317 | ns->setNamespaceDeclared(((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1))); | |
23318 | done: | |
23319 | *vp = OBJECT_TO_JSVAL(obj); | |
23320 | return (JSIntn)1; | |
23321 | } | |
23322 | static JSBool | |
23323 | xml_appendChild(JSContext *cx, uintN argc, jsval *vp) | |
23324 | { | |
23325 | jsval v; | |
23326 | JSObject *vobj; | |
23327 | JSXML *vxml; | |
23328 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23329 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
23330 | if (!xml) | |
23331 | return (JSIntn)0; | |
23332 | jsid name; | |
23333 | if (!js_GetAnyName(cx, &name)) | |
23334 | return (JSIntn)0; | |
23335 | if (!GetProperty(cx, obj, name, &v)) | |
23336 | return (JSIntn)0; | |
23337 | ((void) 0); | |
23338 | vobj = JSVAL_TO_OBJECT(v); | |
23339 | ((void) 0); | |
23340 | vxml = (JSXML *) vobj->getPrivate(); | |
23341 | ((void) 0); | |
23342 | if (!IndexToId(cx, vxml->u.list.kids.length, &name)) | |
23343 | return (JSIntn)0; | |
23344 | *vp = (argc != 0) ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23345 | if (!PutProperty(cx, JSVAL_TO_OBJECT(v), name, false, vp)) | |
23346 | return (JSIntn)0; | |
23347 | *vp = OBJECT_TO_JSVAL(obj); | |
23348 | return (JSIntn)1; | |
23349 | } | |
23350 | static JSBool | |
23351 | xml_attribute(JSContext *cx, uintN argc, jsval *vp) | |
23352 | { | |
23353 | JSObject *qn; | |
23354 | if (argc == 0) { | |
23355 | js_ReportMissingArg(cx, Valueify(*vp), 0); | |
23356 | return (JSIntn)0; | |
23357 | } | |
23358 | qn = ToAttributeName(cx, vp[2]); | |
23359 | if (!qn) | |
23360 | return (JSIntn)0; | |
23361 | vp[2] = OBJECT_TO_JSVAL(qn); | |
23362 | jsid id = OBJECT_TO_JSID(qn); | |
23363 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
23364 | if (!obj) | |
23365 | return (JSIntn)0; | |
23366 | return GetProperty(cx, obj, id, vp); | |
23367 | } | |
23368 | static JSBool | |
23369 | xml_attributes(JSContext *cx, uintN argc, jsval *vp) | |
23370 | { | |
23371 | jsval name = STRING_TO_JSVAL((cx->runtime->atomState.starAtom)); | |
23372 | JSObject *qn = ToAttributeName(cx, name); | |
23373 | if (!qn) | |
23374 | return (JSIntn)0; | |
23375 | AutoObjectRooter tvr(cx, qn); | |
23376 | jsid id = OBJECT_TO_JSID(qn); | |
23377 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
23378 | if (!obj) | |
23379 | return (JSIntn)0; | |
23380 | return GetProperty(cx, obj, id, vp); | |
23381 | } | |
23382 | static JSXML * | |
23383 | xml_list_helper(JSContext *cx, JSXML *xml, jsval *rval) | |
23384 | { | |
23385 | JSObject *listobj; | |
23386 | JSXML *list; | |
23387 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
23388 | if (!listobj) | |
23389 | return __null; | |
23390 | *rval = OBJECT_TO_JSVAL(listobj); | |
23391 | list = (JSXML *) listobj->getPrivate(); | |
23392 | list->u.list.target = xml; | |
23393 | return list; | |
23394 | } | |
23395 | static JSBool | |
23396 | ValueToId(JSContext *cx, jsval v, AutoIdRooter *idr) | |
23397 | { | |
23398 | if (JSVAL_IS_INT(v)) { | |
23399 | jsint i = JSVAL_TO_INT(v); | |
23400 | if (INT_FITS_IN_JSID(i)) | |
23401 | *idr->addr() = INT_TO_JSID(i); | |
23402 | else if (!js_ValueToStringId(cx, Valueify(v), idr->addr())) | |
23403 | return (JSIntn)0; | |
23404 | } else if (JSVAL_IS_STRING(v)) { | |
23405 | JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v), 0); | |
23406 | if (!atom) | |
23407 | return (JSIntn)0; | |
23408 | *idr->addr() = ATOM_TO_JSID(atom); | |
23409 | } else if (!JSVAL_IS_PRIMITIVE(v)) { | |
23410 | *idr->addr() = OBJECT_TO_JSID(JSVAL_TO_OBJECT(v)); | |
23411 | } else { | |
23412 | ReportBadXMLName(cx, Valueify(v)); | |
23413 | return (JSIntn)0; | |
23414 | } | |
23415 | return (JSIntn)1; | |
23416 | } | |
23417 | static JSBool | |
23418 | xml_child_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval name, | |
23419 | jsval *rval) | |
23420 | { | |
23421 | bool isIndex; | |
23422 | uint32 index; | |
23423 | JSXML *kid; | |
23424 | JSObject *kidobj; | |
23425 | ((void) 0); | |
23426 | if (!js_IdValIsIndex(cx, name, &index, &isIndex)) | |
23427 | return (JSIntn)0; | |
23428 | if (isIndex) { | |
23429 | if (index >= ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0)) { | |
23430 | *rval = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23431 | } else { | |
23432 | kid = (((index) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[index] : __null); | |
23433 | if (!kid) { | |
23434 | *rval = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23435 | } else { | |
23436 | kidobj = js_GetXMLObject(cx, kid); | |
23437 | if (!kidobj) | |
23438 | return (JSIntn)0; | |
23439 | *rval = OBJECT_TO_JSVAL(kidobj); | |
23440 | } | |
23441 | } | |
23442 | return (JSIntn)1; | |
23443 | } | |
23444 | AutoIdRooter idr(cx); | |
23445 | if (!ValueToId(cx, name, &idr)) | |
23446 | return (JSIntn)0; | |
23447 | return GetProperty(cx, obj, idr.id(), rval); | |
23448 | } | |
23449 | static JSBool | |
23450 | xml_child(JSContext *cx, uintN argc, jsval *vp) | |
23451 | { | |
23452 | jsval v; | |
23453 | JSXML *list, *vxml; | |
23454 | JSObject *kidobj; | |
23455 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23456 | jsval name = argc != 0 ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23457 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
23458 | list = xml_list_helper(cx, xml, vp); | |
23459 | if (!list) | |
23460 | return (JSIntn)0; | |
23461 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
23462 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
23463 | kidobj = js_GetXMLObject(cx, kid); | |
23464 | if (!kidobj) | |
23465 | return (JSIntn)0; | |
23466 | if (!xml_child_helper(cx, kidobj, kid, name, &v)) | |
23467 | return (JSIntn)0; | |
23468 | if (JSVAL_IS_VOID(v)) { | |
23469 | continue; | |
23470 | } | |
23471 | ((void) 0); | |
23472 | vxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); | |
23473 | if ((!(((vxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) || vxml->u.list.kids.length != 0) && | |
23474 | !Append(cx, list, vxml)) { | |
23475 | return (JSIntn)0; | |
23476 | } | |
23477 | } | |
23478 | return (JSIntn)1; | |
23479 | } | |
23480 | if (!xml_child_helper(cx, obj, xml, name, vp)) | |
23481 | return (JSIntn)0; | |
23482 | if (JSVAL_IS_VOID(*vp) && !xml_list_helper(cx, xml, vp)) | |
23483 | return (JSIntn)0; | |
23484 | return (JSIntn)1; | |
23485 | } | |
23486 | static JSBool | |
23487 | xml_childIndex(JSContext *cx, uintN argc, jsval *vp) | |
23488 | { | |
23489 | JSXML *parent; | |
23490 | uint32 i, n; | |
23491 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23492 | parent = xml->parent; | |
23493 | if (!parent || xml->xml_class == JSXML_CLASS_ATTRIBUTE) { | |
23494 | *vp = DOUBLE_TO_JSVAL(js_NaN); | |
23495 | return (JSIntn)1; | |
23496 | } | |
23497 | for (i = 0, n = ((((parent)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (parent)->u.list.kids.length : 0); i < n; i++) { | |
23498 | if ((((i) < (&parent->u.list.kids)->length) ? (JSXML *) (&parent->u.list.kids)->vector[i] : __null) == xml) | |
23499 | break; | |
23500 | } | |
23501 | ((void) 0); | |
23502 | if (i <= ((jsint)0x7fffffff)) | |
23503 | *vp = INT_TO_JSVAL(i); | |
23504 | else | |
23505 | *vp = DOUBLE_TO_JSVAL(i); | |
23506 | return (JSIntn)1; | |
23507 | } | |
23508 | static JSBool | |
23509 | xml_children(JSContext *cx, uintN argc, jsval *vp) | |
23510 | { | |
23511 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
23512 | if (!obj) | |
23513 | return false; | |
23514 | jsid name = ATOM_TO_JSID(cx->runtime->atomState.starAtom); | |
23515 | return GetProperty(cx, obj, name, vp); | |
23516 | } | |
23517 | static JSBool | |
23518 | xml_comments_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval *vp) | |
23519 | { | |
23520 | JSXML *list, *kid, *vxml; | |
23521 | JSBool ok; | |
23522 | uint32 i, n; | |
23523 | JSObject *kidobj; | |
23524 | jsval v; | |
23525 | list = xml_list_helper(cx, xml, vp); | |
23526 | if (!list) | |
23527 | return (JSIntn)0; | |
23528 | ok = (JSIntn)1; | |
23529 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
23530 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
23531 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
23532 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
23533 | ok = js_EnterLocalRootScope(cx); | |
23534 | if (!ok) | |
23535 | break; | |
23536 | kidobj = js_GetXMLObject(cx, kid); | |
23537 | if (kidobj) { | |
23538 | ok = xml_comments_helper(cx, kidobj, kid, &v); | |
23539 | } else { | |
23540 | ok = (JSIntn)0; | |
23541 | v = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
23542 | } | |
23543 | js_LeaveLocalRootScopeWithResult(cx, Valueify(v)); | |
23544 | if (!ok) | |
23545 | break; | |
23546 | vxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); | |
23547 | if (((((vxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (vxml)->u.list.kids.length : 0) != 0) { | |
23548 | ok = Append(cx, list, vxml); | |
23549 | if (!ok) | |
23550 | break; | |
23551 | } | |
23552 | } | |
23553 | } | |
23554 | } else { | |
23555 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
23556 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
23557 | if (kid && kid->xml_class == JSXML_CLASS_COMMENT) { | |
23558 | ok = Append(cx, list, kid); | |
23559 | if (!ok) | |
23560 | break; | |
23561 | } | |
23562 | } | |
23563 | } | |
23564 | return ok; | |
23565 | } | |
23566 | static JSBool | |
23567 | xml_comments(JSContext *cx, uintN argc, jsval *vp) | |
23568 | { | |
23569 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23570 | return xml_comments_helper(cx, obj, xml, vp); | |
23571 | } | |
23572 | static JSBool | |
23573 | xml_contains(JSContext *cx, uintN argc, jsval *vp) | |
23574 | { | |
23575 | jsval value; | |
23576 | JSBool eq; | |
23577 | JSObject *kidobj; | |
23578 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23579 | value = argc != 0 ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23580 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
23581 | eq = (JSIntn)0; | |
23582 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
23583 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
23584 | kidobj = js_GetXMLObject(cx, kid); | |
23585 | if (!kidobj || !js_TestXMLEquality(cx, ObjectValue(*kidobj), Valueify(value), &eq)) | |
23586 | return (JSIntn)0; | |
23587 | if (eq) | |
23588 | break; | |
23589 | } | |
23590 | } else { | |
23591 | if (!js_TestXMLEquality(cx, ObjectValue(*obj), Valueify(value), &eq)) | |
23592 | return (JSIntn)0; | |
23593 | } | |
23594 | *vp = BOOLEAN_TO_JSVAL(eq); | |
23595 | return (JSIntn)1; | |
23596 | } | |
23597 | static JSBool | |
23598 | xml_copy(JSContext *cx, uintN argc, jsval *vp) | |
23599 | { | |
23600 | JSXML *copy; | |
23601 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23602 | copy = DeepCopy(cx, xml, __null, 0); | |
23603 | if (!copy) | |
23604 | return (JSIntn)0; | |
23605 | *vp = OBJECT_TO_JSVAL(copy->object); | |
23606 | return (JSIntn)1; | |
23607 | } | |
23608 | static JSBool | |
23609 | xml_descendants(JSContext *cx, uintN argc, jsval *vp) | |
23610 | { | |
23611 | jsval name; | |
23612 | JSXML *list; | |
23613 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23614 | name = argc == 0 ? STRING_TO_JSVAL((cx->runtime->atomState.starAtom)) : vp[2]; | |
23615 | list = Descendants(cx, xml, name); | |
23616 | if (!list) | |
23617 | return (JSIntn)0; | |
23618 | *vp = OBJECT_TO_JSVAL(list->object); | |
23619 | return (JSIntn)1; | |
23620 | } | |
23621 | static JSBool | |
23622 | xml_elements_helper(JSContext *cx, JSObject *obj, JSXML *xml, | |
23623 | JSObject *nameqn, jsval *vp) | |
23624 | { | |
23625 | JSXML *list, *vxml; | |
23626 | jsval v; | |
23627 | JSBool ok; | |
23628 | JSObject *kidobj; | |
23629 | uint32 i, n; | |
23630 | list = xml_list_helper(cx, xml, vp); | |
23631 | if (!list) | |
23632 | return (JSIntn)0; | |
23633 | list->u.list.targetprop = nameqn; | |
23634 | ok = (JSIntn)1; | |
23635 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
23636 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
23637 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
23638 | if (kid->xml_class == JSXML_CLASS_ELEMENT) { | |
23639 | ok = js_EnterLocalRootScope(cx); | |
23640 | if (!ok) | |
23641 | break; | |
23642 | kidobj = js_GetXMLObject(cx, kid); | |
23643 | if (kidobj) { | |
23644 | ok = xml_elements_helper(cx, kidobj, kid, nameqn, &v); | |
23645 | } else { | |
23646 | ok = (JSIntn)0; | |
23647 | v = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
23648 | } | |
23649 | js_LeaveLocalRootScopeWithResult(cx, Valueify(v)); | |
23650 | if (!ok) | |
23651 | break; | |
23652 | vxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); | |
23653 | if (((((vxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (vxml)->u.list.kids.length : 0) != 0) { | |
23654 | ok = Append(cx, list, vxml); | |
23655 | if (!ok) | |
23656 | break; | |
23657 | } | |
23658 | } | |
23659 | } | |
23660 | } else { | |
23661 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
23662 | JSXML *kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
23663 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT && | |
23664 | MatchElemName(nameqn, kid)) { | |
23665 | ok = Append(cx, list, kid); | |
23666 | if (!ok) | |
23667 | break; | |
23668 | } | |
23669 | } | |
23670 | } | |
23671 | return ok; | |
23672 | } | |
23673 | static JSBool | |
23674 | xml_elements(JSContext *cx, uintN argc, jsval *vp) | |
23675 | { | |
23676 | jsval name; | |
23677 | JSObject *nameqn; | |
23678 | jsid funid; | |
23679 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23680 | name = (argc == 0) ? STRING_TO_JSVAL((cx->runtime->atomState.starAtom)) : vp[2]; | |
23681 | nameqn = ToXMLName(cx, name, &funid); | |
23682 | if (!nameqn) | |
23683 | return (JSIntn)0; | |
23684 | if (!JSID_IS_VOID(funid)) | |
23685 | return xml_list_helper(cx, xml, vp) != __null; | |
23686 | return xml_elements_helper(cx, obj, xml, nameqn, vp); | |
23687 | } | |
23688 | static JSBool | |
23689 | xml_hasOwnProperty(JSContext *cx, uintN argc, jsval *vp) | |
23690 | { | |
23691 | jsval name; | |
23692 | JSBool found; | |
23693 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
23694 | if (!obj) | |
23695 | return (JSIntn)0; | |
23696 | if (!InstanceOf(cx, obj, &js_XMLClass, Valueify(vp + 2))) | |
23697 | return (JSIntn)0; | |
23698 | name = argc != 0 ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
23699 | if (!HasProperty(cx, obj, name, &found)) | |
23700 | return (JSIntn)0; | |
23701 | if (found) { | |
23702 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1)); | |
23703 | return (JSIntn)1; | |
23704 | } | |
23705 | return js_HasOwnPropertyHelper(cx, js_LookupProperty, argc, Valueify(vp)); | |
23706 | } | |
23707 | static JSBool | |
23708 | xml_hasComplexContent(JSContext *cx, uintN argc, jsval *vp) | |
23709 | { | |
23710 | JSXML *kid; | |
23711 | JSObject *kidobj; | |
23712 | uint32 i, n; | |
23713 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23714 | again: | |
23715 | switch (xml->xml_class) { | |
23716 | case JSXML_CLASS_ATTRIBUTE: | |
23717 | case JSXML_CLASS_COMMENT: | |
23718 | case JSXML_CLASS_PROCESSING_INSTRUCTION: | |
23719 | case JSXML_CLASS_TEXT: | |
23720 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)0)); | |
23721 | break; | |
23722 | case JSXML_CLASS_LIST: | |
23723 | if (xml->u.list.kids.length == 0) { | |
23724 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1)); | |
23725 | } else if (xml->u.list.kids.length == 1) { | |
23726 | kid = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
23727 | if (kid) { | |
23728 | kidobj = js_GetXMLObject(cx, kid); | |
23729 | if (!kidobj) | |
23730 | return (JSIntn)0; | |
23731 | obj = kidobj; | |
23732 | xml = (JSXML *) obj->getPrivate(); | |
23733 | goto again; | |
23734 | } | |
23735 | } | |
23736 | default: | |
23737 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)0)); | |
23738 | for (i = 0, n = xml->u.list.kids.length; i < n; i++) { | |
23739 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
23740 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
23741 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1)); | |
23742 | break; | |
23743 | } | |
23744 | } | |
23745 | break; | |
23746 | } | |
23747 | return (JSIntn)1; | |
23748 | } | |
23749 | static JSBool | |
23750 | xml_hasSimpleContent(JSContext *cx, uintN argc, jsval *vp) | |
23751 | { | |
23752 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23753 | *vp = BOOLEAN_TO_JSVAL(HasSimpleContent(xml)); | |
23754 | return (JSIntn)1; | |
23755 | } | |
23756 | static JSBool | |
23757 | FindInScopeNamespaces(JSContext *cx, JSXML *xml, JSXMLArray *nsarray) | |
23758 | { | |
23759 | uint32 length, i, j, n; | |
23760 | JSObject *ns, *ns2; | |
23761 | JSLinearString *prefix, *prefix2; | |
23762 | length = nsarray->length; | |
23763 | do { | |
23764 | if (xml->xml_class != JSXML_CLASS_ELEMENT) | |
23765 | continue; | |
23766 | for (i = 0, n = xml->u.elem.namespaces.length; i < n; i++) { | |
23767 | ns = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
23768 | if (!ns) | |
23769 | continue; | |
23770 | prefix = ns->getNamePrefix(); | |
23771 | for (j = 0; j < length; j++) { | |
23772 | ns2 = (((j) < (nsarray)->length) ? (JSObject *) (nsarray)->vector[j] : __null); | |
23773 | if (ns2) { | |
23774 | prefix2 = ns2->getNamePrefix(); | |
23775 | if ((prefix2 && prefix) | |
23776 | ? EqualStrings(prefix2, prefix) | |
23777 | : EqualStrings(ns2->getNameURI(), ns->getNameURI())) { | |
23778 | break; | |
23779 | } | |
23780 | } | |
23781 | } | |
23782 | if (j == length) { | |
23783 | if (!XMLArrayAddMember(cx, nsarray, (nsarray)->length, (void *)((ns)))) | |
23784 | return (JSIntn)0; | |
23785 | ++length; | |
23786 | } | |
23787 | } | |
23788 | } while ((xml = xml->parent) != __null); | |
23789 | ((void) 0); | |
23790 | return (JSIntn)1; | |
23791 | } | |
23792 | static | |
23793 | bool | |
23794 | NamespacesToJSArray(JSContext *cx, JSXMLArray *array, jsval *rval) | |
23795 | { | |
23796 | JSObject *arrayobj = NewDenseEmptyArray(cx); | |
23797 | if (!arrayobj) | |
23798 | return false; | |
23799 | *rval = OBJECT_TO_JSVAL(arrayobj); | |
23800 | AutoValueRooter tvr(cx); | |
23801 | for (uint32 i = 0, n = array->length; i < n; i++) { | |
23802 | JSObject *ns = (((i) < (array)->length) ? (JSObject *) (array)->vector[i] : __null); | |
23803 | if (!ns) | |
23804 | continue; | |
23805 | tvr.set(ObjectValue(*ns)); | |
23806 | if (!arrayobj->setProperty(cx, INT_TO_JSID(i), tvr.addr(), false)) | |
23807 | return false; | |
23808 | } | |
23809 | return true; | |
23810 | } | |
23811 | static JSBool | |
23812 | xml_inScopeNamespaces(JSContext *cx, uintN argc, jsval *vp) | |
23813 | { | |
23814 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23815 | AutoNamespaceArray namespaces(cx); | |
23816 | return FindInScopeNamespaces(cx, xml, &namespaces.array) && | |
23817 | NamespacesToJSArray(cx, &namespaces.array, vp); | |
23818 | } | |
23819 | static JSBool | |
23820 | xml_insertChildAfter(JSContext *cx, uintN argc, jsval *vp) | |
23821 | { | |
23822 | jsval arg; | |
23823 | JSXML *kid; | |
23824 | uint32 i; | |
23825 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23826 | *vp = OBJECT_TO_JSVAL(obj); | |
23827 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) || argc == 0) | |
23828 | return (JSIntn)1; | |
23829 | arg = vp[2]; | |
23830 | if (JSVAL_IS_NULL(arg)) { | |
23831 | kid = __null; | |
23832 | i = 0; | |
23833 | } else { | |
23834 | if (!(!JSVAL_IS_PRIMITIVE(arg) && JSVAL_TO_OBJECT(arg)->isXML())) | |
23835 | return (JSIntn)1; | |
23836 | kid = (JSXML *) JSVAL_TO_OBJECT(arg)->getPrivate(); | |
23837 | i = XMLArrayFindMember(&xml->u.list.kids, (void *)(kid), __null); | |
23838 | if (i == ((uint32) -1)) | |
23839 | return (JSIntn)1; | |
23840 | ++i; | |
23841 | } | |
23842 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
23843 | if (!xml) | |
23844 | return (JSIntn)0; | |
23845 | return Insert(cx, xml, i, argc >= 2 ? vp[3] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0))); | |
23846 | } | |
23847 | static JSBool | |
23848 | xml_insertChildBefore(JSContext *cx, uintN argc, jsval *vp) | |
23849 | { | |
23850 | jsval arg; | |
23851 | JSXML *kid; | |
23852 | uint32 i; | |
23853 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23854 | *vp = OBJECT_TO_JSVAL(obj); | |
23855 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) || argc == 0) | |
23856 | return (JSIntn)1; | |
23857 | arg = vp[2]; | |
23858 | if (JSVAL_IS_NULL(arg)) { | |
23859 | kid = __null; | |
23860 | i = xml->u.list.kids.length; | |
23861 | } else { | |
23862 | if (!(!JSVAL_IS_PRIMITIVE(arg) && JSVAL_TO_OBJECT(arg)->isXML())) | |
23863 | return (JSIntn)1; | |
23864 | kid = (JSXML *) JSVAL_TO_OBJECT(arg)->getPrivate(); | |
23865 | i = XMLArrayFindMember(&xml->u.list.kids, (void *)(kid), __null); | |
23866 | if (i == ((uint32) -1)) | |
23867 | return (JSIntn)1; | |
23868 | } | |
23869 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
23870 | if (!xml) | |
23871 | return (JSIntn)0; | |
23872 | return Insert(cx, xml, i, argc >= 2 ? vp[3] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0))); | |
23873 | } | |
23874 | static JSBool | |
23875 | xml_length(JSContext *cx, uintN argc, jsval *vp) | |
23876 | { | |
23877 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
23878 | if (xml->xml_class != JSXML_CLASS_LIST) { | |
23879 | *vp = ((((uint64)(uint32)(JSVAL_TAG_INT32)) << 47) | (1)); | |
23880 | } else { | |
23881 | uint32 l = xml->u.list.kids.length; | |
23882 | if (l <= ((jsint)0x7fffffff)) | |
23883 | *vp = INT_TO_JSVAL(l); | |
23884 | else | |
23885 | *vp = DOUBLE_TO_JSVAL(l); | |
23886 | } | |
23887 | return (JSIntn)1; | |
23888 | } | |
23889 | static JSBool | |
23890 | xml_localName(JSContext *cx, uintN argc, jsval *vp) | |
23891 | { | |
23892 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23893 | *vp = xml->name ? xml->name->getQNameLocalNameVal() : ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
23894 | return (JSIntn)1; | |
23895 | } | |
23896 | static JSBool | |
23897 | xml_name(JSContext *cx, uintN argc, jsval *vp) | |
23898 | { | |
23899 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23900 | *vp = OBJECT_TO_JSVAL(xml->name); | |
23901 | return (JSIntn)1; | |
23902 | } | |
23903 | static JSBool | |
23904 | xml_namespace(JSContext *cx, uintN argc, jsval *vp) | |
23905 | { | |
23906 | JSLinearString *prefix, *nsprefix; | |
23907 | jsuint i, length; | |
23908 | JSObject *ns; | |
23909 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23910 | if (argc == 0 && !((uintN)(((xml)->xml_class) - JSXML_CLASS_ELEMENT) <= (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT))) { | |
23911 | *vp = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
23912 | return true; | |
23913 | } | |
23914 | if (argc == 0) { | |
23915 | prefix = __null; | |
23916 | } else { | |
23917 | JSString *str = js_ValueToString(cx, Valueify(vp[2])); | |
23918 | if (!str) | |
23919 | return false; | |
23920 | prefix = str->ensureLinear(cx); | |
23921 | if (!prefix) | |
23922 | return false; | |
23923 | vp[2] = STRING_TO_JSVAL(prefix); | |
23924 | } | |
23925 | AutoNamespaceArray inScopeNSes(cx); | |
23926 | if (!FindInScopeNamespaces(cx, xml, &inScopeNSes.array)) | |
23927 | return false; | |
23928 | if (!prefix) { | |
23929 | ns = GetNamespace(cx, xml->name, &inScopeNSes.array); | |
23930 | if (!ns) | |
23931 | return false; | |
23932 | } else { | |
23933 | ns = __null; | |
23934 | for (i = 0, length = inScopeNSes.array.length; i < length; i++) { | |
23935 | ns = (((i) < (&inScopeNSes.array)->length) ? (JSObject *) (&inScopeNSes.array)->vector[i] : __null); | |
23936 | if (ns) { | |
23937 | nsprefix = ns->getNamePrefix(); | |
23938 | if (nsprefix && EqualStrings(nsprefix, prefix)) | |
23939 | break; | |
23940 | ns = __null; | |
23941 | } | |
23942 | } | |
23943 | } | |
23944 | *vp = (!ns) ? ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)) : OBJECT_TO_JSVAL(ns); | |
23945 | return true; | |
23946 | } | |
23947 | static JSBool | |
23948 | xml_namespaceDeclarations(JSContext *cx, uintN argc, jsval *vp) | |
23949 | { | |
23950 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23951 | if ((((xml)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) | |
23952 | return true; | |
23953 | AutoNamespaceArray ancestors(cx); | |
23954 | AutoNamespaceArray declared(cx); | |
23955 | JSXML *yml = xml; | |
23956 | while ((yml = yml->parent) != __null) { | |
23957 | ((void) 0); | |
23958 | for (uint32 i = 0, n = yml->u.elem.namespaces.length; i < n; i++) { | |
23959 | JSObject *ns = (((i) < (&yml->u.elem.namespaces)->length) ? (JSObject *) (&yml->u.elem.namespaces)->vector[i] : __null); | |
23960 | if (ns && !(XMLArrayFindMember(&ancestors.array, (void *)(ns), namespace_match) != ((uint32) -1))) { | |
23961 | if (!XMLArrayAddMember(cx, &ancestors.array, (&ancestors.array)->length, (void *)((ns)))) | |
23962 | return false; | |
23963 | } | |
23964 | } | |
23965 | } | |
23966 | for (uint32 i = 0, n = xml->u.elem.namespaces.length; i < n; i++) { | |
23967 | JSObject *ns = (((i) < (&xml->u.elem.namespaces)->length) ? (JSObject *) (&xml->u.elem.namespaces)->vector[i] : __null); | |
23968 | if (!ns) | |
23969 | continue; | |
23970 | if (!IsDeclared(ns)) | |
23971 | continue; | |
23972 | if (!(XMLArrayFindMember(&ancestors.array, (void *)(ns), namespace_match) != ((uint32) -1))) { | |
23973 | if (!XMLArrayAddMember(cx, &declared.array, (&declared.array)->length, (void *)((ns)))) | |
23974 | return false; | |
23975 | } | |
23976 | } | |
23977 | return NamespacesToJSArray(cx, &declared.array, vp); | |
23978 | } | |
23979 | static const char js_attribute_str[] = "attribute"; | |
23980 | static const char js_text_str[] = "text"; | |
23981 | const char *js_xml_class_str[] = { | |
23982 | "list", | |
23983 | "element", | |
23984 | js_attribute_str, | |
23985 | "processing-instruction", | |
23986 | js_text_str, | |
23987 | "comment" | |
23988 | }; | |
23989 | static JSBool | |
23990 | xml_nodeKind(JSContext *cx, uintN argc, jsval *vp) | |
23991 | { | |
23992 | JSString *str; | |
23993 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
23994 | str = JS_InternString(cx, js_xml_class_str[xml->xml_class]); | |
23995 | if (!str) | |
23996 | return (JSIntn)0; | |
23997 | *vp = STRING_TO_JSVAL(str); | |
23998 | return (JSIntn)1; | |
23999 | } | |
24000 | static void | |
24001 | NormalizingDelete(JSContext *cx, JSXML *xml, uint32 index) | |
24002 | { | |
24003 | if (xml->xml_class == JSXML_CLASS_LIST) | |
24004 | DeleteListElement(cx, xml, index); | |
24005 | else | |
24006 | DeleteByIndex(cx, xml, index); | |
24007 | } | |
24008 | static JSBool | |
24009 | xml_normalize_helper(JSContext *cx, JSObject *obj, JSXML *xml) | |
24010 | { | |
24011 | JSXML *kid, *kid2; | |
24012 | uint32 i, n; | |
24013 | JSObject *kidobj; | |
24014 | JSString *str; | |
24015 | if (!(((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE)) | |
24016 | return (JSIntn)1; | |
24017 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24018 | if (!xml) | |
24019 | return (JSIntn)0; | |
24020 | for (i = 0, n = xml->u.list.kids.length; i < n; i++) { | |
24021 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24022 | if (!kid) | |
24023 | continue; | |
24024 | if (kid->xml_class == JSXML_CLASS_ELEMENT) { | |
24025 | kidobj = js_GetXMLObject(cx, kid); | |
24026 | if (!kidobj || !xml_normalize_helper(cx, kidobj, kid)) | |
24027 | return (JSIntn)0; | |
24028 | } else if (kid->xml_class == JSXML_CLASS_TEXT) { | |
24029 | while (i + 1 < n && | |
24030 | (kid2 = (((i + 1) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i + 1] : __null)) && | |
24031 | kid2->xml_class == JSXML_CLASS_TEXT) { | |
24032 | str = js_ConcatStrings(cx, kid->u.value, kid2->u.value); | |
24033 | if (!str) | |
24034 | return (JSIntn)0; | |
24035 | NormalizingDelete(cx, xml, i + 1); | |
24036 | n = xml->u.list.kids.length; | |
24037 | kid->u.value = str; | |
24038 | } | |
24039 | if (kid->u.value->empty()) { | |
24040 | NormalizingDelete(cx, xml, i); | |
24041 | n = xml->u.list.kids.length; | |
24042 | --i; | |
24043 | } | |
24044 | } | |
24045 | } | |
24046 | return (JSIntn)1; | |
24047 | } | |
24048 | static JSBool | |
24049 | xml_normalize(JSContext *cx, uintN argc, jsval *vp) | |
24050 | { | |
24051 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24052 | *vp = OBJECT_TO_JSVAL(obj); | |
24053 | return xml_normalize_helper(cx, obj, xml); | |
24054 | } | |
24055 | static JSBool | |
24056 | xml_parent(JSContext *cx, uintN argc, jsval *vp) | |
24057 | { | |
24058 | JSXML *parent, *kid; | |
24059 | uint32 i, n; | |
24060 | JSObject *parentobj; | |
24061 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24062 | parent = xml->parent; | |
24063 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24064 | *vp = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24065 | n = xml->u.list.kids.length; | |
24066 | if (n == 0) | |
24067 | return (JSIntn)1; | |
24068 | kid = (((0) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[0] : __null); | |
24069 | if (!kid) | |
24070 | return (JSIntn)1; | |
24071 | parent = kid->parent; | |
24072 | for (i = 1; i < n; i++) { | |
24073 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24074 | if (kid && kid->parent != parent) | |
24075 | return (JSIntn)1; | |
24076 | } | |
24077 | } | |
24078 | if (!parent) { | |
24079 | *vp = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
24080 | return (JSIntn)1; | |
24081 | } | |
24082 | parentobj = js_GetXMLObject(cx, parent); | |
24083 | if (!parentobj) | |
24084 | return (JSIntn)0; | |
24085 | *vp = OBJECT_TO_JSVAL(parentobj); | |
24086 | return (JSIntn)1; | |
24087 | } | |
24088 | static JSBool | |
24089 | xml_processingInstructions_helper(JSContext *cx, JSObject *obj, JSXML *xml, | |
24090 | JSObject *nameqn, jsval *vp) | |
24091 | { | |
24092 | JSXML *list, *vxml; | |
24093 | JSBool ok; | |
24094 | JSObject *kidobj; | |
24095 | jsval v; | |
24096 | uint32 i, n; | |
24097 | list = xml_list_helper(cx, xml, vp); | |
24098 | if (!list) | |
24099 | return (JSIntn)0; | |
24100 | list->u.list.targetprop = nameqn; | |
24101 | ok = (JSIntn)1; | |
24102 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24103 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
24104 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
24105 | if (kid->xml_class == JSXML_CLASS_ELEMENT) { | |
24106 | ok = js_EnterLocalRootScope(cx); | |
24107 | if (!ok) | |
24108 | break; | |
24109 | kidobj = js_GetXMLObject(cx, kid); | |
24110 | if (kidobj) { | |
24111 | ok = xml_processingInstructions_helper(cx, kidobj, kid, | |
24112 | nameqn, &v); | |
24113 | } else { | |
24114 | ok = (JSIntn)0; | |
24115 | v = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
24116 | } | |
24117 | js_LeaveLocalRootScopeWithResult(cx, Valueify(v)); | |
24118 | if (!ok) | |
24119 | break; | |
24120 | vxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); | |
24121 | if (((((vxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (vxml)->u.list.kids.length : 0) != 0) { | |
24122 | ok = Append(cx, list, vxml); | |
24123 | if (!ok) | |
24124 | break; | |
24125 | } | |
24126 | } | |
24127 | } | |
24128 | } else { | |
24129 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
24130 | JSXML *kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24131 | if (kid && kid->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) { | |
24132 | JSLinearString *localName = nameqn->getQNameLocalName(); | |
24133 | if (((localName)->length() == 1 && *(localName)->chars() == '*') || | |
24134 | EqualStrings(localName, kid->name->getQNameLocalName())) { | |
24135 | ok = Append(cx, list, kid); | |
24136 | if (!ok) | |
24137 | break; | |
24138 | } | |
24139 | } | |
24140 | } | |
24141 | } | |
24142 | return ok; | |
24143 | } | |
24144 | static JSBool | |
24145 | xml_processingInstructions(JSContext *cx, uintN argc, jsval *vp) | |
24146 | { | |
24147 | jsval name; | |
24148 | JSObject *nameqn; | |
24149 | jsid funid; | |
24150 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24151 | name = (argc == 0) ? STRING_TO_JSVAL((cx->runtime->atomState.starAtom)) : vp[2]; | |
24152 | nameqn = ToXMLName(cx, name, &funid); | |
24153 | if (!nameqn) | |
24154 | return (JSIntn)0; | |
24155 | vp[2] = OBJECT_TO_JSVAL(nameqn); | |
24156 | if (!JSID_IS_VOID(funid)) | |
24157 | return xml_list_helper(cx, xml, vp) != __null; | |
24158 | return xml_processingInstructions_helper(cx, obj, xml, nameqn, vp); | |
24159 | } | |
24160 | static JSBool | |
24161 | xml_prependChild(JSContext *cx, uintN argc, jsval *vp) | |
24162 | { | |
24163 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24164 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24165 | if (!xml) | |
24166 | return (JSIntn)0; | |
24167 | *vp = OBJECT_TO_JSVAL(obj); | |
24168 | return Insert(cx, xml, 0, argc != 0 ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0))); | |
24169 | } | |
24170 | static JSBool | |
24171 | xml_propertyIsEnumerable(JSContext *cx, uintN argc, jsval *vp) | |
24172 | { | |
24173 | bool isIndex; | |
24174 | uint32 index; | |
24175 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24176 | *vp = ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)0)); | |
24177 | if (argc != 0) { | |
24178 | if (!js_IdValIsIndex(cx, vp[2], &index, &isIndex)) | |
24179 | return (JSIntn)0; | |
24180 | if (isIndex) { | |
24181 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24182 | *vp = BOOLEAN_TO_JSVAL(index < xml->u.list.kids.length); | |
24183 | } else { | |
24184 | *vp = BOOLEAN_TO_JSVAL(index == 0); | |
24185 | } | |
24186 | } | |
24187 | } | |
24188 | return (JSIntn)1; | |
24189 | } | |
24190 | static JSBool | |
24191 | namespace_full_match(const void *a, const void *b) | |
24192 | { | |
24193 | const JSObject *nsa = (const JSObject *) a; | |
24194 | const JSObject *nsb = (const JSObject *) b; | |
24195 | JSLinearString *prefixa = nsa->getNamePrefix(); | |
24196 | JSLinearString *prefixb; | |
24197 | if (prefixa) { | |
24198 | prefixb = nsb->getNamePrefix(); | |
24199 | if (prefixb && !EqualStrings(prefixa, prefixb)) | |
24200 | return (JSIntn)0; | |
24201 | } | |
24202 | return EqualStrings(nsa->getNameURI(), nsb->getNameURI()); | |
24203 | } | |
24204 | static JSBool | |
24205 | xml_removeNamespace_helper(JSContext *cx, JSXML *xml, JSObject *ns) | |
24206 | { | |
24207 | JSObject *thisns, *attrns; | |
24208 | uint32 i, n; | |
24209 | JSXML *attr, *kid; | |
24210 | thisns = GetNamespace(cx, xml->name, &xml->u.elem.namespaces); | |
24211 | ((void) 0); | |
24212 | if (thisns == ns) | |
24213 | return (JSIntn)1; | |
24214 | for (i = 0, n = xml->u.elem.attrs.length; i < n; i++) { | |
24215 | attr = (((i) < (&xml->u.elem.attrs)->length) ? (JSXML *) (&xml->u.elem.attrs)->vector[i] : __null); | |
24216 | if (!attr) | |
24217 | continue; | |
24218 | attrns = GetNamespace(cx, attr->name, &xml->u.elem.namespaces); | |
24219 | ((void) 0); | |
24220 | if (attrns == ns) | |
24221 | return (JSIntn)1; | |
24222 | } | |
24223 | i = XMLArrayFindMember(&xml->u.elem.namespaces, (void *)(ns), namespace_full_match); | |
24224 | if (i != ((uint32) -1)) | |
24225 | XMLArrayDelete(cx, &xml->u.elem.namespaces, i, (JSIntn)1); | |
24226 | for (i = 0, n = xml->u.list.kids.length; i < n; i++) { | |
24227 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24228 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
24229 | if (!xml_removeNamespace_helper(cx, kid, ns)) | |
24230 | return (JSIntn)0; | |
24231 | } | |
24232 | } | |
24233 | return (JSIntn)1; | |
24234 | } | |
24235 | static JSBool | |
24236 | xml_removeNamespace(JSContext *cx, uintN argc, jsval *vp) | |
24237 | { | |
24238 | JSObject *ns; | |
24239 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24240 | if (xml->xml_class != JSXML_CLASS_ELEMENT) | |
24241 | goto done; | |
24242 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24243 | if (!xml) | |
24244 | return (JSIntn)0; | |
24245 | if (!NamespaceHelper(cx, __null, argc == 0 ? -1 : 1, vp + 2, vp)) | |
24246 | return (JSIntn)0; | |
24247 | ((void) 0); | |
24248 | ns = JSVAL_TO_OBJECT(*vp); | |
24249 | if (!xml_removeNamespace_helper(cx, xml, ns)) | |
24250 | return (JSIntn)0; | |
24251 | done: | |
24252 | *vp = OBJECT_TO_JSVAL(obj); | |
24253 | return (JSIntn)1; | |
24254 | } | |
24255 | static JSBool | |
24256 | xml_replace(JSContext *cx, uintN argc, jsval *vp) | |
24257 | { | |
24258 | jsval value; | |
24259 | JSXML *vxml, *kid; | |
24260 | uint32 index, i; | |
24261 | JSObject *nameqn; | |
24262 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24263 | if (xml->xml_class != JSXML_CLASS_ELEMENT) | |
24264 | goto done; | |
24265 | if (argc <= 1) { | |
24266 | value = STRING_TO_JSVAL((cx->runtime->atomState.typeAtoms[JSTYPE_VOID])); | |
24267 | } else { | |
24268 | value = vp[3]; | |
24269 | vxml = (!JSVAL_IS_PRIMITIVE(value) && JSVAL_TO_OBJECT(value)->isXML()) | |
24270 | ? (JSXML *) JSVAL_TO_OBJECT(value)->getPrivate() | |
24271 | : __null; | |
24272 | if (!vxml) { | |
24273 | if (!JS_ConvertValue(cx, value, JSTYPE_STRING, &vp[3])) | |
24274 | return (JSIntn)0; | |
24275 | value = vp[3]; | |
24276 | } else { | |
24277 | vxml = DeepCopy(cx, vxml, __null, 0); | |
24278 | if (!vxml) | |
24279 | return (JSIntn)0; | |
24280 | value = vp[3] = OBJECT_TO_JSVAL(vxml->object); | |
24281 | } | |
24282 | } | |
24283 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24284 | if (!xml) | |
24285 | return (JSIntn)0; | |
24286 | bool haveIndex; | |
24287 | if (argc == 0) { | |
24288 | haveIndex = false; | |
24289 | } else { | |
24290 | if (!js_IdValIsIndex(cx, vp[2], &index, &haveIndex)) | |
24291 | return (JSIntn)0; | |
24292 | } | |
24293 | if (!haveIndex) { | |
24294 | if (!QNameHelper(cx, __null, argc == 0 ? -1 : 1, vp + 2, vp)) | |
24295 | return (JSIntn)0; | |
24296 | ((void) 0); | |
24297 | nameqn = JSVAL_TO_OBJECT(*vp); | |
24298 | i = xml->u.list.kids.length; | |
24299 | index = ((uint32) -1); | |
24300 | while (i != 0) { | |
24301 | --i; | |
24302 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24303 | if (kid && MatchElemName(nameqn, kid)) { | |
24304 | if (i != ((uint32) -1)) | |
24305 | DeleteByIndex(cx, xml, i); | |
24306 | index = i; | |
24307 | } | |
24308 | } | |
24309 | if (index == ((uint32) -1)) | |
24310 | goto done; | |
24311 | } | |
24312 | if (!Replace(cx, xml, index, value)) | |
24313 | return (JSIntn)0; | |
24314 | done: | |
24315 | *vp = OBJECT_TO_JSVAL(obj); | |
24316 | return (JSIntn)1; | |
24317 | } | |
24318 | static JSBool | |
24319 | xml_setChildren(JSContext *cx, uintN argc, jsval *vp) | |
24320 | { | |
24321 | JSObject *obj; | |
24322 | if (!StartNonListXMLMethod(cx, vp, &obj)) | |
24323 | return (JSIntn)0; | |
24324 | *vp = argc != 0 ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24325 | if (!PutProperty(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.starAtom), false, vp)) | |
24326 | return (JSIntn)0; | |
24327 | *vp = OBJECT_TO_JSVAL(obj); | |
24328 | return (JSIntn)1; | |
24329 | } | |
24330 | static JSBool | |
24331 | xml_setLocalName(JSContext *cx, uintN argc, jsval *vp) | |
24332 | { | |
24333 | jsval name; | |
24334 | JSObject *nameqn; | |
24335 | JSLinearString *namestr; | |
24336 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24337 | if (!((uintN)(((xml)->xml_class) - JSXML_CLASS_ELEMENT) <= (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT))) | |
24338 | return (JSIntn)1; | |
24339 | if (argc == 0) { | |
24340 | namestr = (cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); | |
24341 | } else { | |
24342 | name = vp[2]; | |
24343 | if (!JSVAL_IS_PRIMITIVE(name) && | |
24344 | JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass) { | |
24345 | nameqn = JSVAL_TO_OBJECT(name); | |
24346 | namestr = nameqn->getQNameLocalName(); | |
24347 | } else { | |
24348 | if (!JS_ConvertValue(cx, name, JSTYPE_STRING, &vp[2])) | |
24349 | return (JSIntn)0; | |
24350 | name = vp[2]; | |
24351 | namestr = JSVAL_TO_STRING(name)->ensureLinear(cx); | |
24352 | if (!namestr) | |
24353 | return (JSIntn)0; | |
24354 | } | |
24355 | } | |
24356 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24357 | if (!xml) | |
24358 | return (JSIntn)0; | |
24359 | if (namestr) | |
24360 | xml->name->setQNameLocalName(namestr); | |
24361 | return (JSIntn)1; | |
24362 | } | |
24363 | static JSBool | |
24364 | xml_setName(JSContext *cx, uintN argc, jsval *vp) | |
24365 | { | |
24366 | jsval name; | |
24367 | JSObject *nameqn; | |
24368 | JSXML *nsowner; | |
24369 | JSXMLArray *nsarray; | |
24370 | uint32 i, n; | |
24371 | JSObject *ns; | |
24372 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24373 | if (!((uintN)(((xml)->xml_class) - JSXML_CLASS_ELEMENT) <= (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT))) | |
24374 | return (JSIntn)1; | |
24375 | if (argc == 0) { | |
24376 | name = STRING_TO_JSVAL((cx->runtime->atomState.typeAtoms[JSTYPE_VOID])); | |
24377 | } else { | |
24378 | name = vp[2]; | |
24379 | if (!JSVAL_IS_PRIMITIVE(name) && | |
24380 | JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass && | |
24381 | !(nameqn = JSVAL_TO_OBJECT(name))->getNameURI()) { | |
24382 | name = vp[2] = nameqn->getQNameLocalNameVal(); | |
24383 | } | |
24384 | } | |
24385 | nameqn = js_ConstructObject(cx, &js_QNameClass, __null, __null, 1, Valueify(&name)); | |
24386 | if (!nameqn) | |
24387 | return (JSIntn)0; | |
24388 | if (xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) | |
24389 | nameqn->setNameURI(cx->runtime->emptyString); | |
24390 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24391 | if (!xml) | |
24392 | return (JSIntn)0; | |
24393 | xml->name = nameqn; | |
24394 | if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
24395 | nsowner = xml; | |
24396 | } else { | |
24397 | if (!xml->parent || xml->parent->xml_class != JSXML_CLASS_ELEMENT) | |
24398 | return (JSIntn)1; | |
24399 | nsowner = xml->parent; | |
24400 | } | |
24401 | if (nameqn->getNamePrefix()) { | |
24402 | ns = GetNamespace(cx, nameqn, &nsowner->u.elem.namespaces); | |
24403 | if (!ns) | |
24404 | return (JSIntn)0; | |
24405 | if ((XMLArrayFindMember(&nsowner->u.elem.namespaces, (void *)(ns), __null) != ((uint32) -1))) | |
24406 | return (JSIntn)1; | |
24407 | } else { | |
24408 | ((void) 0); | |
24409 | nsarray = &nsowner->u.elem.namespaces; | |
24410 | for (i = 0, n = nsarray->length; i < n; i++) { | |
24411 | ns = (((i) < (nsarray)->length) ? (JSObject *) (nsarray)->vector[i] : __null); | |
24412 | if (ns && EqualStrings(ns->getNameURI(), nameqn->getNameURI())) { | |
24413 | nameqn->setNamePrefix(ns->getNamePrefix()); | |
24414 | return (JSIntn)1; | |
24415 | } | |
24416 | } | |
24417 | ns = NewXMLNamespace(cx, __null, nameqn->getNameURI(), (JSIntn)1); | |
24418 | if (!ns) | |
24419 | return (JSIntn)0; | |
24420 | } | |
24421 | if (!AddInScopeNamespace(cx, nsowner, ns)) | |
24422 | return (JSIntn)0; | |
24423 | vp[0] = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24424 | return (JSIntn)1; | |
24425 | } | |
24426 | static JSBool | |
24427 | xml_setNamespace(JSContext *cx, uintN argc, jsval *vp) | |
24428 | { | |
24429 | JSObject *qn; | |
24430 | JSObject *ns; | |
24431 | jsval qnargv[2]; | |
24432 | JSXML *nsowner; | |
24433 | JSObject *obj; JSXML *xml = StartNonListXMLMethod(cx, vp, &obj); if (!xml) return (JSIntn)0; ((void) 0); | |
24434 | if (!((uintN)(((xml)->xml_class) - JSXML_CLASS_ELEMENT) <= (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT))) | |
24435 | return (JSIntn)1; | |
24436 | xml = (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj)); | |
24437 | if (!xml) | |
24438 | return (JSIntn)0; | |
24439 | ns = js_ConstructObject(cx, &js_NamespaceClass, __null, obj, | |
24440 | argc == 0 ? 0 : 1, Valueify(vp + 2)); | |
24441 | if (!ns) | |
24442 | return (JSIntn)0; | |
24443 | vp[0] = OBJECT_TO_JSVAL(ns); | |
24444 | ns->setNamespaceDeclared(((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1))); | |
24445 | qnargv[0] = OBJECT_TO_JSVAL(ns); | |
24446 | qnargv[1] = OBJECT_TO_JSVAL(xml->name); | |
24447 | qn = js_ConstructObject(cx, &js_QNameClass, __null, __null, 2, Valueify(qnargv)); | |
24448 | if (!qn) | |
24449 | return (JSIntn)0; | |
24450 | xml->name = qn; | |
24451 | if (xml->xml_class == JSXML_CLASS_ELEMENT) { | |
24452 | nsowner = xml; | |
24453 | } else { | |
24454 | if (!xml->parent || xml->parent->xml_class != JSXML_CLASS_ELEMENT) | |
24455 | return (JSIntn)1; | |
24456 | nsowner = xml->parent; | |
24457 | } | |
24458 | if (!AddInScopeNamespace(cx, nsowner, ns)) | |
24459 | return (JSIntn)0; | |
24460 | vp[0] = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24461 | return (JSIntn)1; | |
24462 | } | |
24463 | static JSBool | |
24464 | xml_text_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval *vp) | |
24465 | { | |
24466 | JSXML *list, *kid, *vxml; | |
24467 | uint32 i, n; | |
24468 | JSBool ok; | |
24469 | JSObject *kidobj; | |
24470 | jsval v; | |
24471 | list = xml_list_helper(cx, xml, vp); | |
24472 | if (!list) | |
24473 | return (JSIntn)0; | |
24474 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24475 | ok = (JSIntn)1; | |
24476 | for (i = 0, n = xml->u.list.kids.length; i < n; i++) { | |
24477 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24478 | if (kid && kid->xml_class == JSXML_CLASS_ELEMENT) { | |
24479 | ok = js_EnterLocalRootScope(cx); | |
24480 | if (!ok) | |
24481 | break; | |
24482 | kidobj = js_GetXMLObject(cx, kid); | |
24483 | if (kidobj) { | |
24484 | ok = xml_text_helper(cx, kidobj, kid, &v); | |
24485 | } else { | |
24486 | ok = (JSIntn)0; | |
24487 | v = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
24488 | } | |
24489 | js_LeaveLocalRootScopeWithResult(cx, Valueify(v)); | |
24490 | if (!ok) | |
24491 | return (JSIntn)0; | |
24492 | vxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); | |
24493 | if (((((vxml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (vxml)->u.list.kids.length : 0) != 0 && !Append(cx, list, vxml)) | |
24494 | return (JSIntn)0; | |
24495 | } | |
24496 | } | |
24497 | } else { | |
24498 | for (i = 0, n = ((((xml)->xml_class) < JSXML_CLASS_ATTRIBUTE) ? (xml)->u.list.kids.length : 0); i < n; i++) { | |
24499 | kid = (((i) < (&xml->u.list.kids)->length) ? (JSXML *) (&xml->u.list.kids)->vector[i] : __null); | |
24500 | if (kid && kid->xml_class == JSXML_CLASS_TEXT) { | |
24501 | if (!Append(cx, list, kid)) | |
24502 | return (JSIntn)0; | |
24503 | } | |
24504 | } | |
24505 | } | |
24506 | return (JSIntn)1; | |
24507 | } | |
24508 | static JSBool | |
24509 | xml_text(JSContext *cx, uintN argc, jsval *vp) | |
24510 | { | |
24511 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24512 | return xml_text_helper(cx, obj, xml, vp); | |
24513 | } | |
24514 | static JSString * | |
24515 | xml_toString_helper(JSContext *cx, JSXML *xml) | |
24516 | { | |
24517 | JSString *str, *kidstr; | |
24518 | if (xml->xml_class == JSXML_CLASS_ATTRIBUTE || | |
24519 | xml->xml_class == JSXML_CLASS_TEXT) { | |
24520 | return xml->u.value; | |
24521 | } | |
24522 | if (!HasSimpleContent(xml)) | |
24523 | return ToXMLString(cx, OBJECT_TO_JSVAL(xml->object), 0); | |
24524 | str = cx->runtime->emptyString; | |
24525 | if (!js_EnterLocalRootScope(cx)) | |
24526 | return __null; | |
24527 | JSXMLArrayCursor cursor(&xml->u.list.kids); | |
24528 | while (JSXML *kid = (JSXML *) cursor.getNext()) { | |
24529 | if (kid->xml_class != JSXML_CLASS_COMMENT && | |
24530 | kid->xml_class != JSXML_CLASS_PROCESSING_INSTRUCTION) { | |
24531 | kidstr = xml_toString_helper(cx, kid); | |
24532 | if (!kidstr) { | |
24533 | str = __null; | |
24534 | break; | |
24535 | } | |
24536 | str = js_ConcatStrings(cx, str, kidstr); | |
24537 | if (!str) | |
24538 | break; | |
24539 | } | |
24540 | } | |
24541 | js_LeaveLocalRootScopeWithResult(cx, str); | |
24542 | return str; | |
24543 | } | |
24544 | static JSBool | |
24545 | xml_toSource(JSContext *cx, uintN argc, jsval *vp) | |
24546 | { | |
24547 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
24548 | if (!obj) | |
24549 | return (JSIntn)0; | |
24550 | JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), 0x80000000); | |
24551 | if (!str) | |
24552 | return (JSIntn)0; | |
24553 | *vp = STRING_TO_JSVAL(str); | |
24554 | return (JSIntn)1; | |
24555 | } | |
24556 | static JSBool | |
24557 | xml_toString(JSContext *cx, uintN argc, jsval *vp) | |
24558 | { | |
24559 | JSString *str; | |
24560 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); if (!obj) return (JSIntn)0; JSXML *xml = (JSXML *)GetInstancePrivate(cx, obj, &js_XMLClass, Valueify(vp+2)); if (!xml) return (JSIntn)0; | |
24561 | str = xml_toString_helper(cx, xml); | |
24562 | if (!str) | |
24563 | return (JSIntn)0; | |
24564 | *vp = STRING_TO_JSVAL(str); | |
24565 | return (JSIntn)1; | |
24566 | } | |
24567 | static JSBool | |
24568 | xml_toXMLString(JSContext *cx, uintN argc, jsval *vp) | |
24569 | { | |
24570 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
24571 | if (!obj) | |
24572 | return (JSIntn)0; | |
24573 | JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), 0); | |
24574 | if (!str) | |
24575 | return (JSIntn)0; | |
24576 | *vp = STRING_TO_JSVAL(str); | |
24577 | return (JSIntn)1; | |
24578 | } | |
24579 | static JSBool | |
24580 | xml_valueOf(JSContext *cx, uintN argc, jsval *vp) | |
24581 | { | |
24582 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
24583 | if (!obj) | |
24584 | return false; | |
24585 | *vp = OBJECT_TO_JSVAL(obj); | |
24586 | return true; | |
24587 | } | |
24588 | static JSFunctionSpec xml_methods[] = { | |
24589 | {"addNamespace", ((JSNative)(xml_addNamespace)), 1, (0) | 0x1000}, | |
24590 | {"appendChild", ((JSNative)(xml_appendChild)), 1, (0) | 0x1000}, | |
24591 | {js_attribute_str, ((JSNative)(xml_attribute)), 1, (0) | 0x1000}, | |
24592 | {"attributes", ((JSNative)(xml_attributes)), 0, (0) | 0x1000}, | |
24593 | {"child", ((JSNative)(xml_child)), 1, (0) | 0x1000}, | |
24594 | {"childIndex", ((JSNative)(xml_childIndex)), 0, (0) | 0x1000}, | |
24595 | {"children", ((JSNative)(xml_children)), 0, (0) | 0x1000}, | |
24596 | {"comments", ((JSNative)(xml_comments)), 0, (0) | 0x1000}, | |
24597 | {"contains", ((JSNative)(xml_contains)), 1, (0) | 0x1000}, | |
24598 | {"copy", ((JSNative)(xml_copy)), 0, (0) | 0x1000}, | |
24599 | {"descendants", ((JSNative)(xml_descendants)), 1, (0) | 0x1000}, | |
24600 | {"elements", ((JSNative)(xml_elements)), 1, (0) | 0x1000}, | |
24601 | {"hasOwnProperty", ((JSNative)(xml_hasOwnProperty)), 1, (0) | 0x1000}, | |
24602 | {"hasComplexContent", ((JSNative)(xml_hasComplexContent)), 1, (0) | 0x1000}, | |
24603 | {"hasSimpleContent", ((JSNative)(xml_hasSimpleContent)), 1, (0) | 0x1000}, | |
24604 | {"inScopeNamespaces", ((JSNative)(xml_inScopeNamespaces)), 0, (0) | 0x1000}, | |
24605 | {"insertChildAfter", ((JSNative)(xml_insertChildAfter)), 2, (0) | 0x1000}, | |
24606 | {"insertChildBefore", ((JSNative)(xml_insertChildBefore)), 2, (0) | 0x1000}, | |
24607 | {js_length_str, ((JSNative)(xml_length)), 0, (0) | 0x1000}, | |
24608 | {js_localName_str, ((JSNative)(xml_localName)), 0, (0) | 0x1000}, | |
24609 | {js_name_str, ((JSNative)(xml_name)), 0, (0) | 0x1000}, | |
24610 | {js_namespace_str, ((JSNative)(xml_namespace)), 1, (0) | 0x1000}, | |
24611 | {"namespaceDeclarations", ((JSNative)(xml_namespaceDeclarations)), 0, (0) | 0x1000}, | |
24612 | {"nodeKind", ((JSNative)(xml_nodeKind)), 0, (0) | 0x1000}, | |
24613 | {"normalize", ((JSNative)(xml_normalize)), 0, (0) | 0x1000}, | |
24614 | {js_xml_parent_str, ((JSNative)(xml_parent)), 0, (0) | 0x1000}, | |
24615 | {"processingInstructions", ((JSNative)(xml_processingInstructions)), 1, (0) | 0x1000}, | |
24616 | {"prependChild", ((JSNative)(xml_prependChild)), 1, (0) | 0x1000}, | |
24617 | {"propertyIsEnumerable", ((JSNative)(xml_propertyIsEnumerable)), 1, (0) | 0x1000}, | |
24618 | {"removeNamespace", ((JSNative)(xml_removeNamespace)), 1, (0) | 0x1000}, | |
24619 | {"replace", ((JSNative)(xml_replace)), 2, (0) | 0x1000}, | |
24620 | {"setChildren", ((JSNative)(xml_setChildren)), 1, (0) | 0x1000}, | |
24621 | {"setLocalName", ((JSNative)(xml_setLocalName)), 1, (0) | 0x1000}, | |
24622 | {"setName", ((JSNative)(xml_setName)), 1, (0) | 0x1000}, | |
24623 | {"setNamespace", ((JSNative)(xml_setNamespace)), 1, (0) | 0x1000}, | |
24624 | {js_text_str, ((JSNative)(xml_text)), 0, (0) | 0x1000}, | |
24625 | {js_toSource_str, ((JSNative)(xml_toSource)), 0, (0) | 0x1000}, | |
24626 | {js_toString_str, ((JSNative)(xml_toString)), 0, (0) | 0x1000}, | |
24627 | {js_toXMLString_str, ((JSNative)(xml_toXMLString)), 0, (0) | 0x1000}, | |
24628 | {js_valueOf_str, ((JSNative)(xml_valueOf)), 0, (0) | 0x1000}, | |
24629 | {__null, __null, 0, 0} | |
24630 | }; | |
24631 | static JSBool | |
24632 | CopyXMLSettings(JSContext *cx, JSObject *from, JSObject *to) | |
24633 | { | |
24634 | int i; | |
24635 | const char *name; | |
24636 | jsval v; | |
24637 | for (i = 0; xml_static_props[i].name; i++) { | |
24638 | name = xml_static_props[i].name; | |
24639 | if (!JS_GetProperty(cx, from, name, &v)) | |
24640 | return false; | |
24641 | if (name == js_prettyIndent_str) { | |
24642 | if (!JSVAL_IS_NUMBER(v)) | |
24643 | continue; | |
24644 | } else { | |
24645 | if (!JSVAL_IS_BOOLEAN(v)) | |
24646 | continue; | |
24647 | } | |
24648 | if (!JS_SetProperty(cx, to, name, &v)) | |
24649 | return false; | |
24650 | } | |
24651 | return true; | |
24652 | } | |
24653 | static JSBool | |
24654 | SetDefaultXMLSettings(JSContext *cx, JSObject *obj) | |
24655 | { | |
24656 | int i; | |
24657 | jsval v; | |
24658 | for (i = 0; xml_static_props[i].name; i++) { | |
24659 | v = (xml_static_props[i].name != js_prettyIndent_str) | |
24660 | ? ((((uint64)(uint32)(JSVAL_TAG_BOOLEAN)) << 47) | ((JSIntn)1)) : INT_TO_JSVAL(2); | |
24661 | if (!JS_SetProperty(cx, obj, xml_static_props[i].name, &v)) | |
24662 | return (JSIntn)0; | |
24663 | } | |
24664 | return true; | |
24665 | } | |
24666 | static JSBool | |
24667 | xml_settings(JSContext *cx, uintN argc, jsval *vp) | |
24668 | { | |
24669 | JSObject *settings = JS_NewObject(cx, __null, __null, __null); | |
24670 | if (!settings) | |
24671 | return false; | |
24672 | *vp = OBJECT_TO_JSVAL(settings); | |
24673 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
24674 | if (!obj) | |
24675 | return false; | |
24676 | return CopyXMLSettings(cx, obj, settings); | |
24677 | } | |
24678 | static JSBool | |
24679 | xml_setSettings(JSContext *cx, uintN argc, jsval *vp) | |
24680 | { | |
24681 | JSObject *settings; | |
24682 | jsval v; | |
24683 | JSBool ok; | |
24684 | JSObject *obj = ToObject(cx, Valueify(&vp[1])); | |
24685 | if (!obj) | |
24686 | return (JSIntn)0; | |
24687 | v = (argc == 0) ? ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)) : vp[2]; | |
24688 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) { | |
24689 | ok = SetDefaultXMLSettings(cx, obj); | |
24690 | } else { | |
24691 | if (JSVAL_IS_PRIMITIVE(v)) | |
24692 | return (JSIntn)1; | |
24693 | settings = JSVAL_TO_OBJECT(v); | |
24694 | ok = CopyXMLSettings(cx, settings, obj); | |
24695 | } | |
24696 | return ok; | |
24697 | } | |
24698 | static JSBool | |
24699 | xml_defaultSettings(JSContext *cx, uintN argc, jsval *vp) | |
24700 | { | |
24701 | JSObject *settings; | |
24702 | settings = JS_NewObject(cx, __null, __null, __null); | |
24703 | if (!settings) | |
24704 | return (JSIntn)0; | |
24705 | *vp = OBJECT_TO_JSVAL(settings); | |
24706 | return SetDefaultXMLSettings(cx, settings); | |
24707 | } | |
24708 | static JSFunctionSpec xml_static_methods[] = { | |
24709 | {"settings", ((JSNative)(xml_settings)), 0, (0) | 0x1000}, | |
24710 | {"setSettings", ((JSNative)(xml_setSettings)), 1, (0) | 0x1000}, | |
24711 | {"defaultSettings", ((JSNative)(xml_defaultSettings)), 0, (0) | 0x1000}, | |
24712 | {__null, __null, 0, 0} | |
24713 | }; | |
24714 | static JSBool | |
24715 | XML(JSContext *cx, uintN argc, Value *vp) | |
24716 | { | |
24717 | JSXML *xml, *copy; | |
24718 | JSObject *xobj, *vobj; | |
24719 | Class *clasp; | |
24720 | jsval v = argc ? Jsvalify(vp[2]) : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24721 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) | |
24722 | v = STRING_TO_JSVAL(cx->runtime->emptyString); | |
24723 | xobj = ToXML(cx, v); | |
24724 | if (!xobj) | |
24725 | return (JSIntn)0; | |
24726 | xml = (JSXML *) xobj->getPrivate(); | |
24727 | if (IsConstructing(vp) && !JSVAL_IS_PRIMITIVE(v)) { | |
24728 | vobj = JSVAL_TO_OBJECT(v); | |
24729 | clasp = vobj->getClass(); | |
24730 | if (clasp == &js_XMLClass || | |
24731 | (clasp->flags & (1<<7))) { | |
24732 | copy = DeepCopy(cx, xml, __null, 0); | |
24733 | if (!copy) | |
24734 | return (JSIntn)0; | |
24735 | vp->setObject(*copy->object); | |
24736 | return (JSIntn)1; | |
24737 | } | |
24738 | } | |
24739 | vp->setObject(*xobj); | |
24740 | return (JSIntn)1; | |
24741 | } | |
24742 | static JSBool | |
24743 | XMLList(JSContext *cx, uintN argc, jsval *vp) | |
24744 | { | |
24745 | JSObject *vobj, *listobj; | |
24746 | JSXML *xml, *list; | |
24747 | jsval v = argc ? vp[2] : ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24748 | if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) | |
24749 | v = STRING_TO_JSVAL(cx->runtime->emptyString); | |
24750 | if (IsConstructing(Valueify(vp)) && !JSVAL_IS_PRIMITIVE(v)) { | |
24751 | vobj = JSVAL_TO_OBJECT(v); | |
24752 | if (vobj->isXML()) { | |
24753 | xml = (JSXML *) vobj->getPrivate(); | |
24754 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24755 | listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
24756 | if (!listobj) | |
24757 | return (JSIntn)0; | |
24758 | *vp = OBJECT_TO_JSVAL(listobj); | |
24759 | list = (JSXML *) listobj->getPrivate(); | |
24760 | if (!Append(cx, list, xml)) | |
24761 | return (JSIntn)0; | |
24762 | return (JSIntn)1; | |
24763 | } | |
24764 | } | |
24765 | } | |
24766 | listobj = ToXMLList(cx, v); | |
24767 | if (!listobj) | |
24768 | return (JSIntn)0; | |
24769 | *vp = OBJECT_TO_JSVAL(listobj); | |
24770 | return (JSIntn)1; | |
24771 | } | |
24772 | JSXML * | |
24773 | js_NewXML(JSContext *cx, JSXMLClass xml_class) | |
24774 | { | |
24775 | JSXML *xml = js_NewGCXML(cx); | |
24776 | if (!xml) | |
24777 | return __null; | |
24778 | xml->object = __null; | |
24779 | xml->domnode = __null; | |
24780 | xml->parent = __null; | |
24781 | xml->name = __null; | |
24782 | xml->xml_class = xml_class; | |
24783 | xml->xml_flags = 0; | |
24784 | if (((xml_class) >= JSXML_CLASS_ATTRIBUTE)) { | |
24785 | xml->u.value = cx->runtime->emptyString; | |
24786 | } else { | |
24787 | xml->u.list.kids.init(); | |
24788 | if (xml_class == JSXML_CLASS_LIST) { | |
24789 | xml->u.list.target = __null; | |
24790 | xml->u.list.targetprop = __null; | |
24791 | } else { | |
24792 | xml->u.elem.namespaces.init(); | |
24793 | xml->u.elem.attrs.init(); | |
24794 | } | |
24795 | } | |
24796 | ; | |
24797 | return xml; | |
24798 | } | |
24799 | void | |
24800 | js_TraceXML(JSTracer *trc, JSXML *xml) | |
24801 | { | |
24802 | if (xml->object) | |
24803 | MarkObject(trc, *xml->object, "object"); | |
24804 | if (xml->name) | |
24805 | MarkObject(trc, *xml->name, "name"); | |
24806 | if (xml->parent) | |
24807 | do { do { } while (0); JS_CallTracer((trc), (xml->parent), (2)); } while (0); | |
24808 | if ((((xml)->xml_class) >= JSXML_CLASS_ATTRIBUTE)) { | |
24809 | if (xml->u.value) | |
24810 | MarkString(trc, xml->u.value, "value"); | |
24811 | return; | |
24812 | } | |
24813 | xml_trace_vector(trc, | |
24814 | (JSXML **) xml->u.list.kids.vector, | |
24815 | xml->u.list.kids.length); | |
24816 | XMLArrayCursorTrace(trc, xml->u.list.kids.cursors); | |
24817 | if (((trc)->callback == __null)) | |
24818 | xml->u.list.kids.trim(); | |
24819 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
24820 | if (xml->u.list.target) | |
24821 | do { do { } while (0); JS_CallTracer((trc), (xml->u.list.target), (2)); } while (0); | |
24822 | if (xml->u.list.targetprop) | |
24823 | MarkObject(trc, *xml->u.list.targetprop, "targetprop"); | |
24824 | } else { | |
24825 | MarkObjectRange(trc, xml->u.elem.namespaces.length, | |
24826 | (JSObject **) xml->u.elem.namespaces.vector, | |
24827 | "xml_namespaces"); | |
24828 | XMLArrayCursorTrace(trc, xml->u.elem.namespaces.cursors); | |
24829 | if (((trc)->callback == __null)) | |
24830 | xml->u.elem.namespaces.trim(); | |
24831 | xml_trace_vector(trc, | |
24832 | (JSXML **) xml->u.elem.attrs.vector, | |
24833 | xml->u.elem.attrs.length); | |
24834 | XMLArrayCursorTrace(trc, xml->u.elem.attrs.cursors); | |
24835 | if (((trc)->callback == __null)) | |
24836 | xml->u.elem.attrs.trim(); | |
24837 | } | |
24838 | } | |
24839 | JSObject * | |
24840 | js_NewXMLObject(JSContext *cx, JSXMLClass xml_class) | |
24841 | { | |
24842 | JSXML *xml = js_NewXML(cx, xml_class); | |
24843 | if (!xml) | |
24844 | return __null; | |
24845 | AutoXMLRooter root(cx, xml); | |
24846 | return js_GetXMLObject(cx, xml); | |
24847 | } | |
24848 | static JSObject * | |
24849 | NewXMLObject(JSContext *cx, JSXML *xml) | |
24850 | { | |
24851 | JSObject *obj; | |
24852 | obj = NewNonFunction<WithProto::Class>(cx, &js_XMLClass, __null, __null); | |
24853 | if (!obj) | |
24854 | return __null; | |
24855 | obj->setPrivate(xml); | |
24856 | ; | |
24857 | return obj; | |
24858 | } | |
24859 | JSObject * | |
24860 | js_GetXMLObject(JSContext *cx, JSXML *xml) | |
24861 | { | |
24862 | JSObject *obj; | |
24863 | obj = xml->object; | |
24864 | if (obj) { | |
24865 | ((void) 0); | |
24866 | return obj; | |
24867 | } | |
24868 | obj = NewXMLObject(cx, xml); | |
24869 | if (!obj) | |
24870 | return __null; | |
24871 | xml->object = obj; | |
24872 | return obj; | |
24873 | } | |
24874 | JSObject * | |
24875 | js_InitNamespaceClass(JSContext *cx, JSObject *obj) | |
24876 | { | |
24877 | return js_InitClass(cx, obj, __null, &js_NamespaceClass, Namespace, 2, | |
24878 | namespace_props, namespace_methods, __null, __null); | |
24879 | } | |
24880 | JSObject * | |
24881 | js_InitQNameClass(JSContext *cx, JSObject *obj) | |
24882 | { | |
24883 | return js_InitClass(cx, obj, __null, &js_QNameClass, QName, 2, | |
24884 | qname_props, qname_methods, __null, __null); | |
24885 | } | |
24886 | JSObject * | |
24887 | js_InitXMLClass(JSContext *cx, JSObject *obj) | |
24888 | { | |
24889 | JSObject *proto, *pobj; | |
24890 | JSFunction *fun; | |
24891 | JSXML *xml; | |
24892 | JSProperty *prop; | |
24893 | Shape *shape; | |
24894 | jsval cval, vp[3]; | |
24895 | if (!JS_DefineFunction(cx, obj, js_isXMLName_str, xml_isXMLName, 1, 0)) | |
24896 | return __null; | |
24897 | proto = js_InitClass(cx, obj, __null, &js_XMLClass, XML, 1, | |
24898 | __null, xml_methods, | |
24899 | xml_static_props, xml_static_methods); | |
24900 | if (!proto) | |
24901 | return __null; | |
24902 | xml = js_NewXML(cx, JSXML_CLASS_TEXT); | |
24903 | if (!xml) | |
24904 | return __null; | |
24905 | proto->setPrivate(xml); | |
24906 | xml->object = proto; | |
24907 | ; | |
24908 | if (!js_LookupProperty(cx, proto, | |
24909 | ATOM_TO_JSID(cx->runtime->atomState.constructorAtom), | |
24910 | &pobj, &prop)) { | |
24911 | return __null; | |
24912 | } | |
24913 | ((void) 0); | |
24914 | shape = (Shape *) prop; | |
24915 | cval = Jsvalify(pobj->nativeGetSlot(shape->slot)); | |
24916 | ((void) 0); | |
24917 | vp[0] = ((((uint64)(uint32)(JSVAL_TAG_NULL)) << 47) | (0)); | |
24918 | vp[1] = cval; | |
24919 | vp[2] = ((((uint64)(uint32)(JSVAL_TAG_UNDEFINED)) << 47) | (0)); | |
24920 | if (!xml_setSettings(cx, 1, vp)) | |
24921 | return __null; | |
24922 | fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0x0200); | |
24923 | if (!fun) | |
24924 | return __null; | |
24925 | if (!js_SetClassPrototype(cx, (static_cast<JSObject *>(fun)), proto, | |
24926 | 0x02 | 0x04)) { | |
24927 | return __null; | |
24928 | } | |
24929 | return proto; | |
24930 | } | |
24931 | JSObject * | |
24932 | js_InitXMLClasses(JSContext *cx, JSObject *obj) | |
24933 | { | |
24934 | if (!js_InitNamespaceClass(cx, obj)) | |
24935 | return __null; | |
24936 | if (!js_InitQNameClass(cx, obj)) | |
24937 | return __null; | |
24938 | return js_InitXMLClass(cx, obj); | |
24939 | } | |
24940 | JSBool | |
24941 | js_GetFunctionNamespace(JSContext *cx, Value *vp) | |
24942 | { | |
24943 | JSObject *global = cx->hasfp() ? cx->fp()->scopeChain().getGlobal() : cx->globalObject; | |
24944 | *vp = global->getReservedSlot(((((JSProto_LIMIT * 3) + 1) + 1) + 1)); | |
24945 | if (vp->isUndefined()) { | |
24946 | JSRuntime *rt = cx->runtime; | |
24947 | JSLinearString *prefix = rt->atomState.typeAtoms[JSTYPE_FUNCTION]; | |
24948 | JSLinearString *uri = rt->atomState.functionNamespaceURIAtom; | |
24949 | JSObject *obj = NewXMLNamespace(cx, prefix, uri, (JSIntn)0); | |
24950 | if (!obj) | |
24951 | return false; | |
24952 | obj->clearProto(); | |
24953 | vp->setObject(*obj); | |
24954 | if (!js_SetReservedSlot(cx, global, ((((JSProto_LIMIT * 3) + 1) + 1) + 1), *vp)) | |
24955 | return false; | |
24956 | } | |
24957 | return true; | |
24958 | } | |
24959 | JSBool | |
24960 | js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp) | |
24961 | { | |
24962 | JSObject *ns, *obj, *tmp; | |
24963 | jsval v; | |
24964 | JSObject *scopeChain = GetScopeChain(cx); | |
24965 | obj = __null; | |
24966 | for (tmp = scopeChain; tmp; tmp = tmp->getParent()) { | |
24967 | Class *clasp = tmp->getClass(); | |
24968 | if (clasp == &js_BlockClass || clasp == &js_WithClass) | |
24969 | continue; | |
24970 | if (!tmp->getProperty(cx, ((jsid)0x6), Valueify(&v))) | |
24971 | return (JSIntn)0; | |
24972 | if (!JSVAL_IS_PRIMITIVE(v)) { | |
24973 | *vp = v; | |
24974 | return (JSIntn)1; | |
24975 | } | |
24976 | obj = tmp; | |
24977 | } | |
24978 | ns = js_ConstructObject(cx, &js_NamespaceClass, __null, obj, 0, __null); | |
24979 | if (!ns) | |
24980 | return (JSIntn)0; | |
24981 | v = OBJECT_TO_JSVAL(ns); | |
24982 | if (!obj->defineProperty(cx, ((jsid)0x6), Valueify(v), | |
24983 | PropertyStub, StrictPropertyStub, 0x04)) { | |
24984 | return (JSIntn)0; | |
24985 | } | |
24986 | *vp = v; | |
24987 | return (JSIntn)1; | |
24988 | } | |
24989 | JSBool | |
24990 | js_SetDefaultXMLNamespace(JSContext *cx, const Value &v) | |
24991 | { | |
24992 | Value argv[2]; | |
24993 | argv[0].setString(cx->runtime->emptyString); | |
24994 | argv[1] = v; | |
24995 | JSObject *ns = js_ConstructObject(cx, &js_NamespaceClass, __null, __null, 2, argv); | |
24996 | if (!ns) | |
24997 | return (JSIntn)0; | |
24998 | JSStackFrame *fp = js_GetTopStackFrame(cx); | |
24999 | JSObject &varobj = fp->varobj(cx); | |
25000 | if (!varobj.defineProperty(cx, ((jsid)0x6), ObjectValue(*ns), | |
25001 | PropertyStub, StrictPropertyStub, 0x04)) { | |
25002 | return (JSIntn)0; | |
25003 | } | |
25004 | return (JSIntn)1; | |
25005 | } | |
25006 | JSBool | |
25007 | js_ToAttributeName(JSContext *cx, Value *vp) | |
25008 | { | |
25009 | JSObject *qn; | |
25010 | qn = ToAttributeName(cx, Jsvalify(*vp)); | |
25011 | if (!qn) | |
25012 | return (JSIntn)0; | |
25013 | vp->setObject(*qn); | |
25014 | return (JSIntn)1; | |
25015 | } | |
25016 | JSFlatString * | |
25017 | js_EscapeAttributeValue(JSContext *cx, JSString *str, JSBool quote) | |
25018 | { | |
25019 | StringBuffer sb(cx); | |
25020 | return EscapeAttributeValue(cx, sb, str, quote); | |
25021 | } | |
25022 | JSString * | |
25023 | js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, JSString *str2) | |
25024 | { | |
25025 | size_t len = str->length(); | |
25026 | const jschar *chars = str->getChars(cx); | |
25027 | if (!chars) | |
25028 | return __null; | |
25029 | size_t len2 = str2->length(); | |
25030 | const jschar *chars2 = str2->getChars(cx); | |
25031 | if (!chars2) | |
25032 | return __null; | |
25033 | size_t newlen = (isName) ? len + 1 + len2 : len + 2 + len2 + 1; | |
25034 | jschar *newchars = (jschar *) cx->malloc((newlen+1) * sizeof(jschar)); | |
25035 | if (!newchars) | |
25036 | return __null; | |
25037 | memcpy((newchars), (chars), (len) * sizeof(jschar)); | |
25038 | newchars += len; | |
25039 | if (isName) { | |
25040 | *newchars++ = ' '; | |
25041 | memcpy((newchars), (chars2), (len2) * sizeof(jschar)); | |
25042 | newchars += len2; | |
25043 | } else { | |
25044 | *newchars++ = '='; | |
25045 | *newchars++ = '"'; | |
25046 | memcpy((newchars), (chars2), (len2) * sizeof(jschar)); | |
25047 | newchars += len2; | |
25048 | *newchars++ = '"'; | |
25049 | } | |
25050 | *newchars = 0; | |
25051 | return js_NewString(cx, newchars - newlen, newlen); | |
25052 | } | |
25053 | JSFlatString * | |
25054 | js_EscapeElementValue(JSContext *cx, JSString *str) | |
25055 | { | |
25056 | StringBuffer sb(cx); | |
25057 | return EscapeElementValue(cx, sb, str, 0); | |
25058 | } | |
25059 | JSString * | |
25060 | js_ValueToXMLString(JSContext *cx, const Value &v) | |
25061 | { | |
25062 | return ToXMLString(cx, Jsvalify(v), 0); | |
25063 | } | |
25064 | JSBool | |
25065 | js_GetAnyName(JSContext *cx, jsid *idp) | |
25066 | { | |
25067 | JSObject *global = cx->hasfp() ? cx->fp()->scopeChain().getGlobal() : cx->globalObject; | |
25068 | Value v = global->getReservedSlot(JSProto_AnyName); | |
25069 | if (v.isUndefined()) { | |
25070 | JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AnyNameClass, __null, global); | |
25071 | if (!obj) | |
25072 | return false; | |
25073 | ((void) 0); | |
25074 | JSRuntime *rt = cx->runtime; | |
25075 | InitXMLQName(obj, rt->emptyString, rt->emptyString, | |
25076 | (rt->atomState.starAtom)); | |
25077 | ; | |
25078 | v.setObject(*obj); | |
25079 | if (!js_SetReservedSlot(cx, global, JSProto_AnyName, v)) | |
25080 | return false; | |
25081 | } | |
25082 | *idp = OBJECT_TO_JSID(&v.toObject()); | |
25083 | return true; | |
25084 | } | |
25085 | JSBool | |
25086 | js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *idp) | |
25087 | { | |
25088 | JSObject *nameobj; | |
25089 | jsval v; | |
25090 | JSObject *qn; | |
25091 | jsid funid; | |
25092 | JSObject *obj, *target, *proto, *pobj; | |
25093 | JSXML *xml; | |
25094 | JSBool found; | |
25095 | JSProperty *prop; | |
25096 | ((void) 0); | |
25097 | nameobj = &nameval.toObject(); | |
25098 | if (nameobj->getClass() == &js_AnyNameClass) { | |
25099 | v = STRING_TO_JSVAL((cx->runtime->atomState.starAtom)); | |
25100 | nameobj = js_ConstructObject(cx, &js_QNameClass, __null, __null, 1, | |
25101 | Valueify(&v)); | |
25102 | if (!nameobj) | |
25103 | return (JSIntn)0; | |
25104 | } else { | |
25105 | ((void) 0) | |
25106 | ; | |
25107 | } | |
25108 | qn = nameobj; | |
25109 | if (!IsFunctionQName(cx, qn, &funid)) | |
25110 | return (JSIntn)0; | |
25111 | obj = &js_GetTopStackFrame(cx)->scopeChain(); | |
25112 | do { | |
25113 | target = obj; | |
25114 | while (target->getClass() == &js_WithClass) { | |
25115 | proto = target->getProto(); | |
25116 | if (!proto) | |
25117 | break; | |
25118 | target = proto; | |
25119 | } | |
25120 | if (target->isXML()) { | |
25121 | if (JSID_IS_VOID(funid)) { | |
25122 | xml = (JSXML *) target->getPrivate(); | |
25123 | found = HasNamedProperty(xml, qn); | |
25124 | } else { | |
25125 | if (!HasFunctionProperty(cx, target, funid, &found)) | |
25126 | return (JSIntn)0; | |
25127 | } | |
25128 | if (found) { | |
25129 | *idp = OBJECT_TO_JSID(nameobj); | |
25130 | *objp = target; | |
25131 | return (JSIntn)1; | |
25132 | } | |
25133 | } else if (!JSID_IS_VOID(funid)) { | |
25134 | if (!target->lookupProperty(cx, funid, &pobj, &prop)) | |
25135 | return (JSIntn)0; | |
25136 | if (prop) { | |
25137 | *idp = funid; | |
25138 | *objp = target; | |
25139 | return (JSIntn)1; | |
25140 | } | |
25141 | } | |
25142 | } while ((obj = obj->getParent()) != __null); | |
25143 | JSAutoByteString printable; | |
25144 | JSString *str = ConvertQNameToString(cx, nameobj); | |
25145 | if (str && js_ValueToPrintable(cx, StringValue(str), &printable)) { | |
25146 | JS_ReportErrorFlagsAndNumber(cx, 0x0, js_GetErrorMessage, __null, | |
25147 | JSMSG_UNDEFINED_XML_NAME, printable.ptr()); | |
25148 | } | |
25149 | return (JSIntn)0; | |
25150 | } | |
25151 | static JSBool | |
25152 | GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp) | |
25153 | { | |
25154 | ((void) 0); | |
25155 | JSObject *target = obj; | |
25156 | AutoObjectRooter tvr(cx); | |
25157 | for (;;) { | |
25158 | if (!js_GetProperty(cx, target, id, Valueify(vp))) | |
25159 | return false; | |
25160 | if ((!JSVAL_IS_PRIMITIVE(*vp) && JSVAL_TO_OBJECT(*vp)->isFunction())) | |
25161 | return true; | |
25162 | target = target->getProto(); | |
25163 | if (target == __null || !target->isNative()) | |
25164 | break; | |
25165 | tvr.setObject(target); | |
25166 | } | |
25167 | JSXML *xml = (JSXML *) obj->getPrivate(); | |
25168 | if (!HasSimpleContent(xml)) | |
25169 | return true; | |
25170 | if (!js_GetClassPrototype(cx, __null, JSProto_String, tvr.addr())) | |
25171 | return false; | |
25172 | ((void) 0); | |
25173 | return tvr.object()->getProperty(cx, id, Valueify(vp)); | |
25174 | } | |
25175 | static JSXML * | |
25176 | GetPrivate(JSContext *cx, JSObject *obj, const char *method) | |
25177 | { | |
25178 | JSXML *xml; | |
25179 | xml = (JSXML *) GetInstancePrivate(cx, obj, &js_XMLClass, __null); | |
25180 | if (!xml) { | |
25181 | JS_ReportErrorNumber(cx, js_GetErrorMessage, __null, | |
25182 | JSMSG_INCOMPATIBLE_METHOD, | |
25183 | js_XML_str, method, obj->getClass()->name); | |
25184 | } | |
25185 | return xml; | |
25186 | } | |
25187 | JSBool | |
25188 | js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp) | |
25189 | { | |
25190 | JSXML *xml, *list; | |
25191 | xml = GetPrivate(cx, obj, "descendants internal method"); | |
25192 | if (!xml) | |
25193 | return (JSIntn)0; | |
25194 | list = Descendants(cx, xml, id); | |
25195 | if (!list) | |
25196 | return (JSIntn)0; | |
25197 | *vp = OBJECT_TO_JSVAL(list->object); | |
25198 | return (JSIntn)1; | |
25199 | } | |
25200 | JSBool | |
25201 | js_DeleteXMLListElements(JSContext *cx, JSObject *listobj) | |
25202 | { | |
25203 | JSXML *list; | |
25204 | uint32 n; | |
25205 | list = (JSXML *) listobj->getPrivate(); | |
25206 | for (n = list->u.list.kids.length; n != 0; --n) | |
25207 | DeleteListElement(cx, list, 0); | |
25208 | return (JSIntn)1; | |
25209 | } | |
25210 | struct JSXMLFilter | |
25211 | { | |
25212 | JSXML *list; | |
25213 | JSXML *result; | |
25214 | JSXML *kid; | |
25215 | JSXMLArrayCursor cursor; | |
25216 | JSXMLFilter(JSXML *list, JSXMLArray *array) | |
25217 | : list(list), result(__null), kid(__null), cursor(array) {} | |
25218 | ~JSXMLFilter() {} | |
25219 | }; | |
25220 | static void | |
25221 | xmlfilter_trace(JSTracer *trc, JSObject *obj) | |
25222 | { | |
25223 | JSXMLFilter *filter = (JSXMLFilter *) obj->getPrivate(); | |
25224 | if (!filter) | |
25225 | return; | |
25226 | ((void) 0); | |
25227 | do { do { } while (0); JS_CallTracer((trc), (filter->list), (2)); } while (0); | |
25228 | if (filter->result) | |
25229 | do { do { } while (0); JS_CallTracer((trc), (filter->result), (2)); } while (0); | |
25230 | if (filter->kid) | |
25231 | do { do { } while (0); JS_CallTracer((trc), (filter->kid), (2)); } while (0); | |
25232 | } | |
25233 | static void | |
25234 | xmlfilter_finalize(JSContext *cx, JSObject *obj) | |
25235 | { | |
25236 | JSXMLFilter *filter = (JSXMLFilter *) obj->getPrivate(); | |
25237 | if (!filter) | |
25238 | return; | |
25239 | cx->destroy(filter); | |
25240 | } | |
25241 | Class js_XMLFilterClass = { | |
25242 | "XMLFilter", | |
25243 | (1<<0) | (1<<((8 + 8)+1)) | (1<<((8 + 8)+3)), | |
25244 | PropertyStub, | |
25245 | PropertyStub, | |
25246 | PropertyStub, | |
25247 | StrictPropertyStub, | |
25248 | EnumerateStub, | |
25249 | ResolveStub, | |
25250 | ConvertStub, | |
25251 | xmlfilter_finalize, | |
25252 | __null, | |
25253 | __null, | |
25254 | __null, | |
25255 | __null, | |
25256 | __null, | |
25257 | __null, | |
25258 | ((JSMarkOp)(xmlfilter_trace)) | |
25259 | }; | |
25260 | JSBool | |
25261 | js_StepXMLListFilter(JSContext *cx, JSBool initialized) | |
25262 | { | |
25263 | jsval *sp; | |
25264 | JSObject *obj, *filterobj, *resobj, *kidobj; | |
25265 | JSXML *xml, *list; | |
25266 | JSXMLFilter *filter; | |
25267 | LeaveTrace(cx); | |
25268 | sp = Jsvalify(cx->regs->sp); | |
25269 | if (!initialized) { | |
25270 | if (!(!JSVAL_IS_PRIMITIVE(sp[-2]) && JSVAL_TO_OBJECT(sp[-2])->isXML())) { | |
25271 | ((void)js_ReportValueErrorFlags(cx, 0x0, JSMSG_NON_XML_FILTER, -2, Valueify(sp[-2]), __null, __null, __null)); | |
25272 | return (JSIntn)0; | |
25273 | } | |
25274 | obj = JSVAL_TO_OBJECT(sp[-2]); | |
25275 | xml = (JSXML *) obj->getPrivate(); | |
25276 | if (xml->xml_class == JSXML_CLASS_LIST) { | |
25277 | list = xml; | |
25278 | } else { | |
25279 | obj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
25280 | if (!obj) | |
25281 | return (JSIntn)0; | |
25282 | sp[-1] = OBJECT_TO_JSVAL(obj); | |
25283 | list = (JSXML *) obj->getPrivate(); | |
25284 | if (!Append(cx, list, xml)) | |
25285 | return (JSIntn)0; | |
25286 | } | |
25287 | filterobj = NewNonFunction<WithProto::Given>(cx, &js_XMLFilterClass, __null, __null); | |
25288 | if (!filterobj) | |
25289 | return (JSIntn)0; | |
25290 | filter = cx->create<JSXMLFilter>(list, &list->u.list.kids); | |
25291 | if (!filter) | |
25292 | return (JSIntn)0; | |
25293 | filterobj->setPrivate(filter); | |
25294 | sp[-2] = OBJECT_TO_JSVAL(filterobj); | |
25295 | resobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); | |
25296 | if (!resobj) | |
25297 | return (JSIntn)0; | |
25298 | filter->result = (JSXML *) resobj->getPrivate(); | |
25299 | } else { | |
25300 | ((void) 0); | |
25301 | ((void) 0); | |
25302 | filter = (JSXMLFilter *) JSVAL_TO_OBJECT(sp[-2])->getPrivate(); | |
25303 | ((void) 0); | |
25304 | if (js_ValueToBoolean(Valueify(sp[-1])) && | |
25305 | !Append(cx, filter->result, filter->kid)) { | |
25306 | return (JSIntn)0; | |
25307 | } | |
25308 | } | |
25309 | filter->kid = (JSXML *) filter->cursor.getNext(); | |
25310 | if (!filter->kid) { | |
25311 | filter->cursor.disconnect(); | |
25312 | ((void) 0); | |
25313 | sp[-2] = OBJECT_TO_JSVAL(filter->result->object); | |
25314 | kidobj = __null; | |
25315 | } else { | |
25316 | kidobj = js_GetXMLObject(cx, filter->kid); | |
25317 | if (!kidobj) | |
25318 | return (JSIntn)0; | |
25319 | } | |
25320 | sp[-1] = OBJECT_TO_JSVAL(kidobj); | |
25321 | return (JSIntn)1; | |
25322 | } | |
25323 | JSObject * | |
25324 | js_ValueToXMLObject(JSContext *cx, const Value &v) | |
25325 | { | |
25326 | return ToXML(cx, Jsvalify(v)); | |
25327 | } | |
25328 | JSObject * | |
25329 | js_ValueToXMLListObject(JSContext *cx, const Value &v) | |
25330 | { | |
25331 | return ToXMLList(cx, Jsvalify(v)); | |
25332 | } | |
25333 | JSObject * | |
25334 | js_NewXMLSpecialObject(JSContext *cx, JSXMLClass xml_class, JSString *name, | |
25335 | JSString *value) | |
25336 | { | |
25337 | uintN flags; | |
25338 | JSObject *obj; | |
25339 | JSXML *xml; | |
25340 | JSObject *qn; | |
25341 | if (!GetXMLSettingFlags(cx, &flags)) | |
25342 | return __null; | |
25343 | if ((xml_class == JSXML_CLASS_COMMENT && | |
25344 | (flags & ((JSUint32)1 << (0)))) || | |
25345 | (xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION && | |
25346 | (flags & ((JSUint32)1 << (1))))) { | |
25347 | return js_NewXMLObject(cx, JSXML_CLASS_TEXT); | |
25348 | } | |
25349 | obj = js_NewXMLObject(cx, xml_class); | |
25350 | if (!obj) | |
25351 | return __null; | |
25352 | xml = (JSXML *) obj->getPrivate(); | |
25353 | if (name) { | |
25354 | JSLinearString *linearName = name->ensureLinear(cx); | |
25355 | if (!linearName) | |
25356 | return __null; | |
25357 | qn = NewXMLQName(cx, cx->runtime->emptyString, __null, linearName); | |
25358 | if (!qn) | |
25359 | return __null; | |
25360 | xml->name = qn; | |
25361 | } | |
25362 | xml->u.value = value; | |
25363 | return obj; | |
25364 | } | |
25365 | JSString * | |
25366 | js_MakeXMLCDATAString(JSContext *cx, JSString *str) | |
25367 | { | |
25368 | StringBuffer sb(cx); | |
25369 | return MakeXMLCDATAString(cx, sb, str); | |
25370 | } | |
25371 | JSString * | |
25372 | js_MakeXMLCommentString(JSContext *cx, JSString *str) | |
25373 | { | |
25374 | StringBuffer sb(cx); | |
25375 | return MakeXMLCommentString(cx, sb, str); | |
25376 | } | |
25377 | JSString * | |
25378 | js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str) | |
25379 | { | |
25380 | StringBuffer sb(cx); | |
25381 | return MakeXMLPIString(cx, sb, name, str); | |
25382 | } |