johnson 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (311) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/Manifest.txt +4 -285
  3. data/Rakefile +13 -20
  4. data/ext/tracemonkey/global.cc +4 -1
  5. data/ext/tracemonkey/js.cc +30 -33
  6. data/ext/tracemonkey/runtime.cc +96 -6
  7. data/ext/tracemonkey/split_global.cc +0 -5
  8. data/ext/tracemonkey/tracemonkey.h +2 -2
  9. data/lib/johnson.rb +2 -2
  10. data/lib/johnson/runtime.rb +25 -15
  11. data/lib/johnson/tracemonkey/runtime.rb +6 -3
  12. data/vendor/tracemonkey/config/system-headers +1 -3
  13. data/vendor/tracemonkey/jscntxt.h +5 -2
  14. data/vendor/tracemonkey/jsdbgapi.cpp +9 -1
  15. data/vendor/tracemonkey/jsdbgapi.h +4 -0
  16. data/vendor/tracemonkey/tests/ecma/NativeObjects/browser.js +0 -0
  17. data/vendor/tracemonkey/tests/ecma/NativeObjects/jstests.list +0 -0
  18. data/vendor/tracemonkey/tests/ecma_3_1/Object/jstests.list +1 -1
  19. data/vendor/tracemonkey/tests/js1_3/misc/browser.js +0 -0
  20. data/vendor/tracemonkey/tests/js1_3/misc/jstests.list +0 -0
  21. data/vendor/tracemonkey/tests/js1_5/Regress/jstests.list +4 -4
  22. data/vendor/tracemonkey/tests/js1_5/Scope/jstests.list +1 -1
  23. data/vendor/tracemonkey/tests/js1_5/decompilation/jstests.list +2 -2
  24. data/vendor/tracemonkey/tests/js1_7/decompilation/jstests.list +1 -1
  25. data/vendor/tracemonkey/tests/shell.js +2 -1
  26. metadata +51 -309
  27. data/ext/spidermonkey/context.c +0 -116
  28. data/ext/spidermonkey/context.h +0 -19
  29. data/ext/spidermonkey/conversions.c +0 -361
  30. data/ext/spidermonkey/conversions.h +0 -31
  31. data/ext/spidermonkey/debugger.c +0 -234
  32. data/ext/spidermonkey/debugger.h +0 -10
  33. data/ext/spidermonkey/extconf.rb +0 -32
  34. data/ext/spidermonkey/extensions.c +0 -37
  35. data/ext/spidermonkey/extensions.h +0 -12
  36. data/ext/spidermonkey/global.c +0 -40
  37. data/ext/spidermonkey/global.h +0 -11
  38. data/ext/spidermonkey/idhash.c +0 -16
  39. data/ext/spidermonkey/idhash.h +0 -8
  40. data/ext/spidermonkey/immutable_node.c +0 -1153
  41. data/ext/spidermonkey/immutable_node.c.erb +0 -523
  42. data/ext/spidermonkey/immutable_node.h +0 -22
  43. data/ext/spidermonkey/jroot.h +0 -197
  44. data/ext/spidermonkey/js_land_proxy.c +0 -620
  45. data/ext/spidermonkey/js_land_proxy.h +0 -20
  46. data/ext/spidermonkey/ruby_land_proxy.c +0 -618
  47. data/ext/spidermonkey/ruby_land_proxy.h +0 -38
  48. data/ext/spidermonkey/runtime.c +0 -396
  49. data/ext/spidermonkey/runtime.h +0 -27
  50. data/ext/spidermonkey/spidermonkey.c +0 -22
  51. data/ext/spidermonkey/spidermonkey.h +0 -29
  52. data/lib/johnson/spidermonkey.rb +0 -12
  53. data/lib/johnson/spidermonkey/context.rb +0 -10
  54. data/lib/johnson/spidermonkey/debugger.rb +0 -67
  55. data/lib/johnson/spidermonkey/immutable_node.rb +0 -282
  56. data/lib/johnson/spidermonkey/js_land_proxy.rb +0 -64
  57. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +0 -242
  58. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +0 -17
  59. data/lib/johnson/spidermonkey/runtime.rb +0 -74
  60. data/test/johnson/spidermonkey/context_test.rb +0 -21
  61. data/test/johnson/spidermonkey/immutable_node_test.rb +0 -34
  62. data/test/johnson/spidermonkey/js_land_proxy_test.rb +0 -273
  63. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +0 -274
  64. data/test/johnson/spidermonkey/runtime_test.rb +0 -41
  65. data/vendor/spidermonkey/.cvsignore +0 -9
  66. data/vendor/spidermonkey/Makefile.in +0 -449
  67. data/vendor/spidermonkey/Makefile.ref +0 -365
  68. data/vendor/spidermonkey/README.html +0 -820
  69. data/vendor/spidermonkey/SpiderMonkey.rsp +0 -12
  70. data/vendor/spidermonkey/Y.js +0 -19
  71. data/vendor/spidermonkey/build.mk +0 -43
  72. data/vendor/spidermonkey/config.mk +0 -192
  73. data/vendor/spidermonkey/config/AIX4.1.mk +0 -65
  74. data/vendor/spidermonkey/config/AIX4.2.mk +0 -64
  75. data/vendor/spidermonkey/config/AIX4.3.mk +0 -65
  76. data/vendor/spidermonkey/config/Darwin.mk +0 -83
  77. data/vendor/spidermonkey/config/Darwin1.3.mk +0 -81
  78. data/vendor/spidermonkey/config/Darwin1.4.mk +0 -41
  79. data/vendor/spidermonkey/config/Darwin5.2.mk +0 -81
  80. data/vendor/spidermonkey/config/Darwin5.3.mk +0 -81
  81. data/vendor/spidermonkey/config/HP-UXB.10.10.mk +0 -77
  82. data/vendor/spidermonkey/config/HP-UXB.10.20.mk +0 -77
  83. data/vendor/spidermonkey/config/HP-UXB.11.00.mk +0 -80
  84. data/vendor/spidermonkey/config/IRIX.mk +0 -87
  85. data/vendor/spidermonkey/config/IRIX5.3.mk +0 -44
  86. data/vendor/spidermonkey/config/IRIX6.1.mk +0 -44
  87. data/vendor/spidermonkey/config/IRIX6.2.mk +0 -44
  88. data/vendor/spidermonkey/config/IRIX6.3.mk +0 -44
  89. data/vendor/spidermonkey/config/IRIX6.5.mk +0 -44
  90. data/vendor/spidermonkey/config/Linux_All.mk +0 -103
  91. data/vendor/spidermonkey/config/Mac_OS10.0.mk +0 -82
  92. data/vendor/spidermonkey/config/OSF1V4.0.mk +0 -72
  93. data/vendor/spidermonkey/config/OSF1V5.0.mk +0 -69
  94. data/vendor/spidermonkey/config/SunOS4.1.4.mk +0 -101
  95. data/vendor/spidermonkey/config/SunOS5.10.mk +0 -50
  96. data/vendor/spidermonkey/config/SunOS5.3.mk +0 -91
  97. data/vendor/spidermonkey/config/SunOS5.4.mk +0 -92
  98. data/vendor/spidermonkey/config/SunOS5.5.1.mk +0 -44
  99. data/vendor/spidermonkey/config/SunOS5.5.mk +0 -87
  100. data/vendor/spidermonkey/config/SunOS5.6.mk +0 -89
  101. data/vendor/spidermonkey/config/SunOS5.7.mk +0 -44
  102. data/vendor/spidermonkey/config/SunOS5.8.mk +0 -44
  103. data/vendor/spidermonkey/config/SunOS5.9.mk +0 -44
  104. data/vendor/spidermonkey/config/WINNT4.0.mk +0 -117
  105. data/vendor/spidermonkey/config/WINNT5.0.mk +0 -117
  106. data/vendor/spidermonkey/config/WINNT5.1.mk +0 -117
  107. data/vendor/spidermonkey/config/WINNT5.2.mk +0 -117
  108. data/vendor/spidermonkey/config/WINNT6.0.mk +0 -117
  109. data/vendor/spidermonkey/config/dgux.mk +0 -64
  110. data/vendor/spidermonkey/editline/Makefile.ref +0 -144
  111. data/vendor/spidermonkey/editline/README +0 -83
  112. data/vendor/spidermonkey/editline/editline.3 +0 -175
  113. data/vendor/spidermonkey/editline/editline.c +0 -1369
  114. data/vendor/spidermonkey/editline/editline.h +0 -135
  115. data/vendor/spidermonkey/editline/sysunix.c +0 -182
  116. data/vendor/spidermonkey/editline/unix.h +0 -82
  117. data/vendor/spidermonkey/fdlibm/.cvsignore +0 -7
  118. data/vendor/spidermonkey/fdlibm/Makefile.in +0 -127
  119. data/vendor/spidermonkey/fdlibm/Makefile.ref +0 -192
  120. data/vendor/spidermonkey/fdlibm/e_acos.c +0 -147
  121. data/vendor/spidermonkey/fdlibm/e_acosh.c +0 -105
  122. data/vendor/spidermonkey/fdlibm/e_asin.c +0 -156
  123. data/vendor/spidermonkey/fdlibm/e_atan2.c +0 -165
  124. data/vendor/spidermonkey/fdlibm/e_atanh.c +0 -110
  125. data/vendor/spidermonkey/fdlibm/e_cosh.c +0 -133
  126. data/vendor/spidermonkey/fdlibm/e_exp.c +0 -202
  127. data/vendor/spidermonkey/fdlibm/e_fmod.c +0 -184
  128. data/vendor/spidermonkey/fdlibm/e_gamma.c +0 -71
  129. data/vendor/spidermonkey/fdlibm/e_gamma_r.c +0 -70
  130. data/vendor/spidermonkey/fdlibm/e_hypot.c +0 -173
  131. data/vendor/spidermonkey/fdlibm/e_j0.c +0 -524
  132. data/vendor/spidermonkey/fdlibm/e_j1.c +0 -523
  133. data/vendor/spidermonkey/fdlibm/e_jn.c +0 -315
  134. data/vendor/spidermonkey/fdlibm/e_lgamma.c +0 -71
  135. data/vendor/spidermonkey/fdlibm/e_lgamma_r.c +0 -347
  136. data/vendor/spidermonkey/fdlibm/e_log.c +0 -184
  137. data/vendor/spidermonkey/fdlibm/e_log10.c +0 -134
  138. data/vendor/spidermonkey/fdlibm/e_pow.c +0 -386
  139. data/vendor/spidermonkey/fdlibm/e_rem_pio2.c +0 -222
  140. data/vendor/spidermonkey/fdlibm/e_remainder.c +0 -120
  141. data/vendor/spidermonkey/fdlibm/e_scalb.c +0 -89
  142. data/vendor/spidermonkey/fdlibm/e_sinh.c +0 -122
  143. data/vendor/spidermonkey/fdlibm/e_sqrt.c +0 -497
  144. data/vendor/spidermonkey/fdlibm/fdlibm.h +0 -273
  145. data/vendor/spidermonkey/fdlibm/fdlibm.mak +0 -1453
  146. data/vendor/spidermonkey/fdlibm/fdlibm.mdp +0 -0
  147. data/vendor/spidermonkey/fdlibm/k_cos.c +0 -135
  148. data/vendor/spidermonkey/fdlibm/k_rem_pio2.c +0 -354
  149. data/vendor/spidermonkey/fdlibm/k_sin.c +0 -114
  150. data/vendor/spidermonkey/fdlibm/k_standard.c +0 -785
  151. data/vendor/spidermonkey/fdlibm/k_tan.c +0 -170
  152. data/vendor/spidermonkey/fdlibm/s_asinh.c +0 -101
  153. data/vendor/spidermonkey/fdlibm/s_atan.c +0 -175
  154. data/vendor/spidermonkey/fdlibm/s_cbrt.c +0 -133
  155. data/vendor/spidermonkey/fdlibm/s_ceil.c +0 -120
  156. data/vendor/spidermonkey/fdlibm/s_copysign.c +0 -72
  157. data/vendor/spidermonkey/fdlibm/s_cos.c +0 -118
  158. data/vendor/spidermonkey/fdlibm/s_erf.c +0 -356
  159. data/vendor/spidermonkey/fdlibm/s_expm1.c +0 -267
  160. data/vendor/spidermonkey/fdlibm/s_fabs.c +0 -70
  161. data/vendor/spidermonkey/fdlibm/s_finite.c +0 -71
  162. data/vendor/spidermonkey/fdlibm/s_floor.c +0 -121
  163. data/vendor/spidermonkey/fdlibm/s_frexp.c +0 -99
  164. data/vendor/spidermonkey/fdlibm/s_ilogb.c +0 -85
  165. data/vendor/spidermonkey/fdlibm/s_isnan.c +0 -74
  166. data/vendor/spidermonkey/fdlibm/s_ldexp.c +0 -66
  167. data/vendor/spidermonkey/fdlibm/s_lib_version.c +0 -73
  168. data/vendor/spidermonkey/fdlibm/s_log1p.c +0 -211
  169. data/vendor/spidermonkey/fdlibm/s_logb.c +0 -79
  170. data/vendor/spidermonkey/fdlibm/s_matherr.c +0 -64
  171. data/vendor/spidermonkey/fdlibm/s_modf.c +0 -132
  172. data/vendor/spidermonkey/fdlibm/s_nextafter.c +0 -124
  173. data/vendor/spidermonkey/fdlibm/s_rint.c +0 -131
  174. data/vendor/spidermonkey/fdlibm/s_scalbn.c +0 -107
  175. data/vendor/spidermonkey/fdlibm/s_signgam.c +0 -40
  176. data/vendor/spidermonkey/fdlibm/s_significand.c +0 -68
  177. data/vendor/spidermonkey/fdlibm/s_sin.c +0 -118
  178. data/vendor/spidermonkey/fdlibm/s_tan.c +0 -112
  179. data/vendor/spidermonkey/fdlibm/s_tanh.c +0 -122
  180. data/vendor/spidermonkey/fdlibm/w_acos.c +0 -78
  181. data/vendor/spidermonkey/fdlibm/w_acosh.c +0 -78
  182. data/vendor/spidermonkey/fdlibm/w_asin.c +0 -80
  183. data/vendor/spidermonkey/fdlibm/w_atan2.c +0 -79
  184. data/vendor/spidermonkey/fdlibm/w_atanh.c +0 -81
  185. data/vendor/spidermonkey/fdlibm/w_cosh.c +0 -77
  186. data/vendor/spidermonkey/fdlibm/w_exp.c +0 -88
  187. data/vendor/spidermonkey/fdlibm/w_fmod.c +0 -78
  188. data/vendor/spidermonkey/fdlibm/w_gamma.c +0 -85
  189. data/vendor/spidermonkey/fdlibm/w_gamma_r.c +0 -81
  190. data/vendor/spidermonkey/fdlibm/w_hypot.c +0 -78
  191. data/vendor/spidermonkey/fdlibm/w_j0.c +0 -105
  192. data/vendor/spidermonkey/fdlibm/w_j1.c +0 -106
  193. data/vendor/spidermonkey/fdlibm/w_jn.c +0 -128
  194. data/vendor/spidermonkey/fdlibm/w_lgamma.c +0 -85
  195. data/vendor/spidermonkey/fdlibm/w_lgamma_r.c +0 -81
  196. data/vendor/spidermonkey/fdlibm/w_log.c +0 -78
  197. data/vendor/spidermonkey/fdlibm/w_log10.c +0 -81
  198. data/vendor/spidermonkey/fdlibm/w_pow.c +0 -99
  199. data/vendor/spidermonkey/fdlibm/w_remainder.c +0 -77
  200. data/vendor/spidermonkey/fdlibm/w_scalb.c +0 -95
  201. data/vendor/spidermonkey/fdlibm/w_sinh.c +0 -77
  202. data/vendor/spidermonkey/fdlibm/w_sqrt.c +0 -77
  203. data/vendor/spidermonkey/javascript-trace.d +0 -73
  204. data/vendor/spidermonkey/js.c +0 -3951
  205. data/vendor/spidermonkey/js.mdp +0 -0
  206. data/vendor/spidermonkey/js.msg +0 -308
  207. data/vendor/spidermonkey/js.pkg +0 -2
  208. data/vendor/spidermonkey/js3240.rc +0 -79
  209. data/vendor/spidermonkey/jsOS240.def +0 -654
  210. data/vendor/spidermonkey/jsapi.c +0 -5836
  211. data/vendor/spidermonkey/jsapi.h +0 -2624
  212. data/vendor/spidermonkey/jsarena.c +0 -450
  213. data/vendor/spidermonkey/jsarena.h +0 -318
  214. data/vendor/spidermonkey/jsarray.c +0 -2996
  215. data/vendor/spidermonkey/jsarray.h +0 -127
  216. data/vendor/spidermonkey/jsatom.c +0 -1045
  217. data/vendor/spidermonkey/jsatom.h +0 -442
  218. data/vendor/spidermonkey/jsbit.h +0 -253
  219. data/vendor/spidermonkey/jsbool.c +0 -176
  220. data/vendor/spidermonkey/jsbool.h +0 -73
  221. data/vendor/spidermonkey/jsclist.h +0 -139
  222. data/vendor/spidermonkey/jscntxt.c +0 -1348
  223. data/vendor/spidermonkey/jscntxt.h +0 -1120
  224. data/vendor/spidermonkey/jscompat.h +0 -57
  225. data/vendor/spidermonkey/jsconfig.h +0 -248
  226. data/vendor/spidermonkey/jsconfig.mk +0 -181
  227. data/vendor/spidermonkey/jscpucfg.c +0 -396
  228. data/vendor/spidermonkey/jscpucfg.h +0 -212
  229. data/vendor/spidermonkey/jsdate.c +0 -2390
  230. data/vendor/spidermonkey/jsdate.h +0 -124
  231. data/vendor/spidermonkey/jsdbgapi.c +0 -1802
  232. data/vendor/spidermonkey/jsdbgapi.h +0 -464
  233. data/vendor/spidermonkey/jsdhash.c +0 -868
  234. data/vendor/spidermonkey/jsdhash.h +0 -592
  235. data/vendor/spidermonkey/jsdtoa.c +0 -3167
  236. data/vendor/spidermonkey/jsdtoa.h +0 -130
  237. data/vendor/spidermonkey/jsdtracef.c +0 -317
  238. data/vendor/spidermonkey/jsdtracef.h +0 -77
  239. data/vendor/spidermonkey/jsemit.c +0 -6909
  240. data/vendor/spidermonkey/jsemit.h +0 -741
  241. data/vendor/spidermonkey/jsexn.c +0 -1371
  242. data/vendor/spidermonkey/jsexn.h +0 -96
  243. data/vendor/spidermonkey/jsfile.c +0 -2736
  244. data/vendor/spidermonkey/jsfile.h +0 -56
  245. data/vendor/spidermonkey/jsfile.msg +0 -90
  246. data/vendor/spidermonkey/jsfun.c +0 -2634
  247. data/vendor/spidermonkey/jsfun.h +0 -254
  248. data/vendor/spidermonkey/jsgc.c +0 -3562
  249. data/vendor/spidermonkey/jsgc.h +0 -403
  250. data/vendor/spidermonkey/jshash.c +0 -476
  251. data/vendor/spidermonkey/jshash.h +0 -151
  252. data/vendor/spidermonkey/jsify.pl +0 -485
  253. data/vendor/spidermonkey/jsinterp.c +0 -7007
  254. data/vendor/spidermonkey/jsinterp.h +0 -525
  255. data/vendor/spidermonkey/jsinvoke.c +0 -43
  256. data/vendor/spidermonkey/jsiter.c +0 -1067
  257. data/vendor/spidermonkey/jsiter.h +0 -122
  258. data/vendor/spidermonkey/jskeyword.tbl +0 -124
  259. data/vendor/spidermonkey/jskwgen.c +0 -460
  260. data/vendor/spidermonkey/jslibmath.h +0 -266
  261. data/vendor/spidermonkey/jslock.c +0 -1309
  262. data/vendor/spidermonkey/jslock.h +0 -313
  263. data/vendor/spidermonkey/jslocko.asm +0 -60
  264. data/vendor/spidermonkey/jslog2.c +0 -94
  265. data/vendor/spidermonkey/jslong.c +0 -264
  266. data/vendor/spidermonkey/jslong.h +0 -412
  267. data/vendor/spidermonkey/jsmath.c +0 -567
  268. data/vendor/spidermonkey/jsmath.h +0 -57
  269. data/vendor/spidermonkey/jsnum.c +0 -1239
  270. data/vendor/spidermonkey/jsnum.h +0 -283
  271. data/vendor/spidermonkey/jsobj.c +0 -5282
  272. data/vendor/spidermonkey/jsobj.h +0 -709
  273. data/vendor/spidermonkey/jsopcode.c +0 -5245
  274. data/vendor/spidermonkey/jsopcode.h +0 -394
  275. data/vendor/spidermonkey/jsopcode.tbl +0 -523
  276. data/vendor/spidermonkey/jsotypes.h +0 -202
  277. data/vendor/spidermonkey/jsparse.c +0 -6704
  278. data/vendor/spidermonkey/jsparse.h +0 -511
  279. data/vendor/spidermonkey/jsprf.c +0 -1264
  280. data/vendor/spidermonkey/jsprf.h +0 -150
  281. data/vendor/spidermonkey/jsproto.tbl +0 -128
  282. data/vendor/spidermonkey/jsprvtd.h +0 -267
  283. data/vendor/spidermonkey/jspubtd.h +0 -744
  284. data/vendor/spidermonkey/jsregexp.c +0 -4364
  285. data/vendor/spidermonkey/jsregexp.h +0 -183
  286. data/vendor/spidermonkey/jsreops.tbl +0 -145
  287. data/vendor/spidermonkey/jsscan.c +0 -2012
  288. data/vendor/spidermonkey/jsscan.h +0 -387
  289. data/vendor/spidermonkey/jsscope.c +0 -1957
  290. data/vendor/spidermonkey/jsscope.h +0 -418
  291. data/vendor/spidermonkey/jsscript.c +0 -1832
  292. data/vendor/spidermonkey/jsscript.h +0 -287
  293. data/vendor/spidermonkey/jsshell.msg +0 -50
  294. data/vendor/spidermonkey/jsstddef.h +0 -83
  295. data/vendor/spidermonkey/jsstr.c +0 -5005
  296. data/vendor/spidermonkey/jsstr.h +0 -641
  297. data/vendor/spidermonkey/jstypes.h +0 -475
  298. data/vendor/spidermonkey/jsutil.c +0 -345
  299. data/vendor/spidermonkey/jsutil.h +0 -157
  300. data/vendor/spidermonkey/jsxdrapi.c +0 -800
  301. data/vendor/spidermonkey/jsxdrapi.h +0 -218
  302. data/vendor/spidermonkey/jsxml.c +0 -8476
  303. data/vendor/spidermonkey/jsxml.h +0 -349
  304. data/vendor/spidermonkey/lock_SunOS.s +0 -119
  305. data/vendor/spidermonkey/perfect.js +0 -39
  306. data/vendor/spidermonkey/plify_jsdhash.sed +0 -36
  307. data/vendor/spidermonkey/prmjtime.c +0 -846
  308. data/vendor/spidermonkey/prmjtime.h +0 -103
  309. data/vendor/spidermonkey/resource.h +0 -15
  310. data/vendor/spidermonkey/rules.mk +0 -197
  311. data/vendor/spidermonkey/win32.order +0 -384
@@ -1,183 +0,0 @@
1
- /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
- *
3
- * ***** BEGIN LICENSE BLOCK *****
4
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
- *
6
- * The contents of this file are subject to the Mozilla Public License Version
7
- * 1.1 (the "License"); you may not use this file except in compliance with
8
- * the License. You may obtain a copy of the License at
9
- * http://www.mozilla.org/MPL/
10
- *
11
- * Software distributed under the License is distributed on an "AS IS" basis,
12
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
- * for the specific language governing rights and limitations under the
14
- * License.
15
- *
16
- * The Original Code is Mozilla Communicator client code, released
17
- * March 31, 1998.
18
- *
19
- * The Initial Developer of the Original Code is
20
- * Netscape Communications Corporation.
21
- * Portions created by the Initial Developer are Copyright (C) 1998
22
- * the Initial Developer. All Rights Reserved.
23
- *
24
- * Contributor(s):
25
- *
26
- * Alternatively, the contents of this file may be used under the terms of
27
- * either of the GNU General Public License Version 2 or later (the "GPL"),
28
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
- * in which case the provisions of the GPL or the LGPL are applicable instead
30
- * of those above. If you wish to allow use of your version of this file only
31
- * under the terms of either the GPL or the LGPL, and not to allow others to
32
- * use your version of this file under the terms of the MPL, indicate your
33
- * decision by deleting the provisions above and replace them with the notice
34
- * and other provisions required by the GPL or the LGPL. If you do not delete
35
- * the provisions above, a recipient may use your version of this file under
36
- * the terms of any one of the MPL, the GPL or the LGPL.
37
- *
38
- * ***** END LICENSE BLOCK ***** */
39
-
40
- #ifndef jsregexp_h___
41
- #define jsregexp_h___
42
- /*
43
- * JS regular expression interface.
44
- */
45
- #include <stddef.h>
46
- #include "jspubtd.h"
47
- #include "jsstr.h"
48
-
49
- #ifdef JS_THREADSAFE
50
- #include "jsdhash.h"
51
- #endif
52
-
53
- JS_BEGIN_EXTERN_C
54
-
55
- struct JSRegExpStatics {
56
- JSString *input; /* input string to match (perl $_, GC root) */
57
- JSBool multiline; /* whether input contains newlines (perl $*) */
58
- uint16 parenCount; /* number of valid elements in parens[] */
59
- uint16 moreLength; /* number of allocated elements in moreParens */
60
- JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */
61
- JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */
62
- JSSubString lastMatch; /* last string matched (perl $&) */
63
- JSSubString lastParen; /* last paren matched (perl $+) */
64
- JSSubString leftContext; /* input to left of last match (perl $`) */
65
- JSSubString rightContext; /* input to right of last match (perl $') */
66
- };
67
-
68
- /*
69
- * This struct holds a bitmap representation of a class from a regexp.
70
- * There's a list of these referenced by the classList field in the JSRegExp
71
- * struct below. The initial state has startIndex set to the offset in the
72
- * original regexp source of the beginning of the class contents. The first
73
- * use of the class converts the source representation into a bitmap.
74
- *
75
- */
76
- typedef struct RECharSet {
77
- JSPackedBool converted;
78
- JSPackedBool sense;
79
- uint16 length;
80
- union {
81
- uint8 *bits;
82
- struct {
83
- size_t startIndex;
84
- size_t length;
85
- } src;
86
- } u;
87
- } RECharSet;
88
-
89
- /*
90
- * This macro is safe because moreParens is guaranteed to be allocated and big
91
- * enough to hold parenCount, or else be null when parenCount is 0.
92
- */
93
- #define REGEXP_PAREN_SUBSTRING(res, num) \
94
- (((jsuint)(num) < (jsuint)(res)->parenCount) \
95
- ? ((jsuint)(num) < 9) \
96
- ? &(res)->parens[num] \
97
- : &(res)->moreParens[(num) - 9] \
98
- : &js_EmptySubString)
99
-
100
- typedef struct RENode RENode;
101
-
102
- struct JSRegExp {
103
- jsrefcount nrefs; /* reference count */
104
- uint16 flags; /* flags, see jsapi.h's JSREG_* defines */
105
- size_t parenCount; /* number of parenthesized submatches */
106
- size_t classCount; /* count [...] bitmaps */
107
- RECharSet *classList; /* list of [...] bitmaps */
108
- JSString *source; /* locked source string, sans // */
109
- jsbytecode program[1]; /* regular expression bytecode */
110
- };
111
-
112
- extern JSRegExp *
113
- js_NewRegExp(JSContext *cx, JSTokenStream *ts,
114
- JSString *str, uintN flags, JSBool flat);
115
-
116
- extern JSRegExp *
117
- js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt, JSBool flat);
118
-
119
- #define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
120
- #define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
121
-
122
- extern void
123
- js_DestroyRegExp(JSContext *cx, JSRegExp *re);
124
-
125
- /*
126
- * Execute re on input str at *indexp, returning null in *rval on mismatch.
127
- * On match, return true if test is true, otherwise return an array object.
128
- * Update *indexp and cx->regExpStatics always on match.
129
- */
130
- extern JSBool
131
- js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
132
- JSBool test, jsval *rval);
133
-
134
- /*
135
- * These two add and remove GC roots, respectively, so their calls must be
136
- * well-ordered.
137
- */
138
- extern JSBool
139
- js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res);
140
-
141
- extern void
142
- js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res);
143
-
144
- #define JSVAL_IS_REGEXP(cx, v) \
145
- (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \
146
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass)
147
-
148
- extern JSClass js_RegExpClass;
149
-
150
- extern JSObject *
151
- js_InitRegExpClass(JSContext *cx, JSObject *obj);
152
-
153
- /*
154
- * Export js_regexp_toString to the decompiler.
155
- */
156
- extern JSBool
157
- js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp);
158
-
159
- /*
160
- * Create, serialize/deserialize, or clone a RegExp object.
161
- */
162
- extern JSObject *
163
- js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
164
- jschar *chars, size_t length, uintN flags);
165
-
166
- extern JSBool
167
- js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
168
-
169
- extern JSObject *
170
- js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent);
171
-
172
- /*
173
- * Get and set the per-object (clone or clone-parent) lastIndex slot.
174
- */
175
- extern JSBool
176
- js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex);
177
-
178
- extern JSBool
179
- js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex);
180
-
181
- JS_END_EXTERN_C
182
-
183
- #endif /* jsregexp_h___ */
@@ -1,145 +0,0 @@
1
- /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
- * vim: set ts=8 sw=4 et tw=0 ft=C:
3
- *
4
- * ***** BEGIN LICENSE BLOCK *****
5
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
- *
7
- * The contents of this file are subject to the Mozilla Public License Version
8
- * 1.1 (the "license"); you may not use this file except in compliance with
9
- * the License. You may obtain a copy of the License at
10
- * http://www.mozilla.org/MPL/
11
- *
12
- * Software distributed under the License is distributed on an "as is" basis,
13
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
- * for the specific language governing rights and limitations under the
15
- * License.
16
- *
17
- * The Original Code is Mozilla Communicator client code, released
18
- * March 31, 1998.
19
- *
20
- * The Initial Developer of the Original Code is
21
- * Netscape Communications Corporation.
22
- * Portions created by the Initial Developer are Copyright (C) 1998
23
- * the Initial Developer. All Rights Reserved.
24
- *
25
- * Contributor(s):
26
- *
27
- * Alternatively, the contentsof this file are subject to the Mozilla Public License Version
28
- * 1.1 (the "license"); you may not use this file except in compliance with
29
- * the License. You may obtain a copy of thter (the "lgpl"),
30
- * in which case the provisions of the GPL or the LGPL are applicable instead
31
- * of those above. If you wish to allow use of your version of this file only
32
- * under the terms of either the GPL or the LGPL, and not to allow others to
33
- * use your version of this file under the terms of the MPL, indicate your
34
- * decision by deleting the provisions above and replace them with the notice
35
- * and other provisions required by the GPL or the LGPL. If you do not delete
36
- * the provisions above, a recipient may use your version of this file under
37
- * the terms of any one of the MPL, the GPL or the LGPL.
38
- *
39
- * ***** END LICENSE BLOCK ***** */
40
-
41
-
42
- /* Note : contiguity of 'simple opcodes' is important for SimpleMatch() */
43
-
44
- /* match rest of input against rest of r.e. */
45
- REOP_DEF(REOP_EMPTY, "empty")
46
- /* beginning of input (or line if multiline) */
47
- REOP_DEF(REOP_BOL, "bol")
48
- /* end of input (or line if multiline) */
49
- REOP_DEF(REOP_EOL, "eol")
50
- /* match "" at word boundary */
51
- REOP_DEF(REOP_WBDRY, "wbdry")
52
- /* match "" at word non-boundary */
53
- REOP_DEF(REOP_WNONBDRY, "wnonbdry")
54
- /* stands for any character */
55
- REOP_DEF(REOP_DOT, "dot")
56
- /* match a digit char: [0-9] */
57
- REOP_DEF(REOP_DIGIT, "digit")
58
- /* match a non-digit char: [^0-9] */
59
- REOP_DEF(REOP_NONDIGIT, "nondigit")
60
- /* match an alphanumeric char: [0-9a-z_A-Z] */
61
- REOP_DEF(REOP_ALNUM, "alnum")
62
- /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
63
- REOP_DEF(REOP_NONALNUM, "nonalnum")
64
- /* match a whitespace char */
65
- REOP_DEF(REOP_SPACE, "space")
66
- /* match a non-whitespace char */
67
- REOP_DEF(REOP_NONSPACE, "nonspace")
68
- /* back-reference (e.g., \1) to a parenthetical */
69
- REOP_DEF(REOP_BACKREF, "backref")
70
- /* match a flat string */
71
- REOP_DEF(REOP_FLAT, "flat")
72
- /* match a single char */
73
- REOP_DEF(REOP_FLAT1, "flat1")
74
- /* case-independent REOP_FLAT */
75
- REOP_DEF(REOP_FLATi, "flati")
76
- /* case-independent REOP_FLAT1 */
77
- REOP_DEF(REOP_FLAT1i, "flat1i")
78
- /* single Unicode char */
79
- REOP_DEF(REOP_UCFLAT1, "ucflat1")
80
- /* case-independent REOP_UCFLAT1 */
81
- REOP_DEF(REOP_UCFLAT1i, "ucflat1i")
82
- /* flat Unicode string; len immediate counts chars */
83
- REOP_DEF(REOP_UCFLAT, "ucflat")
84
- /* case-independent REOP_UCFLAT */
85
- REOP_DEF(REOP_UCFLATi, "ucflati")
86
- /* character class with index */
87
- REOP_DEF(REOP_CLASS, "class")
88
- /* negated character class with index */
89
- REOP_DEF(REOP_NCLASS, "nclass")
90
-
91
- /* NCLASS is considered to be the last "simple" op-code */
92
-
93
-
94
- /* alternative subexpressions in kid and next */
95
- REOP_DEF(REOP_ALT, "alt")
96
- /* quantified atom: atom{1,2} */
97
- REOP_DEF(REOP_QUANT, "quant")
98
- /* zero or more occurrences of kid */
99
- REOP_DEF(REOP_STAR, "star")
100
- /* one or more occurrences of kid */
101
- REOP_DEF(REOP_PLUS, "plus")
102
- /* optional subexpression in kid */
103
- REOP_DEF(REOP_OPT, "opt")
104
- /* left paren bytecode: kid is u.num'th sub-regexp */
105
- REOP_DEF(REOP_LPAREN, "lparen")
106
- /* right paren bytecode */
107
- REOP_DEF(REOP_RPAREN, "rparen")
108
- /* for deoptimized closure loops */
109
- REOP_DEF(REOP_JUMP, "jump")
110
- /* optimize .* to use a single opcode */
111
- REOP_DEF(REOP_DOTSTAR, "dotstar")
112
- /* non-capturing version of REOP_LPAREN */
113
- REOP_DEF(REOP_LPARENNON, "lparennon")
114
- /* zero width positive lookahead assertion */
115
- REOP_DEF(REOP_ASSERT, "assert")
116
- /* zero width negative lookahead assertion */
117
- REOP_DEF(REOP_ASSERT_NOT, "assert_not")
118
- /* sentinel at end of assertion child */
119
- REOP_DEF(REOP_ASSERTTEST, "asserttest")
120
- /* sentinel at end of !assertion child */
121
- REOP_DEF(REOP_ASSERTNOTTEST, "assertnottest")
122
- /* non-greedy version of * */
123
- REOP_DEF(REOP_MINIMALSTAR, "minimalstar")
124
- /* non-greedy version of + */
125
- REOP_DEF(REOP_MINIMALPLUS, "minimalplus")
126
- /* non-greedy version of ? */
127
- REOP_DEF(REOP_MINIMALOPT, "minimalopt")
128
- /* non-greedy version of {} */
129
- REOP_DEF(REOP_MINIMALQUANT, "minimalquant")
130
- /* sentinel at end of quantifier child */
131
- REOP_DEF(REOP_ENDCHILD, "endchild")
132
- /* directs execution of greedy quantifier */
133
- REOP_DEF(REOP_REPEAT, "repeat")
134
- /* directs execution of non-greedy quantifier */
135
- REOP_DEF(REOP_MINIMALREPEAT, "minimalrepeat")
136
- /* prerequisite for ALT, either of two chars */
137
- REOP_DEF(REOP_ALTPREREQ, "altprereq")
138
- /* prerequisite for ALT, a char or a class */
139
- REOP_DEF(REOP_ALTPREREQ2, "altprereq2")
140
- /* end of final alternate */
141
- REOP_DEF(REOP_ENDALT, "endalt")
142
- /* concatenation of terms (parse time only) */
143
- REOP_DEF(REOP_CONCAT, "concat")
144
- /* end of expression */
145
- REOP_DEF(REOP_END, "end")
@@ -1,2012 +0,0 @@
1
- /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
- * vim: set sw=4 ts=8 et tw=78:
3
- *
4
- * ***** BEGIN LICENSE BLOCK *****
5
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
- *
7
- * The contents of this file are subject to the Mozilla Public License Version
8
- * 1.1 (the "License"); you may not use this file except in compliance with
9
- * the License. You may obtain a copy of the License at
10
- * http://www.mozilla.org/MPL/
11
- *
12
- * Software distributed under the License is distributed on an "AS IS" basis,
13
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
- * for the specific language governing rights and limitations under the
15
- * License.
16
- *
17
- * The Original Code is Mozilla Communicator client code, released
18
- * March 31, 1998.
19
- *
20
- * The Initial Developer of the Original Code is
21
- * Netscape Communications Corporation.
22
- * Portions created by the Initial Developer are Copyright (C) 1998
23
- * the Initial Developer. All Rights Reserved.
24
- *
25
- * Contributor(s):
26
- *
27
- * Alternatively, the contents of this file may be used under the terms of
28
- * either of the GNU General Public License Version 2 or later (the "GPL"),
29
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
- * in which case the provisions of the GPL or the LGPL are applicable instead
31
- * of those above. If you wish to allow use of your version of this file only
32
- * under the terms of either the GPL or the LGPL, and not to allow others to
33
- * use your version of this file under the terms of the MPL, indicate your
34
- * decision by deleting the provisions above and replace them with the notice
35
- * and other provisions required by the GPL or the LGPL. If you do not delete
36
- * the provisions above, a recipient may use your version of this file under
37
- * the terms of any one of the MPL, the GPL or the LGPL.
38
- *
39
- * ***** END LICENSE BLOCK ***** */
40
-
41
- /*
42
- * JS lexical scanner.
43
- */
44
- #include "jsstddef.h"
45
- #include <stdio.h> /* first to avoid trouble on some systems */
46
- #include <errno.h>
47
- #include <limits.h>
48
- #include <math.h>
49
- #ifdef HAVE_MEMORY_H
50
- #include <memory.h>
51
- #endif
52
- #include <stdarg.h>
53
- #include <stdlib.h>
54
- #include <string.h>
55
- #include "jstypes.h"
56
- #include "jsarena.h" /* Added by JSIFY */
57
- #include "jsutil.h" /* Added by JSIFY */
58
- #include "jsdtoa.h"
59
- #include "jsprf.h"
60
- #include "jsapi.h"
61
- #include "jsatom.h"
62
- #include "jscntxt.h"
63
- #include "jsconfig.h"
64
- #include "jsemit.h"
65
- #include "jsexn.h"
66
- #include "jsnum.h"
67
- #include "jsopcode.h"
68
- #include "jsparse.h"
69
- #include "jsregexp.h"
70
- #include "jsscan.h"
71
- #include "jsscript.h"
72
-
73
- #if JS_HAS_XML_SUPPORT
74
- #include "jsxml.h"
75
- #endif
76
-
77
- #define JS_KEYWORD(keyword, type, op, version) \
78
- const char js_##keyword##_str[] = #keyword;
79
- #include "jskeyword.tbl"
80
- #undef JS_KEYWORD
81
-
82
- struct keyword {
83
- const char *chars; /* C string with keyword text */
84
- JSTokenType tokentype; /* JSTokenType */
85
- JSOp op; /* JSOp */
86
- JSVersion version; /* JSVersion */
87
- };
88
-
89
- static const struct keyword keyword_defs[] = {
90
- #define JS_KEYWORD(keyword, type, op, version) \
91
- {js_##keyword##_str, type, op, version},
92
- #include "jskeyword.tbl"
93
- #undef JS_KEYWORD
94
- };
95
-
96
- #define KEYWORD_COUNT JS_ARRAY_LENGTH(keyword_defs)
97
-
98
- static const struct keyword *
99
- FindKeyword(const jschar *s, size_t length)
100
- {
101
- register size_t i;
102
- const struct keyword *kw;
103
- const char *chars;
104
-
105
- JS_ASSERT(length != 0);
106
-
107
- #define JSKW_LENGTH() length
108
- #define JSKW_AT(column) s[column]
109
- #define JSKW_GOT_MATCH(index) i = (index); goto got_match;
110
- #define JSKW_TEST_GUESS(index) i = (index); goto test_guess;
111
- #define JSKW_NO_MATCH() goto no_match;
112
- #include "jsautokw.h"
113
- #undef JSKW_NO_MATCH
114
- #undef JSKW_TEST_GUESS
115
- #undef JSKW_GOT_MATCH
116
- #undef JSKW_AT
117
- #undef JSKW_LENGTH
118
-
119
- got_match:
120
- return &keyword_defs[i];
121
-
122
- test_guess:
123
- kw = &keyword_defs[i];
124
- chars = kw->chars;
125
- do {
126
- if (*s++ != (unsigned char)(*chars++))
127
- goto no_match;
128
- } while (--length != 0);
129
- return kw;
130
-
131
- no_match:
132
- return NULL;
133
- }
134
-
135
- JSTokenType
136
- js_CheckKeyword(const jschar *str, size_t length)
137
- {
138
- const struct keyword *kw;
139
-
140
- JS_ASSERT(length != 0);
141
- kw = FindKeyword(str, length);
142
- return kw ? kw->tokentype : TOK_EOF;
143
- }
144
-
145
- JS_FRIEND_API(void)
146
- js_MapKeywords(void (*mapfun)(const char *))
147
- {
148
- size_t i;
149
-
150
- for (i = 0; i != KEYWORD_COUNT; ++i)
151
- mapfun(keyword_defs[i].chars);
152
- }
153
-
154
- JSBool
155
- js_IsIdentifier(JSString *str)
156
- {
157
- size_t length;
158
- jschar c, *chars, *end;
159
-
160
- JSSTRING_CHARS_AND_LENGTH(str, chars, length);
161
- if (length == 0)
162
- return JS_FALSE;
163
- c = *chars;
164
- if (!JS_ISIDSTART(c))
165
- return JS_FALSE;
166
- end = chars + length;
167
- while (++chars != end) {
168
- c = *chars;
169
- if (!JS_ISIDENT(c))
170
- return JS_FALSE;
171
- }
172
- return JS_TRUE;
173
- }
174
-
175
- #define TBMIN 64
176
-
177
- static JSBool
178
- GrowTokenBuf(JSStringBuffer *sb, size_t newlength)
179
- {
180
- JSContext *cx;
181
- jschar *base;
182
- ptrdiff_t offset, length;
183
- size_t tbsize;
184
- JSArenaPool *pool;
185
-
186
- cx = (JSContext*) sb->data;
187
- base = sb->base;
188
- offset = PTRDIFF(sb->ptr, base, jschar);
189
- pool = &cx->tempPool;
190
- if (!base) {
191
- tbsize = TBMIN * sizeof(jschar);
192
- length = TBMIN - 1;
193
- JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize);
194
- } else {
195
- length = PTRDIFF(sb->limit, base, jschar);
196
- if ((size_t)length >= ~(size_t)0 / sizeof(jschar)) {
197
- base = NULL;
198
- } else {
199
- tbsize = (length + 1) * sizeof(jschar);
200
- length += length + 1;
201
- JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize);
202
- }
203
- }
204
- if (!base) {
205
- js_ReportOutOfScriptQuota(cx);
206
- sb->base = STRING_BUFFER_ERROR_BASE;
207
- return JS_FALSE;
208
- }
209
- sb->base = base;
210
- sb->limit = base + length;
211
- sb->ptr = base + offset;
212
- return JS_TRUE;
213
- }
214
-
215
- JSBool
216
- js_InitTokenStream(JSContext *cx, JSTokenStream *ts,
217
- const jschar *base, size_t length,
218
- FILE *fp, const char *filename, uintN lineno)
219
- {
220
- jschar *buf;
221
- size_t nb;
222
-
223
- JS_ASSERT_IF(fp, !base);
224
- JS_ASSERT_IF(!base, length == 0);
225
- nb = fp
226
- ? 2 * JS_LINE_LIMIT * sizeof(jschar)
227
- : JS_LINE_LIMIT * sizeof(jschar);
228
- JS_ARENA_ALLOCATE_CAST(buf, jschar *, &cx->tempPool, nb);
229
- if (!buf) {
230
- js_ReportOutOfScriptQuota(cx);
231
- return JS_FALSE;
232
- }
233
- memset(buf, 0, nb);
234
- memset(ts, 0, sizeof(*ts));
235
- ts->filename = filename;
236
- ts->lineno = lineno;
237
- ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = buf;
238
- if (fp) {
239
- ts->file = fp;
240
- ts->userbuf.base = buf + JS_LINE_LIMIT;
241
- ts->userbuf.ptr = ts->userbuf.limit = ts->userbuf.base + JS_LINE_LIMIT;
242
- } else {
243
- ts->userbuf.base = (jschar *)base;
244
- ts->userbuf.limit = (jschar *)base + length;
245
- ts->userbuf.ptr = (jschar *)base;
246
- }
247
- ts->tokenbuf.grow = GrowTokenBuf;
248
- ts->tokenbuf.data = cx;
249
- ts->listener = cx->debugHooks->sourceHandler;
250
- ts->listenerData = cx->debugHooks->sourceHandlerData;
251
- return JS_TRUE;
252
- }
253
-
254
- void
255
- js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
256
- {
257
- if (ts->flags & TSF_OWNFILENAME)
258
- JS_free(cx, (void *) ts->filename);
259
- }
260
-
261
- JS_FRIEND_API(int)
262
- js_fgets(char *buf, int size, FILE *file)
263
- {
264
- int n, i, c;
265
- JSBool crflag;
266
-
267
- n = size - 1;
268
- if (n < 0)
269
- return -1;
270
-
271
- crflag = JS_FALSE;
272
- for (i = 0; i < n && (c = getc(file)) != EOF; i++) {
273
- buf[i] = c;
274
- if (c == '\n') { /* any \n ends a line */
275
- i++; /* keep the \n; we know there is room for \0 */
276
- break;
277
- }
278
- if (crflag) { /* \r not followed by \n ends line at the \r */
279
- ungetc(c, file);
280
- break; /* and overwrite c in buf with \0 */
281
- }
282
- crflag = (c == '\r');
283
- }
284
-
285
- buf[i] = '\0';
286
- return i;
287
- }
288
-
289
- static int32
290
- GetChar(JSTokenStream *ts)
291
- {
292
- int32 c;
293
- ptrdiff_t i, j, len, olen;
294
- JSBool crflag;
295
- char cbuf[JS_LINE_LIMIT];
296
- jschar *ubuf, *nl;
297
-
298
- if (ts->ungetpos != 0) {
299
- c = ts->ungetbuf[--ts->ungetpos];
300
- } else {
301
- if (ts->linebuf.ptr == ts->linebuf.limit) {
302
- len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar);
303
- if (len <= 0) {
304
- if (!ts->file) {
305
- ts->flags |= TSF_EOF;
306
- return EOF;
307
- }
308
-
309
- /* Fill ts->userbuf so that \r and \r\n convert to \n. */
310
- crflag = (ts->flags & TSF_CRFLAG) != 0;
311
- len = js_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
312
- if (len <= 0) {
313
- ts->flags |= TSF_EOF;
314
- return EOF;
315
- }
316
- olen = len;
317
- ubuf = ts->userbuf.base;
318
- i = 0;
319
- if (crflag) {
320
- ts->flags &= ~TSF_CRFLAG;
321
- if (cbuf[0] != '\n') {
322
- ubuf[i++] = '\n';
323
- len++;
324
- ts->linepos--;
325
- }
326
- }
327
- for (j = 0; i < len; i++, j++)
328
- ubuf[i] = (jschar) (unsigned char) cbuf[j];
329
- ts->userbuf.limit = ubuf + len;
330
- ts->userbuf.ptr = ubuf;
331
- }
332
- if (ts->listener) {
333
- ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len,
334
- &ts->listenerTSData, ts->listenerData);
335
- }
336
-
337
- nl = ts->saveEOL;
338
- if (!nl) {
339
- /*
340
- * Any one of \n, \r, or \r\n ends a line (the longest
341
- * match wins). Also allow the Unicode line and paragraph
342
- * separators.
343
- */
344
- for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) {
345
- /*
346
- * Try to prevent value-testing on most characters by
347
- * filtering out characters that aren't 000x or 202x.
348
- */
349
- if ((*nl & 0xDFD0) == 0) {
350
- if (*nl == '\n')
351
- break;
352
- if (*nl == '\r') {
353
- if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')
354
- nl++;
355
- break;
356
- }
357
- if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
358
- break;
359
- }
360
- }
361
- }
362
-
363
- /*
364
- * If there was a line terminator, copy thru it into linebuf.
365
- * Else copy JS_LINE_LIMIT-1 bytes into linebuf.
366
- */
367
- if (nl < ts->userbuf.limit)
368
- len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1;
369
- if (len >= JS_LINE_LIMIT) {
370
- len = JS_LINE_LIMIT - 1;
371
- ts->saveEOL = nl;
372
- } else {
373
- ts->saveEOL = NULL;
374
- }
375
- js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len);
376
- ts->userbuf.ptr += len;
377
- olen = len;
378
-
379
- /*
380
- * Make sure linebuf contains \n for EOL (don't do this in
381
- * userbuf because the user's string might be readonly).
382
- */
383
- if (nl < ts->userbuf.limit) {
384
- if (*nl == '\r') {
385
- if (ts->linebuf.base[len-1] == '\r') {
386
- /*
387
- * Does the line segment end in \r? We must check
388
- * for a \n at the front of the next segment before
389
- * storing a \n into linebuf. This case matters
390
- * only when we're reading from a file.
391
- */
392
- if (nl + 1 == ts->userbuf.limit && ts->file) {
393
- len--;
394
- ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */
395
- if (len == 0) {
396
- /*
397
- * This can happen when a segment ends in
398
- * \r\r. Start over. ptr == limit in this
399
- * case, so we'll fall into buffer-filling
400
- * code.
401
- */
402
- return GetChar(ts);
403
- }
404
- } else {
405
- ts->linebuf.base[len-1] = '\n';
406
- }
407
- }
408
- } else if (*nl == '\n') {
409
- if (nl > ts->userbuf.base &&
410
- nl[-1] == '\r' &&
411
- ts->linebuf.base[len-2] == '\r') {
412
- len--;
413
- JS_ASSERT(ts->linebuf.base[len] == '\n');
414
- ts->linebuf.base[len-1] = '\n';
415
- }
416
- } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {
417
- ts->linebuf.base[len-1] = '\n';
418
- }
419
- }
420
-
421
- /* Reset linebuf based on adjusted segment length. */
422
- ts->linebuf.limit = ts->linebuf.base + len;
423
- ts->linebuf.ptr = ts->linebuf.base;
424
-
425
- /* Update position of linebuf within physical userbuf line. */
426
- if (!(ts->flags & TSF_NLFLAG))
427
- ts->linepos += ts->linelen;
428
- else
429
- ts->linepos = 0;
430
- if (ts->linebuf.limit[-1] == '\n')
431
- ts->flags |= TSF_NLFLAG;
432
- else
433
- ts->flags &= ~TSF_NLFLAG;
434
-
435
- /* Update linelen from original segment length. */
436
- ts->linelen = olen;
437
- }
438
- c = *ts->linebuf.ptr++;
439
- }
440
- if (c == '\n')
441
- ts->lineno++;
442
- return c;
443
- }
444
-
445
- static void
446
- UngetChar(JSTokenStream *ts, int32 c)
447
- {
448
- if (c == EOF)
449
- return;
450
- JS_ASSERT(ts->ungetpos < JS_ARRAY_LENGTH(ts->ungetbuf));
451
- if (c == '\n')
452
- ts->lineno--;
453
- ts->ungetbuf[ts->ungetpos++] = (jschar)c;
454
- }
455
-
456
- static int32
457
- PeekChar(JSTokenStream *ts)
458
- {
459
- int32 c;
460
-
461
- c = GetChar(ts);
462
- UngetChar(ts, c);
463
- return c;
464
- }
465
-
466
- /*
467
- * Peek n chars ahead into ts. Return true if n chars were read, false if
468
- * there weren't enough characters in the input stream. This function cannot
469
- * be used to peek into or past a newline.
470
- */
471
- static JSBool
472
- PeekChars(JSTokenStream *ts, intN n, jschar *cp)
473
- {
474
- intN i, j;
475
- int32 c;
476
-
477
- for (i = 0; i < n; i++) {
478
- c = GetChar(ts);
479
- if (c == EOF)
480
- break;
481
- if (c == '\n') {
482
- UngetChar(ts, c);
483
- break;
484
- }
485
- cp[i] = (jschar)c;
486
- }
487
- for (j = i - 1; j >= 0; j--)
488
- UngetChar(ts, cp[j]);
489
- return i == n;
490
- }
491
-
492
- static void
493
- SkipChars(JSTokenStream *ts, intN n)
494
- {
495
- while (--n >= 0)
496
- GetChar(ts);
497
- }
498
-
499
- static JSBool
500
- MatchChar(JSTokenStream *ts, int32 expect)
501
- {
502
- int32 c;
503
-
504
- c = GetChar(ts);
505
- if (c == expect)
506
- return JS_TRUE;
507
- UngetChar(ts, c);
508
- return JS_FALSE;
509
- }
510
-
511
- JSBool
512
- js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
513
- uintN flags, uintN errorNumber, ...)
514
- {
515
- JSErrorReport report;
516
- char *message;
517
- size_t linelength;
518
- jschar *linechars;
519
- char *linebytes;
520
- va_list ap;
521
- JSBool warning, ok;
522
- JSTokenPos *tp;
523
- uintN index, i;
524
- JSErrorReporter onError;
525
-
526
- JS_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
527
-
528
- if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
529
- return JS_TRUE;
530
-
531
- memset(&report, 0, sizeof report);
532
- report.flags = flags;
533
- report.errorNumber = errorNumber;
534
- message = NULL;
535
- linechars = NULL;
536
- linebytes = NULL;
537
-
538
- /* From this point the control must flow through the label out.*/
539
- va_start(ap, errorNumber);
540
- ok = js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
541
- errorNumber, &message, &report, &warning,
542
- !(flags & JSREPORT_UC), ap);
543
- va_end(ap);
544
- if (!ok) {
545
- warning = JS_FALSE;
546
- goto out;
547
- }
548
-
549
- report.filename = ts->filename;
550
-
551
- if (pn) {
552
- report.lineno = pn->pn_pos.begin.lineno;
553
- if (report.lineno != ts->lineno)
554
- goto report;
555
- tp = &pn->pn_pos;
556
- } else {
557
- /* Point to the current token, not the next one to get. */
558
- tp = &ts->tokens[ts->cursor].pos;
559
- }
560
- report.lineno = ts->lineno;
561
- linelength = PTRDIFF(ts->linebuf.limit, ts->linebuf.base, jschar);
562
- linechars = (jschar *)JS_malloc(cx, (linelength + 1) * sizeof(jschar));
563
- if (!linechars) {
564
- warning = JS_FALSE;
565
- goto out;
566
- }
567
- memcpy(linechars, ts->linebuf.base, linelength * sizeof(jschar));
568
- linechars[linelength] = 0;
569
- linebytes = js_DeflateString(cx, linechars, linelength);
570
- if (!linebytes) {
571
- warning = JS_FALSE;
572
- goto out;
573
- }
574
- report.linebuf = linebytes;
575
-
576
- /*
577
- * FIXME: What should instead happen here is that we should
578
- * find error-tokens in userbuf, if !ts->file. That will
579
- * allow us to deliver a more helpful error message, which
580
- * includes all or part of the bad string or bad token. The
581
- * code here yields something that looks truncated.
582
- * See https://bugzilla.mozilla.org/show_bug.cgi?id=352970
583
- */
584
- index = 0;
585
- if (tp->begin.lineno == tp->end.lineno) {
586
- if (tp->begin.index < ts->linepos)
587
- goto report;
588
-
589
- index = tp->begin.index - ts->linepos;
590
- }
591
-
592
- report.tokenptr = report.linebuf + index;
593
- report.uclinebuf = linechars;
594
- report.uctokenptr = report.uclinebuf + index;
595
-
596
- /*
597
- * If there's a runtime exception type associated with this error
598
- * number, set that as the pending exception. For errors occuring at
599
- * compile time, this is very likely to be a JSEXN_SYNTAXERR.
600
- *
601
- * If an exception is thrown but not caught, the JSREPORT_EXCEPTION
602
- * flag will be set in report.flags. Proper behavior for an error
603
- * reporter is to ignore a report with this flag for all but top-level
604
- * compilation errors. The exception will remain pending, and so long
605
- * as the non-top-level "load", "eval", or "compile" native function
606
- * returns false, the top-level reporter will eventually receive the
607
- * uncaught exception report.
608
- *
609
- * XXX it'd probably be best if there was only one call to this
610
- * function, but there seem to be two error reporter call points.
611
- */
612
- report:
613
- onError = cx->errorReporter;
614
-
615
- /*
616
- * Try to raise an exception only if there isn't one already set --
617
- * otherwise the exception will describe the last compile-time error,
618
- * which is likely spurious.
619
- */
620
- if (!(ts->flags & TSF_ERROR)) {
621
- if (js_ErrorToException(cx, message, &report))
622
- onError = NULL;
623
- }
624
-
625
- /*
626
- * Suppress any compile-time errors that don't occur at the top level.
627
- * This may still fail, as interplevel may be zero in contexts where we
628
- * don't really want to call the error reporter, as when js is called
629
- * by other code which could catch the error.
630
- */
631
- if (cx->interpLevel != 0 && !JSREPORT_IS_WARNING(flags))
632
- onError = NULL;
633
-
634
- if (onError) {
635
- JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
636
-
637
- /*
638
- * If debugErrorHook is present then we give it a chance to veto
639
- * sending the error on to the regular error reporter.
640
- */
641
- if (hook && !hook(cx, message, &report,
642
- cx->debugHooks->debugErrorHookData)) {
643
- onError = NULL;
644
- }
645
- }
646
- if (onError)
647
- (*onError)(cx, message, &report);
648
-
649
- out:
650
- if (linebytes)
651
- JS_free(cx, linebytes);
652
- if (linechars)
653
- JS_free(cx, linechars);
654
- if (message)
655
- JS_free(cx, message);
656
- if (report.ucmessage)
657
- JS_free(cx, (void *)report.ucmessage);
658
-
659
- if (report.messageArgs) {
660
- if (!(flags & JSREPORT_UC)) {
661
- i = 0;
662
- while (report.messageArgs[i])
663
- JS_free(cx, (void *)report.messageArgs[i++]);
664
- }
665
- JS_free(cx, (void *)report.messageArgs);
666
- }
667
-
668
- if (!JSREPORT_IS_WARNING(flags)) {
669
- /* Set the error flag to suppress spurious reports. */
670
- ts->flags |= TSF_ERROR;
671
- }
672
-
673
- return warning;
674
- }
675
-
676
- static JSBool
677
- GrowStringBuffer(JSStringBuffer *sb, size_t newlength)
678
- {
679
- ptrdiff_t offset;
680
- jschar *bp;
681
-
682
- offset = PTRDIFF(sb->ptr, sb->base, jschar);
683
- JS_ASSERT(offset >= 0);
684
- newlength += offset + 1;
685
- if ((size_t)offset < newlength && newlength < ~(size_t)0 / sizeof(jschar))
686
- bp = (jschar *) realloc(sb->base, newlength * sizeof(jschar));
687
- else
688
- bp = NULL;
689
- if (!bp) {
690
- free(sb->base);
691
- sb->base = STRING_BUFFER_ERROR_BASE;
692
- return JS_FALSE;
693
- }
694
- sb->base = bp;
695
- sb->ptr = bp + offset;
696
- sb->limit = bp + newlength - 1;
697
- return JS_TRUE;
698
- }
699
-
700
- static void
701
- FreeStringBuffer(JSStringBuffer *sb)
702
- {
703
- JS_ASSERT(STRING_BUFFER_OK(sb));
704
- if (sb->base)
705
- free(sb->base);
706
- }
707
-
708
- void
709
- js_InitStringBuffer(JSStringBuffer *sb)
710
- {
711
- sb->base = sb->limit = sb->ptr = NULL;
712
- sb->data = NULL;
713
- sb->grow = GrowStringBuffer;
714
- sb->free = FreeStringBuffer;
715
- }
716
-
717
- void
718
- js_FinishStringBuffer(JSStringBuffer *sb)
719
- {
720
- sb->free(sb);
721
- }
722
-
723
- #define ENSURE_STRING_BUFFER(sb,n) \
724
- ((sb)->ptr + (n) <= (sb)->limit || sb->grow(sb, n))
725
-
726
- static void
727
- FastAppendChar(JSStringBuffer *sb, jschar c)
728
- {
729
- if (!STRING_BUFFER_OK(sb))
730
- return;
731
- if (!ENSURE_STRING_BUFFER(sb, 1))
732
- return;
733
- *sb->ptr++ = c;
734
- }
735
-
736
- void
737
- js_AppendChar(JSStringBuffer *sb, jschar c)
738
- {
739
- jschar *bp;
740
-
741
- if (!STRING_BUFFER_OK(sb))
742
- return;
743
- if (!ENSURE_STRING_BUFFER(sb, 1))
744
- return;
745
- bp = sb->ptr;
746
- *bp++ = c;
747
- *bp = 0;
748
- sb->ptr = bp;
749
- }
750
-
751
- #if JS_HAS_XML_SUPPORT
752
-
753
- void
754
- js_RepeatChar(JSStringBuffer *sb, jschar c, uintN count)
755
- {
756
- jschar *bp;
757
-
758
- if (!STRING_BUFFER_OK(sb) || count == 0)
759
- return;
760
- if (!ENSURE_STRING_BUFFER(sb, count))
761
- return;
762
- for (bp = sb->ptr; count; --count)
763
- *bp++ = c;
764
- *bp = 0;
765
- sb->ptr = bp;
766
- }
767
-
768
- void
769
- js_AppendCString(JSStringBuffer *sb, const char *asciiz)
770
- {
771
- size_t length;
772
- jschar *bp;
773
-
774
- if (!STRING_BUFFER_OK(sb) || *asciiz == '\0')
775
- return;
776
- length = strlen(asciiz);
777
- if (!ENSURE_STRING_BUFFER(sb, length))
778
- return;
779
- for (bp = sb->ptr; length; --length)
780
- *bp++ = (jschar) *asciiz++;
781
- *bp = 0;
782
- sb->ptr = bp;
783
- }
784
-
785
- void
786
- js_AppendJSString(JSStringBuffer *sb, JSString *str)
787
- {
788
- size_t length;
789
- jschar *bp;
790
-
791
- if (!STRING_BUFFER_OK(sb))
792
- return;
793
- length = JSSTRING_LENGTH(str);
794
- if (length == 0 || !ENSURE_STRING_BUFFER(sb, length))
795
- return;
796
- bp = sb->ptr;
797
- js_strncpy(bp, JSSTRING_CHARS(str), length);
798
- bp += length;
799
- *bp = 0;
800
- sb->ptr = bp;
801
- }
802
-
803
- static JSBool
804
- GetXMLEntity(JSContext *cx, JSTokenStream *ts)
805
- {
806
- ptrdiff_t offset, length, i;
807
- int32 c, d;
808
- JSBool ispair;
809
- jschar *bp, digit;
810
- char *bytes;
811
- JSErrNum msg;
812
-
813
- /* Put the entity, including the '&' already scanned, in ts->tokenbuf. */
814
- offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar);
815
- FastAppendChar(&ts->tokenbuf, '&');
816
- if (!STRING_BUFFER_OK(&ts->tokenbuf))
817
- return JS_FALSE;
818
- while ((c = GetChar(ts)) != ';') {
819
- if (c == EOF || c == '\n') {
820
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
821
- JSMSG_END_OF_XML_ENTITY);
822
- return JS_FALSE;
823
- }
824
- FastAppendChar(&ts->tokenbuf, (jschar) c);
825
- if (!STRING_BUFFER_OK(&ts->tokenbuf))
826
- return JS_FALSE;
827
- }
828
-
829
- /* Let length be the number of jschars after the '&', including the ';'. */
830
- length = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar) - offset;
831
- bp = ts->tokenbuf.base + offset;
832
- c = d = 0;
833
- ispair = JS_FALSE;
834
- if (length > 2 && bp[1] == '#') {
835
- /* Match a well-formed XML Character Reference. */
836
- i = 2;
837
- if (length > 3 && JS_TOLOWER(bp[i]) == 'x') {
838
- if (length > 9) /* at most 6 hex digits allowed */
839
- goto badncr;
840
- while (++i < length) {
841
- digit = bp[i];
842
- if (!JS7_ISHEX(digit))
843
- goto badncr;
844
- c = (c << 4) + JS7_UNHEX(digit);
845
- }
846
- } else {
847
- while (i < length) {
848
- digit = bp[i++];
849
- if (!JS7_ISDEC(digit))
850
- goto badncr;
851
- c = (c * 10) + JS7_UNDEC(digit);
852
- if (c < 0)
853
- goto badncr;
854
- }
855
- }
856
-
857
- if (0x10000 <= c && c <= 0x10FFFF) {
858
- /* Form a surrogate pair (c, d) -- c is the high surrogate. */
859
- d = 0xDC00 + (c & 0x3FF);
860
- c = 0xD7C0 + (c >> 10);
861
- ispair = JS_TRUE;
862
- } else {
863
- /* Enforce the http://www.w3.org/TR/REC-xml/#wf-Legalchar WFC. */
864
- if (c != 0x9 && c != 0xA && c != 0xD &&
865
- !(0x20 <= c && c <= 0xD7FF) &&
866
- !(0xE000 <= c && c <= 0xFFFD)) {
867
- goto badncr;
868
- }
869
- }
870
- } else {
871
- /* Try to match one of the five XML 1.0 predefined entities. */
872
- switch (length) {
873
- case 3:
874
- if (bp[2] == 't') {
875
- if (bp[1] == 'l')
876
- c = '<';
877
- else if (bp[1] == 'g')
878
- c = '>';
879
- }
880
- break;
881
- case 4:
882
- if (bp[1] == 'a' && bp[2] == 'm' && bp[3] == 'p')
883
- c = '&';
884
- break;
885
- case 5:
886
- if (bp[3] == 'o') {
887
- if (bp[1] == 'a' && bp[2] == 'p' && bp[4] == 's')
888
- c = '\'';
889
- else if (bp[1] == 'q' && bp[2] == 'u' && bp[4] == 't')
890
- c = '"';
891
- }
892
- break;
893
- }
894
- if (c == 0) {
895
- msg = JSMSG_UNKNOWN_XML_ENTITY;
896
- goto bad;
897
- }
898
- }
899
-
900
- /* If we matched, retract ts->tokenbuf and store the entity's value. */
901
- *bp++ = (jschar) c;
902
- if (ispair)
903
- *bp++ = (jschar) d;
904
- *bp = 0;
905
- ts->tokenbuf.ptr = bp;
906
- return JS_TRUE;
907
-
908
- badncr:
909
- msg = JSMSG_BAD_XML_NCR;
910
- bad:
911
- /* No match: throw a TypeError per ECMA-357 10.3.2.1 step 8(a). */
912
- JS_ASSERT(STRING_BUFFER_OK(&ts->tokenbuf));
913
- JS_ASSERT(PTRDIFF(ts->tokenbuf.ptr, bp, jschar) >= 1);
914
- bytes = js_DeflateString(cx, bp + 1,
915
- PTRDIFF(ts->tokenbuf.ptr, bp, jschar) - 1);
916
- if (bytes) {
917
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
918
- msg, bytes);
919
- JS_free(cx, bytes);
920
- }
921
- return JS_FALSE;
922
- }
923
-
924
- #endif /* JS_HAS_XML_SUPPORT */
925
-
926
- JSTokenType
927
- js_PeekToken(JSContext *cx, JSTokenStream *ts)
928
- {
929
- JSTokenType tt;
930
-
931
- if (ts->lookahead != 0) {
932
- tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type;
933
- } else {
934
- tt = js_GetToken(cx, ts);
935
- js_UngetToken(ts);
936
- }
937
- return tt;
938
- }
939
-
940
- JSTokenType
941
- js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts)
942
- {
943
- JSTokenType tt;
944
-
945
- if (!ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos))
946
- return TOK_EOL;
947
- ts->flags |= TSF_NEWLINES;
948
- tt = js_PeekToken(cx, ts);
949
- ts->flags &= ~TSF_NEWLINES;
950
- return tt;
951
- }
952
-
953
- /*
954
- * We have encountered a '\': check for a Unicode escape sequence after it,
955
- * returning the character code value if we found a Unicode escape sequence.
956
- * Otherwise, non-destructively return the original '\'.
957
- */
958
- static int32
959
- GetUnicodeEscape(JSTokenStream *ts)
960
- {
961
- jschar cp[5];
962
- int32 c;
963
-
964
- if (PeekChars(ts, 5, cp) && cp[0] == 'u' &&
965
- JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
966
- JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4]))
967
- {
968
- c = (((((JS7_UNHEX(cp[1]) << 4)
969
- + JS7_UNHEX(cp[2])) << 4)
970
- + JS7_UNHEX(cp[3])) << 4)
971
- + JS7_UNHEX(cp[4]);
972
- SkipChars(ts, 5);
973
- return c;
974
- }
975
- return '\\';
976
- }
977
-
978
- static JSToken *
979
- NewToken(JSTokenStream *ts, ptrdiff_t adjust)
980
- {
981
- JSToken *tp;
982
-
983
- ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
984
- tp = &CURRENT_TOKEN(ts);
985
- tp->ptr = ts->linebuf.ptr + adjust;
986
- tp->pos.begin.index = ts->linepos +
987
- PTRDIFF(tp->ptr, ts->linebuf.base, jschar) -
988
- ts->ungetpos;
989
- tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno;
990
- return tp;
991
- }
992
-
993
- static JS_INLINE JSBool
994
- ScanAsSpace(jschar c)
995
- {
996
- /* Treat little- and big-endian BOMs as whitespace for compatibility. */
997
- if (JS_ISSPACE(c) || c == 0xfffe || c == 0xfeff)
998
- return JS_TRUE;
999
- return JS_FALSE;
1000
- }
1001
-
1002
- JSTokenType
1003
- js_GetToken(JSContext *cx, JSTokenStream *ts)
1004
- {
1005
- JSTokenType tt;
1006
- int32 c, qc;
1007
- JSToken *tp;
1008
- JSAtom *atom;
1009
- JSBool hadUnicodeEscape;
1010
- const struct keyword *kw;
1011
- #if JS_HAS_XML_SUPPORT
1012
- JSBool inTarget;
1013
- size_t targetLength;
1014
- ptrdiff_t contentIndex;
1015
- #endif
1016
-
1017
- #define INIT_TOKENBUF() (ts->tokenbuf.ptr = ts->tokenbuf.base)
1018
- #define TOKENBUF_LENGTH() PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar)
1019
- #define TOKENBUF_OK() STRING_BUFFER_OK(&ts->tokenbuf)
1020
- #define TOKENBUF_TO_ATOM() (TOKENBUF_OK() \
1021
- ? js_AtomizeChars(cx, \
1022
- TOKENBUF_BASE(), \
1023
- TOKENBUF_LENGTH(), \
1024
- 0) \
1025
- : NULL)
1026
- #define ADD_TO_TOKENBUF(c) FastAppendChar(&ts->tokenbuf, (jschar) (c))
1027
-
1028
- /* The following 4 macros should only be used when TOKENBUF_OK() is true. */
1029
- #define TOKENBUF_BASE() (ts->tokenbuf.base)
1030
- #define TOKENBUF_END() (ts->tokenbuf.ptr)
1031
- #define TOKENBUF_CHAR(i) (ts->tokenbuf.base[i])
1032
- #define TRIM_TOKENBUF(i) (ts->tokenbuf.ptr = ts->tokenbuf.base + i)
1033
- #define NUL_TERM_TOKENBUF() (*ts->tokenbuf.ptr = 0)
1034
-
1035
- /* Check for a pushed-back token resulting from mismatching lookahead. */
1036
- while (ts->lookahead != 0) {
1037
- JS_ASSERT(!(ts->flags & TSF_XMLTEXTMODE));
1038
- ts->lookahead--;
1039
- ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
1040
- tt = CURRENT_TOKEN(ts).type;
1041
- if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES))
1042
- return tt;
1043
- }
1044
-
1045
- /* If there was a fatal error, keep returning TOK_ERROR. */
1046
- if (ts->flags & TSF_ERROR)
1047
- return TOK_ERROR;
1048
-
1049
- #if JS_HAS_XML_SUPPORT
1050
- if (ts->flags & TSF_XMLTEXTMODE) {
1051
- tt = TOK_XMLSPACE; /* veto if non-space, return TOK_XMLTEXT */
1052
- tp = NewToken(ts, 0);
1053
- INIT_TOKENBUF();
1054
- qc = (ts->flags & TSF_XMLONLYMODE) ? '<' : '{';
1055
-
1056
- while ((c = GetChar(ts)) != qc && c != '<' && c != EOF) {
1057
- if (c == '&' && qc == '<') {
1058
- if (!GetXMLEntity(cx, ts))
1059
- goto error;
1060
- tt = TOK_XMLTEXT;
1061
- continue;
1062
- }
1063
-
1064
- if (!JS_ISXMLSPACE(c))
1065
- tt = TOK_XMLTEXT;
1066
- ADD_TO_TOKENBUF(c);
1067
- }
1068
- UngetChar(ts, c);
1069
-
1070
- if (TOKENBUF_LENGTH() == 0) {
1071
- atom = NULL;
1072
- } else {
1073
- atom = TOKENBUF_TO_ATOM();
1074
- if (!atom)
1075
- goto error;
1076
- }
1077
- tp->pos.end.lineno = (uint16)ts->lineno;
1078
- tp->t_op = JSOP_STRING;
1079
- tp->t_atom = atom;
1080
- goto out;
1081
- }
1082
-
1083
- if (ts->flags & TSF_XMLTAGMODE) {
1084
- tp = NewToken(ts, 0);
1085
- c = GetChar(ts);
1086
- if (JS_ISXMLSPACE(c)) {
1087
- do {
1088
- c = GetChar(ts);
1089
- } while (JS_ISXMLSPACE(c));
1090
- UngetChar(ts, c);
1091
- tt = TOK_XMLSPACE;
1092
- goto out;
1093
- }
1094
-
1095
- if (c == EOF) {
1096
- tt = TOK_EOF;
1097
- goto out;
1098
- }
1099
-
1100
- INIT_TOKENBUF();
1101
- if (JS_ISXMLNSSTART(c)) {
1102
- JSBool sawColon = JS_FALSE;
1103
-
1104
- ADD_TO_TOKENBUF(c);
1105
- while ((c = GetChar(ts)) != EOF && JS_ISXMLNAME(c)) {
1106
- if (c == ':') {
1107
- int nextc;
1108
-
1109
- if (sawColon ||
1110
- (nextc = PeekChar(ts),
1111
- ((ts->flags & TSF_XMLONLYMODE) || nextc != '{') &&
1112
- !JS_ISXMLNAME(nextc))) {
1113
- js_ReportCompileErrorNumber(cx, ts, NULL,
1114
- JSREPORT_ERROR,
1115
- JSMSG_BAD_XML_QNAME);
1116
- goto error;
1117
- }
1118
- sawColon = JS_TRUE;
1119
- }
1120
-
1121
- ADD_TO_TOKENBUF(c);
1122
- }
1123
-
1124
- UngetChar(ts, c);
1125
- atom = TOKENBUF_TO_ATOM();
1126
- if (!atom)
1127
- goto error;
1128
- tp->t_op = JSOP_STRING;
1129
- tp->t_atom = atom;
1130
- tt = TOK_XMLNAME;
1131
- goto out;
1132
- }
1133
-
1134
- switch (c) {
1135
- case '{':
1136
- if (ts->flags & TSF_XMLONLYMODE)
1137
- goto bad_xml_char;
1138
- tt = TOK_LC;
1139
- goto out;
1140
-
1141
- case '=':
1142
- tt = TOK_ASSIGN;
1143
- goto out;
1144
-
1145
- case '"':
1146
- case '\'':
1147
- qc = c;
1148
- while ((c = GetChar(ts)) != qc) {
1149
- if (c == EOF) {
1150
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1151
- JSMSG_UNTERMINATED_STRING);
1152
- goto error;
1153
- }
1154
-
1155
- /*
1156
- * XML attribute values are double-quoted when pretty-printed,
1157
- * so escape " if it is expressed directly in a single-quoted
1158
- * attribute value.
1159
- */
1160
- if (c == '"' && !(ts->flags & TSF_XMLONLYMODE)) {
1161
- JS_ASSERT(qc == '\'');
1162
- js_AppendCString(&ts->tokenbuf, js_quot_entity_str);
1163
- continue;
1164
- }
1165
-
1166
- if (c == '&' && (ts->flags & TSF_XMLONLYMODE)) {
1167
- if (!GetXMLEntity(cx, ts))
1168
- goto error;
1169
- continue;
1170
- }
1171
-
1172
- ADD_TO_TOKENBUF(c);
1173
- }
1174
- atom = TOKENBUF_TO_ATOM();
1175
- if (!atom)
1176
- goto error;
1177
- tp->pos.end.lineno = (uint16)ts->lineno;
1178
- tp->t_op = JSOP_STRING;
1179
- tp->t_atom = atom;
1180
- tt = TOK_XMLATTR;
1181
- goto out;
1182
-
1183
- case '>':
1184
- tt = TOK_XMLTAGC;
1185
- goto out;
1186
-
1187
- case '/':
1188
- if (MatchChar(ts, '>')) {
1189
- tt = TOK_XMLPTAGC;
1190
- goto out;
1191
- }
1192
- /* FALL THROUGH */
1193
-
1194
- bad_xml_char:
1195
- default:
1196
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1197
- JSMSG_BAD_XML_CHARACTER);
1198
- goto error;
1199
- }
1200
- /* NOTREACHED */
1201
- }
1202
- #endif /* JS_HAS_XML_SUPPORT */
1203
-
1204
- retry:
1205
- do {
1206
- c = GetChar(ts);
1207
- if (c == '\n') {
1208
- ts->flags &= ~TSF_DIRTYLINE;
1209
- if (ts->flags & TSF_NEWLINES)
1210
- break;
1211
- }
1212
- } while (ScanAsSpace(c));
1213
-
1214
- tp = NewToken(ts, -1);
1215
- if (c == EOF) {
1216
- tt = TOK_EOF;
1217
- goto out;
1218
- }
1219
-
1220
- hadUnicodeEscape = JS_FALSE;
1221
- if (JS_ISIDSTART(c) ||
1222
- (c == '\\' &&
1223
- (qc = GetUnicodeEscape(ts),
1224
- hadUnicodeEscape = JS_ISIDSTART(qc)))) {
1225
- if (hadUnicodeEscape)
1226
- c = qc;
1227
- INIT_TOKENBUF();
1228
- for (;;) {
1229
- ADD_TO_TOKENBUF(c);
1230
- c = GetChar(ts);
1231
- if (c == '\\') {
1232
- qc = GetUnicodeEscape(ts);
1233
- if (!JS_ISIDENT(qc))
1234
- break;
1235
- c = qc;
1236
- hadUnicodeEscape = JS_TRUE;
1237
- } else {
1238
- if (!JS_ISIDENT(c))
1239
- break;
1240
- }
1241
- }
1242
- UngetChar(ts, c);
1243
-
1244
- /*
1245
- * Check for keywords unless we saw Unicode escape or parser asks
1246
- * to ignore keywords.
1247
- */
1248
- if (!hadUnicodeEscape &&
1249
- !(ts->flags & TSF_KEYWORD_IS_NAME) &&
1250
- TOKENBUF_OK() &&
1251
- (kw = FindKeyword(TOKENBUF_BASE(), TOKENBUF_LENGTH()))) {
1252
- if (kw->tokentype == TOK_RESERVED) {
1253
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
1254
- JSREPORT_WARNING |
1255
- JSREPORT_STRICT,
1256
- JSMSG_RESERVED_ID,
1257
- kw->chars)) {
1258
- goto error;
1259
- }
1260
- } else if (kw->version <= JSVERSION_NUMBER(cx)) {
1261
- tt = kw->tokentype;
1262
- tp->t_op = (JSOp) kw->op;
1263
- goto out;
1264
- }
1265
- }
1266
-
1267
- atom = TOKENBUF_TO_ATOM();
1268
- if (!atom)
1269
- goto error;
1270
- tp->t_op = JSOP_NAME;
1271
- tp->t_atom = atom;
1272
- tt = TOK_NAME;
1273
- goto out;
1274
- }
1275
-
1276
- if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) {
1277
- jsint radix;
1278
- const jschar *endptr;
1279
- jsdouble dval;
1280
-
1281
- radix = 10;
1282
- INIT_TOKENBUF();
1283
-
1284
- if (c == '0') {
1285
- ADD_TO_TOKENBUF(c);
1286
- c = GetChar(ts);
1287
- if (JS_TOLOWER(c) == 'x') {
1288
- ADD_TO_TOKENBUF(c);
1289
- c = GetChar(ts);
1290
- radix = 16;
1291
- } else if (JS7_ISDEC(c)) {
1292
- radix = 8;
1293
- }
1294
- }
1295
-
1296
- while (JS7_ISHEX(c)) {
1297
- if (radix < 16) {
1298
- if (JS7_ISLET(c))
1299
- break;
1300
-
1301
- /*
1302
- * We permit 08 and 09 as decimal numbers, which makes our
1303
- * behaviour a superset of the ECMA numeric grammar. We might
1304
- * not always be so permissive, so we warn about it.
1305
- */
1306
- if (radix == 8 && c >= '8') {
1307
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
1308
- JSREPORT_WARNING,
1309
- JSMSG_BAD_OCTAL,
1310
- c == '8' ? "08" : "09")) {
1311
- goto error;
1312
- }
1313
- radix = 10;
1314
- }
1315
- }
1316
- ADD_TO_TOKENBUF(c);
1317
- c = GetChar(ts);
1318
- }
1319
-
1320
- if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) {
1321
- if (c == '.') {
1322
- do {
1323
- ADD_TO_TOKENBUF(c);
1324
- c = GetChar(ts);
1325
- } while (JS7_ISDEC(c));
1326
- }
1327
- if (JS_TOLOWER(c) == 'e') {
1328
- ADD_TO_TOKENBUF(c);
1329
- c = GetChar(ts);
1330
- if (c == '+' || c == '-') {
1331
- ADD_TO_TOKENBUF(c);
1332
- c = GetChar(ts);
1333
- }
1334
- if (!JS7_ISDEC(c)) {
1335
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1336
- JSMSG_MISSING_EXPONENT);
1337
- goto error;
1338
- }
1339
- do {
1340
- ADD_TO_TOKENBUF(c);
1341
- c = GetChar(ts);
1342
- } while (JS7_ISDEC(c));
1343
- }
1344
- }
1345
-
1346
- /* Put back the next char and NUL-terminate tokenbuf for js_strto*. */
1347
- UngetChar(ts, c);
1348
- ADD_TO_TOKENBUF(0);
1349
-
1350
- if (!TOKENBUF_OK())
1351
- goto error;
1352
- if (radix == 10) {
1353
- if (!js_strtod(cx, TOKENBUF_BASE(), TOKENBUF_END(),
1354
- &endptr, &dval)) {
1355
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1356
- JSMSG_OUT_OF_MEMORY);
1357
- goto error;
1358
- }
1359
- } else {
1360
- if (!js_strtointeger(cx, TOKENBUF_BASE(), TOKENBUF_END(),
1361
- &endptr, radix, &dval)) {
1362
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1363
- JSMSG_OUT_OF_MEMORY);
1364
- goto error;
1365
- }
1366
- }
1367
- tp->t_dval = dval;
1368
- tt = TOK_NUMBER;
1369
- goto out;
1370
- }
1371
-
1372
- if (c == '"' || c == '\'') {
1373
- qc = c;
1374
- INIT_TOKENBUF();
1375
- while ((c = GetChar(ts)) != qc) {
1376
- if (c == '\n' || c == EOF) {
1377
- UngetChar(ts, c);
1378
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1379
- JSMSG_UNTERMINATED_STRING);
1380
- goto error;
1381
- }
1382
- if (c == '\\') {
1383
- switch (c = GetChar(ts)) {
1384
- case 'b': c = '\b'; break;
1385
- case 'f': c = '\f'; break;
1386
- case 'n': c = '\n'; break;
1387
- case 'r': c = '\r'; break;
1388
- case 't': c = '\t'; break;
1389
- case 'v': c = '\v'; break;
1390
-
1391
- default:
1392
- if ('0' <= c && c < '8') {
1393
- int32 val = JS7_UNDEC(c);
1394
-
1395
- c = PeekChar(ts);
1396
- if ('0' <= c && c < '8') {
1397
- val = 8 * val + JS7_UNDEC(c);
1398
- GetChar(ts);
1399
- c = PeekChar(ts);
1400
- if ('0' <= c && c < '8') {
1401
- int32 save = val;
1402
- val = 8 * val + JS7_UNDEC(c);
1403
- if (val <= 0377)
1404
- GetChar(ts);
1405
- else
1406
- val = save;
1407
- }
1408
- }
1409
-
1410
- c = (jschar)val;
1411
- } else if (c == 'u') {
1412
- jschar cp[4];
1413
- if (PeekChars(ts, 4, cp) &&
1414
- JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) &&
1415
- JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) {
1416
- c = (((((JS7_UNHEX(cp[0]) << 4)
1417
- + JS7_UNHEX(cp[1])) << 4)
1418
- + JS7_UNHEX(cp[2])) << 4)
1419
- + JS7_UNHEX(cp[3]);
1420
- SkipChars(ts, 4);
1421
- }
1422
- } else if (c == 'x') {
1423
- jschar cp[2];
1424
- if (PeekChars(ts, 2, cp) &&
1425
- JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) {
1426
- c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]);
1427
- SkipChars(ts, 2);
1428
- }
1429
- } else if (c == '\n') {
1430
- /* ECMA follows C by removing escaped newlines. */
1431
- continue;
1432
- }
1433
- break;
1434
- }
1435
- }
1436
- ADD_TO_TOKENBUF(c);
1437
- }
1438
- atom = TOKENBUF_TO_ATOM();
1439
- if (!atom)
1440
- goto error;
1441
- tp->pos.end.lineno = (uint16)ts->lineno;
1442
- tp->t_op = JSOP_STRING;
1443
- tp->t_atom = atom;
1444
- tt = TOK_STRING;
1445
- goto out;
1446
- }
1447
-
1448
- switch (c) {
1449
- case '\n': tt = TOK_EOL; goto eol_out;
1450
- case ';': tt = TOK_SEMI; break;
1451
- case '[': tt = TOK_LB; break;
1452
- case ']': tt = TOK_RB; break;
1453
- case '{': tt = TOK_LC; break;
1454
- case '}': tt = TOK_RC; break;
1455
- case '(': tt = TOK_LP; break;
1456
- case ')': tt = TOK_RP; break;
1457
- case ',': tt = TOK_COMMA; break;
1458
- case '?': tt = TOK_HOOK; break;
1459
-
1460
- case '.':
1461
- #if JS_HAS_XML_SUPPORT
1462
- if (MatchChar(ts, c))
1463
- tt = TOK_DBLDOT;
1464
- else
1465
- #endif
1466
- tt = TOK_DOT;
1467
- break;
1468
-
1469
- case ':':
1470
- #if JS_HAS_XML_SUPPORT
1471
- if (MatchChar(ts, c)) {
1472
- tt = TOK_DBLCOLON;
1473
- break;
1474
- }
1475
- #endif
1476
- /*
1477
- * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an
1478
- * object initializer, likewise for setter.
1479
- */
1480
- tp->t_op = JSOP_NOP;
1481
- tt = TOK_COLON;
1482
- break;
1483
-
1484
- case '|':
1485
- if (MatchChar(ts, c)) {
1486
- tt = TOK_OR;
1487
- } else if (MatchChar(ts, '=')) {
1488
- tp->t_op = JSOP_BITOR;
1489
- tt = TOK_ASSIGN;
1490
- } else {
1491
- tt = TOK_BITOR;
1492
- }
1493
- break;
1494
-
1495
- case '^':
1496
- if (MatchChar(ts, '=')) {
1497
- tp->t_op = JSOP_BITXOR;
1498
- tt = TOK_ASSIGN;
1499
- } else {
1500
- tt = TOK_BITXOR;
1501
- }
1502
- break;
1503
-
1504
- case '&':
1505
- if (MatchChar(ts, c)) {
1506
- tt = TOK_AND;
1507
- } else if (MatchChar(ts, '=')) {
1508
- tp->t_op = JSOP_BITAND;
1509
- tt = TOK_ASSIGN;
1510
- } else {
1511
- tt = TOK_BITAND;
1512
- }
1513
- break;
1514
-
1515
- case '=':
1516
- if (MatchChar(ts, c)) {
1517
- tp->t_op = MatchChar(ts, c) ? JSOP_STRICTEQ : JSOP_EQ;
1518
- tt = TOK_EQOP;
1519
- } else {
1520
- tp->t_op = JSOP_NOP;
1521
- tt = TOK_ASSIGN;
1522
- }
1523
- break;
1524
-
1525
- case '!':
1526
- if (MatchChar(ts, '=')) {
1527
- tp->t_op = MatchChar(ts, '=') ? JSOP_STRICTNE : JSOP_NE;
1528
- tt = TOK_EQOP;
1529
- } else {
1530
- tp->t_op = JSOP_NOT;
1531
- tt = TOK_UNARYOP;
1532
- }
1533
- break;
1534
-
1535
- #if JS_HAS_XML_SUPPORT
1536
- case '@':
1537
- tt = TOK_AT;
1538
- break;
1539
- #endif
1540
-
1541
- case '<':
1542
- #if JS_HAS_XML_SUPPORT
1543
- /*
1544
- * After much testing, it's clear that Postel's advice to protocol
1545
- * designers ("be liberal in what you accept, and conservative in what
1546
- * you send") invites a natural-law repercussion for JS as "protocol":
1547
- *
1548
- * "If you are liberal in what you accept, others will utterly fail to
1549
- * be conservative in what they send."
1550
- *
1551
- * Which means you will get <!-- comments to end of line in the middle
1552
- * of .js files, and after if conditions whose then statements are on
1553
- * the next line, and other wonders. See at least the following bugs:
1554
- * https://bugzilla.mozilla.org/show_bug.cgi?id=309242
1555
- * https://bugzilla.mozilla.org/show_bug.cgi?id=309712
1556
- * https://bugzilla.mozilla.org/show_bug.cgi?id=310993
1557
- *
1558
- * So without JSOPTION_XML, we never scan an XML comment or CDATA
1559
- * literal. We always scan <! as the start of an HTML comment hack
1560
- * to end of line, used since Netscape 2 to hide script tag content
1561
- * from script-unaware browsers.
1562
- */
1563
- if ((ts->flags & TSF_OPERAND) &&
1564
- (JS_HAS_XML_OPTION(cx) || PeekChar(ts) != '!')) {
1565
- /* Check for XML comment or CDATA section. */
1566
- if (MatchChar(ts, '!')) {
1567
- INIT_TOKENBUF();
1568
-
1569
- /* Scan XML comment. */
1570
- if (MatchChar(ts, '-')) {
1571
- if (!MatchChar(ts, '-'))
1572
- goto bad_xml_markup;
1573
- while ((c = GetChar(ts)) != '-' || !MatchChar(ts, '-')) {
1574
- if (c == EOF)
1575
- goto bad_xml_markup;
1576
- ADD_TO_TOKENBUF(c);
1577
- }
1578
- tt = TOK_XMLCOMMENT;
1579
- tp->t_op = JSOP_XMLCOMMENT;
1580
- goto finish_xml_markup;
1581
- }
1582
-
1583
- /* Scan CDATA section. */
1584
- if (MatchChar(ts, '[')) {
1585
- jschar cp[6];
1586
- if (PeekChars(ts, 6, cp) &&
1587
- cp[0] == 'C' &&
1588
- cp[1] == 'D' &&
1589
- cp[2] == 'A' &&
1590
- cp[3] == 'T' &&
1591
- cp[4] == 'A' &&
1592
- cp[5] == '[') {
1593
- SkipChars(ts, 6);
1594
- while ((c = GetChar(ts)) != ']' ||
1595
- !PeekChars(ts, 2, cp) ||
1596
- cp[0] != ']' ||
1597
- cp[1] != '>') {
1598
- if (c == EOF)
1599
- goto bad_xml_markup;
1600
- ADD_TO_TOKENBUF(c);
1601
- }
1602
- GetChar(ts); /* discard ] but not > */
1603
- tt = TOK_XMLCDATA;
1604
- tp->t_op = JSOP_XMLCDATA;
1605
- goto finish_xml_markup;
1606
- }
1607
- goto bad_xml_markup;
1608
- }
1609
- }
1610
-
1611
- /* Check for processing instruction. */
1612
- if (MatchChar(ts, '?')) {
1613
- inTarget = JS_TRUE;
1614
- targetLength = 0;
1615
- contentIndex = -1;
1616
-
1617
- INIT_TOKENBUF();
1618
- while ((c = GetChar(ts)) != '?' || PeekChar(ts) != '>') {
1619
- if (c == EOF)
1620
- goto bad_xml_markup;
1621
- if (inTarget) {
1622
- if (JS_ISXMLSPACE(c)) {
1623
- if (TOKENBUF_LENGTH() == 0)
1624
- goto bad_xml_markup;
1625
- inTarget = JS_FALSE;
1626
- } else {
1627
- if (!((TOKENBUF_LENGTH() == 0)
1628
- ? JS_ISXMLNSSTART(c)
1629
- : JS_ISXMLNS(c))) {
1630
- goto bad_xml_markup;
1631
- }
1632
- ++targetLength;
1633
- }
1634
- } else {
1635
- if (contentIndex < 0 && !JS_ISXMLSPACE(c))
1636
- contentIndex = TOKENBUF_LENGTH();
1637
- }
1638
- ADD_TO_TOKENBUF(c);
1639
- }
1640
- if (targetLength == 0)
1641
- goto bad_xml_markup;
1642
- if (!TOKENBUF_OK())
1643
- goto error;
1644
- if (contentIndex < 0) {
1645
- atom = cx->runtime->atomState.emptyAtom;
1646
- } else {
1647
- atom = js_AtomizeChars(cx,
1648
- &TOKENBUF_CHAR(contentIndex),
1649
- TOKENBUF_LENGTH() - contentIndex,
1650
- 0);
1651
- if (!atom)
1652
- goto error;
1653
- }
1654
- TRIM_TOKENBUF(targetLength);
1655
- tp->t_atom2 = atom;
1656
- tt = TOK_XMLPI;
1657
-
1658
- finish_xml_markup:
1659
- if (!MatchChar(ts, '>'))
1660
- goto bad_xml_markup;
1661
- atom = TOKENBUF_TO_ATOM();
1662
- if (!atom)
1663
- goto error;
1664
- tp->t_atom = atom;
1665
- tp->pos.end.lineno = (uint16)ts->lineno;
1666
- goto out;
1667
- }
1668
-
1669
- /* An XML start-of-tag character. */
1670
- tt = MatchChar(ts, '/') ? TOK_XMLETAGO : TOK_XMLSTAGO;
1671
- goto out;
1672
-
1673
- bad_xml_markup:
1674
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1675
- JSMSG_BAD_XML_MARKUP);
1676
- goto error;
1677
- }
1678
- #endif /* JS_HAS_XML_SUPPORT */
1679
-
1680
- /* NB: treat HTML begin-comment as comment-till-end-of-line */
1681
- if (MatchChar(ts, '!')) {
1682
- if (MatchChar(ts, '-')) {
1683
- if (MatchChar(ts, '-')) {
1684
- ts->flags |= TSF_IN_HTML_COMMENT;
1685
- goto skipline;
1686
- }
1687
- UngetChar(ts, '-');
1688
- }
1689
- UngetChar(ts, '!');
1690
- }
1691
- if (MatchChar(ts, c)) {
1692
- tp->t_op = JSOP_LSH;
1693
- tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
1694
- } else {
1695
- tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT;
1696
- tt = TOK_RELOP;
1697
- }
1698
- break;
1699
-
1700
- case '>':
1701
- if (MatchChar(ts, c)) {
1702
- tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH;
1703
- tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
1704
- } else {
1705
- tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT;
1706
- tt = TOK_RELOP;
1707
- }
1708
- break;
1709
-
1710
- case '*':
1711
- tp->t_op = JSOP_MUL;
1712
- tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR;
1713
- break;
1714
-
1715
- case '/':
1716
- if (MatchChar(ts, '/')) {
1717
- /*
1718
- * Hack for source filters such as the Mozilla XUL preprocessor:
1719
- * "//@line 123\n" sets the number of the *next* line after the
1720
- * comment to 123.
1721
- */
1722
- if (JS_HAS_ATLINE_OPTION(cx)) {
1723
- jschar cp[5];
1724
- uintN i, line, temp;
1725
- char filename[1024];
1726
-
1727
- if (PeekChars(ts, 5, cp) &&
1728
- cp[0] == '@' &&
1729
- cp[1] == 'l' &&
1730
- cp[2] == 'i' &&
1731
- cp[3] == 'n' &&
1732
- cp[4] == 'e') {
1733
- SkipChars(ts, 5);
1734
- while ((c = GetChar(ts)) != '\n' && ScanAsSpace(c))
1735
- continue;
1736
- if (JS7_ISDEC(c)) {
1737
- line = JS7_UNDEC(c);
1738
- while ((c = GetChar(ts)) != EOF && JS7_ISDEC(c)) {
1739
- temp = 10 * line + JS7_UNDEC(c);
1740
- if (temp < line) {
1741
- /* Ignore overlarge line numbers. */
1742
- goto skipline;
1743
- }
1744
- line = temp;
1745
- }
1746
- while (c != '\n' && ScanAsSpace(c))
1747
- c = GetChar(ts);
1748
- i = 0;
1749
- if (c == '"') {
1750
- while ((c = GetChar(ts)) != EOF && c != '"') {
1751
- if (c == '\n') {
1752
- UngetChar(ts, c);
1753
- goto skipline;
1754
- }
1755
- if ((c >> 8) != 0 || i >= sizeof filename - 1)
1756
- goto skipline;
1757
- filename[i++] = (char) c;
1758
- }
1759
- if (c == '"') {
1760
- while ((c = GetChar(ts)) != '\n' &&
1761
- ScanAsSpace(c)) {
1762
- continue;
1763
- }
1764
- }
1765
- }
1766
- filename[i] = '\0';
1767
- if (c == '\n') {
1768
- if (i > 0) {
1769
- if (ts->flags & TSF_OWNFILENAME)
1770
- JS_free(cx, (void *) ts->filename);
1771
- ts->filename = JS_strdup(cx, filename);
1772
- if (!ts->filename)
1773
- goto error;
1774
- ts->flags |= TSF_OWNFILENAME;
1775
- }
1776
- ts->lineno = line;
1777
- }
1778
- }
1779
- UngetChar(ts, c);
1780
- }
1781
- }
1782
-
1783
- skipline:
1784
- /* Optimize line skipping if we are not in an HTML comment. */
1785
- if (ts->flags & TSF_IN_HTML_COMMENT) {
1786
- while ((c = GetChar(ts)) != EOF && c != '\n') {
1787
- if (c == '-' && MatchChar(ts, '-') && MatchChar(ts, '>'))
1788
- ts->flags &= ~TSF_IN_HTML_COMMENT;
1789
- }
1790
- } else {
1791
- while ((c = GetChar(ts)) != EOF && c != '\n')
1792
- continue;
1793
- }
1794
- UngetChar(ts, c);
1795
- ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
1796
- goto retry;
1797
- }
1798
-
1799
- if (MatchChar(ts, '*')) {
1800
- while ((c = GetChar(ts)) != EOF &&
1801
- !(c == '*' && MatchChar(ts, '/'))) {
1802
- /* Ignore all characters until comment close. */
1803
- }
1804
- if (c == EOF) {
1805
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1806
- JSMSG_UNTERMINATED_COMMENT);
1807
- goto error;
1808
- }
1809
- ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
1810
- goto retry;
1811
- }
1812
-
1813
- if (ts->flags & TSF_OPERAND) {
1814
- uintN flags;
1815
- JSBool inCharClass = JS_FALSE;
1816
-
1817
- INIT_TOKENBUF();
1818
- for (;;) {
1819
- c = GetChar(ts);
1820
- if (c == '\n' || c == EOF) {
1821
- UngetChar(ts, c);
1822
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1823
- JSMSG_UNTERMINATED_REGEXP);
1824
- goto error;
1825
- }
1826
- if (c == '\\') {
1827
- ADD_TO_TOKENBUF(c);
1828
- c = GetChar(ts);
1829
- } else if (c == '[') {
1830
- inCharClass = JS_TRUE;
1831
- } else if (c == ']') {
1832
- inCharClass = JS_FALSE;
1833
- } else if (c == '/' && !inCharClass) {
1834
- /* For compat with IE, allow unescaped / in char classes. */
1835
- break;
1836
- }
1837
- ADD_TO_TOKENBUF(c);
1838
- }
1839
- for (flags = 0; ; ) {
1840
- c = PeekChar(ts);
1841
- if (c == 'g')
1842
- flags |= JSREG_GLOB;
1843
- else if (c == 'i')
1844
- flags |= JSREG_FOLD;
1845
- else if (c == 'm')
1846
- flags |= JSREG_MULTILINE;
1847
- else if (c == 'y')
1848
- flags |= JSREG_STICKY;
1849
- else
1850
- break;
1851
- GetChar(ts);
1852
- }
1853
- c = PeekChar(ts);
1854
- if (JS7_ISLET(c)) {
1855
- tp->ptr = ts->linebuf.ptr - 1;
1856
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1857
- JSMSG_BAD_REGEXP_FLAG);
1858
- (void) GetChar(ts);
1859
- goto error;
1860
- }
1861
- /* XXXbe fix jsregexp.c so it doesn't depend on NUL termination */
1862
- if (!TOKENBUF_OK())
1863
- goto error;
1864
- NUL_TERM_TOKENBUF();
1865
- tp->t_reflags = flags;
1866
- tt = TOK_REGEXP;
1867
- break;
1868
- }
1869
-
1870
- tp->t_op = JSOP_DIV;
1871
- tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
1872
- break;
1873
-
1874
- case '%':
1875
- tp->t_op = JSOP_MOD;
1876
- tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
1877
- break;
1878
-
1879
- case '~':
1880
- tp->t_op = JSOP_BITNOT;
1881
- tt = TOK_UNARYOP;
1882
- break;
1883
-
1884
- case '+':
1885
- if (MatchChar(ts, '=')) {
1886
- tp->t_op = JSOP_ADD;
1887
- tt = TOK_ASSIGN;
1888
- } else if (MatchChar(ts, c)) {
1889
- tt = TOK_INC;
1890
- } else {
1891
- tp->t_op = JSOP_POS;
1892
- tt = TOK_PLUS;
1893
- }
1894
- break;
1895
-
1896
- case '-':
1897
- if (MatchChar(ts, '=')) {
1898
- tp->t_op = JSOP_SUB;
1899
- tt = TOK_ASSIGN;
1900
- } else if (MatchChar(ts, c)) {
1901
- if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE)) {
1902
- ts->flags &= ~TSF_IN_HTML_COMMENT;
1903
- goto skipline;
1904
- }
1905
- tt = TOK_DEC;
1906
- } else {
1907
- tp->t_op = JSOP_NEG;
1908
- tt = TOK_MINUS;
1909
- }
1910
- break;
1911
-
1912
- #if JS_HAS_SHARP_VARS
1913
- case '#':
1914
- {
1915
- uint32 n;
1916
-
1917
- c = GetChar(ts);
1918
- if (!JS7_ISDEC(c)) {
1919
- UngetChar(ts, c);
1920
- goto badchar;
1921
- }
1922
- n = (uint32)JS7_UNDEC(c);
1923
- for (;;) {
1924
- c = GetChar(ts);
1925
- if (!JS7_ISDEC(c))
1926
- break;
1927
- n = 10 * n + JS7_UNDEC(c);
1928
- if (n >= UINT16_LIMIT) {
1929
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1930
- JSMSG_SHARPVAR_TOO_BIG);
1931
- goto error;
1932
- }
1933
- }
1934
- tp->t_dval = (jsdouble) n;
1935
- if (JS_HAS_STRICT_OPTION(cx) &&
1936
- (c == '=' || c == '#')) {
1937
- char buf[20];
1938
- JS_snprintf(buf, sizeof buf, "#%u%c", n, c);
1939
- if (!js_ReportCompileErrorNumber(cx, ts, NULL,
1940
- JSREPORT_WARNING |
1941
- JSREPORT_STRICT,
1942
- JSMSG_DEPRECATED_USAGE,
1943
- buf)) {
1944
- goto error;
1945
- }
1946
- }
1947
- if (c == '=')
1948
- tt = TOK_DEFSHARP;
1949
- else if (c == '#')
1950
- tt = TOK_USESHARP;
1951
- else
1952
- goto badchar;
1953
- break;
1954
- }
1955
- #endif /* JS_HAS_SHARP_VARS */
1956
-
1957
- #if JS_HAS_SHARP_VARS || JS_HAS_XML_SUPPORT
1958
- badchar:
1959
- #endif
1960
-
1961
- default:
1962
- js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1963
- JSMSG_ILLEGAL_CHARACTER);
1964
- goto error;
1965
- }
1966
-
1967
- out:
1968
- JS_ASSERT(tt != TOK_EOL);
1969
- ts->flags |= TSF_DIRTYLINE;
1970
-
1971
- eol_out:
1972
- if (!STRING_BUFFER_OK(&ts->tokenbuf))
1973
- tt = TOK_ERROR;
1974
- JS_ASSERT(tt < TOK_LIMIT);
1975
- tp->pos.end.index = ts->linepos +
1976
- PTRDIFF(ts->linebuf.ptr, ts->linebuf.base, jschar) -
1977
- ts->ungetpos;
1978
- tp->type = tt;
1979
- return tt;
1980
-
1981
- error:
1982
- tt = TOK_ERROR;
1983
- ts->flags |= TSF_ERROR;
1984
- goto out;
1985
-
1986
- #undef INIT_TOKENBUF
1987
- #undef TOKENBUF_LENGTH
1988
- #undef TOKENBUF_OK
1989
- #undef TOKENBUF_TO_ATOM
1990
- #undef ADD_TO_TOKENBUF
1991
- #undef TOKENBUF_BASE
1992
- #undef TOKENBUF_CHAR
1993
- #undef TRIM_TOKENBUF
1994
- #undef NUL_TERM_TOKENBUF
1995
- }
1996
-
1997
- void
1998
- js_UngetToken(JSTokenStream *ts)
1999
- {
2000
- JS_ASSERT(ts->lookahead < NTOKENS_MASK);
2001
- ts->lookahead++;
2002
- ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
2003
- }
2004
-
2005
- JSBool
2006
- js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
2007
- {
2008
- if (js_GetToken(cx, ts) == tt)
2009
- return JS_TRUE;
2010
- js_UngetToken(ts);
2011
- return JS_FALSE;
2012
- }