johnson 2.0.0.pre1 → 2.0.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }