libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,1398 @@
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #include "v8.h"
29
+
30
+ #if defined(V8_TARGET_ARCH_X64)
31
+
32
+ #include "serialize.h"
33
+ #include "unicode.h"
34
+ #include "log.h"
35
+ #include "regexp-stack.h"
36
+ #include "macro-assembler.h"
37
+ #include "regexp-macro-assembler.h"
38
+ #include "x64/regexp-macro-assembler-x64.h"
39
+
40
+ namespace v8 {
41
+ namespace internal {
42
+
43
+ #ifndef V8_INTERPRETED_REGEXP
44
+
45
+ /*
46
+ * This assembler uses the following register assignment convention
47
+ * - rdx : currently loaded character(s) as ASCII or UC16. Must be loaded using
48
+ * LoadCurrentCharacter before using any of the dispatch methods.
49
+ * - rdi : current position in input, as negative offset from end of string.
50
+ * Please notice that this is the byte offset, not the character
51
+ * offset! Is always a 32-bit signed (negative) offset, but must be
52
+ * maintained sign-extended to 64 bits, since it is used as index.
53
+ * - rsi : end of input (points to byte after last character in input),
54
+ * so that rsi+rdi points to the current character.
55
+ * - rbp : frame pointer. Used to access arguments, local variables and
56
+ * RegExp registers.
57
+ * - rsp : points to tip of C stack.
58
+ * - rcx : points to tip of backtrack stack. The backtrack stack contains
59
+ * only 32-bit values. Most are offsets from some base (e.g., character
60
+ * positions from end of string or code location from Code* pointer).
61
+ * - r8 : code object pointer. Used to convert between absolute and
62
+ * code-object-relative addresses.
63
+ *
64
+ * The registers rax, rbx, r9 and r11 are free to use for computations.
65
+ * If changed to use r12+, they should be saved as callee-save registers.
66
+ * The macro assembler special registers r12 and r13 (kSmiConstantRegister,
67
+ * kRootRegister) aren't special during execution of RegExp code (they don't
68
+ * hold the values assumed when creating JS code), so no Smi or Root related
69
+ * macro operations can be used.
70
+ *
71
+ * Each call to a C++ method should retain these registers.
72
+ *
73
+ * The stack will have the following content, in some order, indexable from the
74
+ * frame pointer (see, e.g., kStackHighEnd):
75
+ * - Isolate* isolate (Address of the current isolate)
76
+ * - direct_call (if 1, direct call from JavaScript code, if 0 call
77
+ * through the runtime system)
78
+ * - stack_area_base (High end of the memory area to use as
79
+ * backtracking stack)
80
+ * - int* capture_array (int[num_saved_registers_], for output).
81
+ * - end of input (Address of end of string)
82
+ * - start of input (Address of first character in string)
83
+ * - start index (character index of start)
84
+ * - String* input_string (input string)
85
+ * - return address
86
+ * - backup of callee save registers (rbx, possibly rsi and rdi).
87
+ * - Offset of location before start of input (effectively character
88
+ * position -1). Used to initialize capture registers to a non-position.
89
+ * - At start of string (if 1, we are starting at the start of the
90
+ * string, otherwise 0)
91
+ * - register 0 rbp[-n] (Only positions must be stored in the first
92
+ * - register 1 rbp[-n-8] num_saved_registers_ registers)
93
+ * - ...
94
+ *
95
+ * The first num_saved_registers_ registers are initialized to point to
96
+ * "character -1" in the string (i.e., char_size() bytes before the first
97
+ * character of the string). The remaining registers starts out uninitialized.
98
+ *
99
+ * The first seven values must be provided by the calling code by
100
+ * calling the code's entry address cast to a function pointer with the
101
+ * following signature:
102
+ * int (*match)(String* input_string,
103
+ * int start_index,
104
+ * Address start,
105
+ * Address end,
106
+ * int* capture_output_array,
107
+ * bool at_start,
108
+ * byte* stack_area_base,
109
+ * bool direct_call)
110
+ */
111
+
112
+ #define __ ACCESS_MASM((&masm_))
113
+
114
+ RegExpMacroAssemblerX64::RegExpMacroAssemblerX64(
115
+ Mode mode,
116
+ int registers_to_save)
117
+ : masm_(Isolate::Current(), NULL, kRegExpCodeSize),
118
+ no_root_array_scope_(&masm_),
119
+ code_relative_fixup_positions_(4),
120
+ mode_(mode),
121
+ num_registers_(registers_to_save),
122
+ num_saved_registers_(registers_to_save),
123
+ entry_label_(),
124
+ start_label_(),
125
+ success_label_(),
126
+ backtrack_label_(),
127
+ exit_label_() {
128
+ ASSERT_EQ(0, registers_to_save % 2);
129
+ __ jmp(&entry_label_); // We'll write the entry code when we know more.
130
+ __ bind(&start_label_); // And then continue from here.
131
+ }
132
+
133
+
134
+ RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() {
135
+ // Unuse labels in case we throw away the assembler without calling GetCode.
136
+ entry_label_.Unuse();
137
+ start_label_.Unuse();
138
+ success_label_.Unuse();
139
+ backtrack_label_.Unuse();
140
+ exit_label_.Unuse();
141
+ check_preempt_label_.Unuse();
142
+ stack_overflow_label_.Unuse();
143
+ }
144
+
145
+
146
+ int RegExpMacroAssemblerX64::stack_limit_slack() {
147
+ return RegExpStack::kStackLimitSlack;
148
+ }
149
+
150
+
151
+ void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) {
152
+ if (by != 0) {
153
+ __ addq(rdi, Immediate(by * char_size()));
154
+ }
155
+ }
156
+
157
+
158
+ void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) {
159
+ ASSERT(reg >= 0);
160
+ ASSERT(reg < num_registers_);
161
+ if (by != 0) {
162
+ __ addq(register_location(reg), Immediate(by));
163
+ }
164
+ }
165
+
166
+
167
+ void RegExpMacroAssemblerX64::Backtrack() {
168
+ CheckPreemption();
169
+ // Pop Code* offset from backtrack stack, add Code* and jump to location.
170
+ Pop(rbx);
171
+ __ addq(rbx, code_object_pointer());
172
+ __ jmp(rbx);
173
+ }
174
+
175
+
176
+ void RegExpMacroAssemblerX64::Bind(Label* label) {
177
+ __ bind(label);
178
+ }
179
+
180
+
181
+ void RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) {
182
+ __ cmpl(current_character(), Immediate(c));
183
+ BranchOrBacktrack(equal, on_equal);
184
+ }
185
+
186
+
187
+ void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) {
188
+ __ cmpl(current_character(), Immediate(limit));
189
+ BranchOrBacktrack(greater, on_greater);
190
+ }
191
+
192
+
193
+ void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
194
+ Label not_at_start;
195
+ // Did we start the match at the start of the string at all?
196
+ __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
197
+ BranchOrBacktrack(not_equal, &not_at_start);
198
+ // If we did, are we still at the start of the input?
199
+ __ lea(rax, Operand(rsi, rdi, times_1, 0));
200
+ __ cmpq(rax, Operand(rbp, kInputStart));
201
+ BranchOrBacktrack(equal, on_at_start);
202
+ __ bind(&not_at_start);
203
+ }
204
+
205
+
206
+ void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
207
+ // Did we start the match at the start of the string at all?
208
+ __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
209
+ BranchOrBacktrack(not_equal, on_not_at_start);
210
+ // If we did, are we still at the start of the input?
211
+ __ lea(rax, Operand(rsi, rdi, times_1, 0));
212
+ __ cmpq(rax, Operand(rbp, kInputStart));
213
+ BranchOrBacktrack(not_equal, on_not_at_start);
214
+ }
215
+
216
+
217
+ void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) {
218
+ __ cmpl(current_character(), Immediate(limit));
219
+ BranchOrBacktrack(less, on_less);
220
+ }
221
+
222
+
223
+ void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str,
224
+ int cp_offset,
225
+ Label* on_failure,
226
+ bool check_end_of_string) {
227
+ #ifdef DEBUG
228
+ // If input is ASCII, don't even bother calling here if the string to
229
+ // match contains a non-ascii character.
230
+ if (mode_ == ASCII) {
231
+ ASSERT(String::IsAscii(str.start(), str.length()));
232
+ }
233
+ #endif
234
+ int byte_length = str.length() * char_size();
235
+ int byte_offset = cp_offset * char_size();
236
+ if (check_end_of_string) {
237
+ // Check that there are at least str.length() characters left in the input.
238
+ __ cmpl(rdi, Immediate(-(byte_offset + byte_length)));
239
+ BranchOrBacktrack(greater, on_failure);
240
+ }
241
+
242
+ if (on_failure == NULL) {
243
+ // Instead of inlining a backtrack, (re)use the global backtrack target.
244
+ on_failure = &backtrack_label_;
245
+ }
246
+
247
+ // Do one character test first to minimize loading for the case that
248
+ // we don't match at all (loading more than one character introduces that
249
+ // chance of reading unaligned and reading across cache boundaries).
250
+ // If the first character matches, expect a larger chance of matching the
251
+ // string, and start loading more characters at a time.
252
+ if (mode_ == ASCII) {
253
+ __ cmpb(Operand(rsi, rdi, times_1, byte_offset),
254
+ Immediate(static_cast<int8_t>(str[0])));
255
+ } else {
256
+ // Don't use 16-bit immediate. The size changing prefix throws off
257
+ // pre-decoding.
258
+ __ movzxwl(rax,
259
+ Operand(rsi, rdi, times_1, byte_offset));
260
+ __ cmpl(rax, Immediate(static_cast<int32_t>(str[0])));
261
+ }
262
+ BranchOrBacktrack(not_equal, on_failure);
263
+
264
+ __ lea(rbx, Operand(rsi, rdi, times_1, 0));
265
+ for (int i = 1, n = str.length(); i < n; ) {
266
+ if (mode_ == ASCII) {
267
+ if (i + 8 <= n) {
268
+ uint64_t combined_chars =
269
+ (static_cast<uint64_t>(str[i + 0]) << 0) ||
270
+ (static_cast<uint64_t>(str[i + 1]) << 8) ||
271
+ (static_cast<uint64_t>(str[i + 2]) << 16) ||
272
+ (static_cast<uint64_t>(str[i + 3]) << 24) ||
273
+ (static_cast<uint64_t>(str[i + 4]) << 32) ||
274
+ (static_cast<uint64_t>(str[i + 5]) << 40) ||
275
+ (static_cast<uint64_t>(str[i + 6]) << 48) ||
276
+ (static_cast<uint64_t>(str[i + 7]) << 56);
277
+ __ movq(rax, combined_chars, RelocInfo::NONE);
278
+ __ cmpq(rax, Operand(rbx, byte_offset + i));
279
+ i += 8;
280
+ } else if (i + 4 <= n) {
281
+ uint32_t combined_chars =
282
+ (static_cast<uint32_t>(str[i + 0]) << 0) ||
283
+ (static_cast<uint32_t>(str[i + 1]) << 8) ||
284
+ (static_cast<uint32_t>(str[i + 2]) << 16) ||
285
+ (static_cast<uint32_t>(str[i + 3]) << 24);
286
+ __ cmpl(Operand(rbx, byte_offset + i), Immediate(combined_chars));
287
+ i += 4;
288
+ } else {
289
+ __ cmpb(Operand(rbx, byte_offset + i),
290
+ Immediate(static_cast<int8_t>(str[i])));
291
+ i++;
292
+ }
293
+ } else {
294
+ ASSERT(mode_ == UC16);
295
+ if (i + 4 <= n) {
296
+ uint64_t combined_chars = *reinterpret_cast<const uint64_t*>(&str[i]);
297
+ __ movq(rax, combined_chars, RelocInfo::NONE);
298
+ __ cmpq(rax,
299
+ Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
300
+ i += 4;
301
+ } else if (i + 2 <= n) {
302
+ uint32_t combined_chars = *reinterpret_cast<const uint32_t*>(&str[i]);
303
+ __ cmpl(Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)),
304
+ Immediate(combined_chars));
305
+ i += 2;
306
+ } else {
307
+ __ movzxwl(rax,
308
+ Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
309
+ __ cmpl(rax, Immediate(str[i]));
310
+ i++;
311
+ }
312
+ }
313
+ BranchOrBacktrack(not_equal, on_failure);
314
+ }
315
+ }
316
+
317
+
318
+ void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
319
+ Label fallthrough;
320
+ __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
321
+ __ j(not_equal, &fallthrough);
322
+ Drop();
323
+ BranchOrBacktrack(no_condition, on_equal);
324
+ __ bind(&fallthrough);
325
+ }
326
+
327
+
328
+ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
329
+ int start_reg,
330
+ Label* on_no_match) {
331
+ Label fallthrough;
332
+ __ movq(rdx, register_location(start_reg)); // Offset of start of capture
333
+ __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture
334
+ __ subq(rbx, rdx); // Length of capture.
335
+
336
+ // -----------------------
337
+ // rdx = Start offset of capture.
338
+ // rbx = Length of capture
339
+
340
+ // If length is negative, this code will fail (it's a symptom of a partial or
341
+ // illegal capture where start of capture after end of capture).
342
+ // This must not happen (no back-reference can reference a capture that wasn't
343
+ // closed before in the reg-exp, and we must not generate code that can cause
344
+ // this condition).
345
+
346
+ // If length is zero, either the capture is empty or it is nonparticipating.
347
+ // In either case succeed immediately.
348
+ __ j(equal, &fallthrough);
349
+
350
+ if (mode_ == ASCII) {
351
+ Label loop_increment;
352
+ if (on_no_match == NULL) {
353
+ on_no_match = &backtrack_label_;
354
+ }
355
+
356
+ __ lea(r9, Operand(rsi, rdx, times_1, 0));
357
+ __ lea(r11, Operand(rsi, rdi, times_1, 0));
358
+ __ addq(rbx, r9); // End of capture
359
+ // ---------------------
360
+ // r11 - current input character address
361
+ // r9 - current capture character address
362
+ // rbx - end of capture
363
+
364
+ Label loop;
365
+ __ bind(&loop);
366
+ __ movzxbl(rdx, Operand(r9, 0));
367
+ __ movzxbl(rax, Operand(r11, 0));
368
+ // al - input character
369
+ // dl - capture character
370
+ __ cmpb(rax, rdx);
371
+ __ j(equal, &loop_increment);
372
+
373
+ // Mismatch, try case-insensitive match (converting letters to lower-case).
374
+ // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's
375
+ // a match.
376
+ __ or_(rax, Immediate(0x20)); // Convert match character to lower-case.
377
+ __ or_(rdx, Immediate(0x20)); // Convert capture character to lower-case.
378
+ __ cmpb(rax, rdx);
379
+ __ j(not_equal, on_no_match); // Definitely not equal.
380
+ __ subb(rax, Immediate('a'));
381
+ __ cmpb(rax, Immediate('z' - 'a'));
382
+ __ j(above, on_no_match); // Weren't letters anyway.
383
+
384
+ __ bind(&loop_increment);
385
+ // Increment pointers into match and capture strings.
386
+ __ addq(r11, Immediate(1));
387
+ __ addq(r9, Immediate(1));
388
+ // Compare to end of capture, and loop if not done.
389
+ __ cmpq(r9, rbx);
390
+ __ j(below, &loop);
391
+
392
+ // Compute new value of character position after the matched part.
393
+ __ movq(rdi, r11);
394
+ __ subq(rdi, rsi);
395
+ } else {
396
+ ASSERT(mode_ == UC16);
397
+ // Save important/volatile registers before calling C function.
398
+ #ifndef _WIN64
399
+ // Caller save on Linux and callee save in Windows.
400
+ __ push(rsi);
401
+ __ push(rdi);
402
+ #endif
403
+ __ push(backtrack_stackpointer());
404
+
405
+ static const int num_arguments = 4;
406
+ __ PrepareCallCFunction(num_arguments);
407
+
408
+ // Put arguments into parameter registers. Parameters are
409
+ // Address byte_offset1 - Address captured substring's start.
410
+ // Address byte_offset2 - Address of current character position.
411
+ // size_t byte_length - length of capture in bytes(!)
412
+ // Isolate* isolate
413
+ #ifdef _WIN64
414
+ // Compute and set byte_offset1 (start of capture).
415
+ __ lea(rcx, Operand(rsi, rdx, times_1, 0));
416
+ // Set byte_offset2.
417
+ __ lea(rdx, Operand(rsi, rdi, times_1, 0));
418
+ // Set byte_length.
419
+ __ movq(r8, rbx);
420
+ // Isolate.
421
+ __ LoadAddress(r9, ExternalReference::isolate_address());
422
+ #else // AMD64 calling convention
423
+ // Compute byte_offset2 (current position = rsi+rdi).
424
+ __ lea(rax, Operand(rsi, rdi, times_1, 0));
425
+ // Compute and set byte_offset1 (start of capture).
426
+ __ lea(rdi, Operand(rsi, rdx, times_1, 0));
427
+ // Set byte_offset2.
428
+ __ movq(rsi, rax);
429
+ // Set byte_length.
430
+ __ movq(rdx, rbx);
431
+ // Isolate.
432
+ __ LoadAddress(rcx, ExternalReference::isolate_address());
433
+ #endif
434
+ ExternalReference compare =
435
+ ExternalReference::re_case_insensitive_compare_uc16(masm_.isolate());
436
+ __ CallCFunction(compare, num_arguments);
437
+
438
+ // Restore original values before reacting on result value.
439
+ __ Move(code_object_pointer(), masm_.CodeObject());
440
+ __ pop(backtrack_stackpointer());
441
+ #ifndef _WIN64
442
+ __ pop(rdi);
443
+ __ pop(rsi);
444
+ #endif
445
+
446
+ // Check if function returned non-zero for success or zero for failure.
447
+ __ testq(rax, rax);
448
+ BranchOrBacktrack(zero, on_no_match);
449
+ // On success, increment position by length of capture.
450
+ // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs).
451
+ __ addq(rdi, rbx);
452
+ }
453
+ __ bind(&fallthrough);
454
+ }
455
+
456
+
457
+ void RegExpMacroAssemblerX64::CheckNotBackReference(
458
+ int start_reg,
459
+ Label* on_no_match) {
460
+ Label fallthrough;
461
+
462
+ // Find length of back-referenced capture.
463
+ __ movq(rdx, register_location(start_reg));
464
+ __ movq(rax, register_location(start_reg + 1));
465
+ __ subq(rax, rdx); // Length to check.
466
+
467
+ // Fail on partial or illegal capture (start of capture after end of capture).
468
+ // This must not happen (no back-reference can reference a capture that wasn't
469
+ // closed before in the reg-exp).
470
+ __ Check(greater_equal, "Invalid capture referenced");
471
+
472
+ // Succeed on empty capture (including non-participating capture)
473
+ __ j(equal, &fallthrough);
474
+
475
+ // -----------------------
476
+ // rdx - Start of capture
477
+ // rax - length of capture
478
+
479
+ // Check that there are sufficient characters left in the input.
480
+ __ movl(rbx, rdi);
481
+ __ addl(rbx, rax);
482
+ BranchOrBacktrack(greater, on_no_match);
483
+
484
+ // Compute pointers to match string and capture string
485
+ __ lea(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match.
486
+ __ addq(rdx, rsi); // Start of capture.
487
+ __ lea(r9, Operand(rdx, rax, times_1, 0)); // End of capture
488
+
489
+ // -----------------------
490
+ // rbx - current capture character address.
491
+ // rbx - current input character address .
492
+ // r9 - end of input to match (capture length after rbx).
493
+
494
+ Label loop;
495
+ __ bind(&loop);
496
+ if (mode_ == ASCII) {
497
+ __ movzxbl(rax, Operand(rdx, 0));
498
+ __ cmpb(rax, Operand(rbx, 0));
499
+ } else {
500
+ ASSERT(mode_ == UC16);
501
+ __ movzxwl(rax, Operand(rdx, 0));
502
+ __ cmpw(rax, Operand(rbx, 0));
503
+ }
504
+ BranchOrBacktrack(not_equal, on_no_match);
505
+ // Increment pointers into capture and match string.
506
+ __ addq(rbx, Immediate(char_size()));
507
+ __ addq(rdx, Immediate(char_size()));
508
+ // Check if we have reached end of match area.
509
+ __ cmpq(rdx, r9);
510
+ __ j(below, &loop);
511
+
512
+ // Success.
513
+ // Set current character position to position after match.
514
+ __ movq(rdi, rbx);
515
+ __ subq(rdi, rsi);
516
+
517
+ __ bind(&fallthrough);
518
+ }
519
+
520
+
521
+ void RegExpMacroAssemblerX64::CheckNotRegistersEqual(int reg1,
522
+ int reg2,
523
+ Label* on_not_equal) {
524
+ __ movq(rax, register_location(reg1));
525
+ __ cmpq(rax, register_location(reg2));
526
+ BranchOrBacktrack(not_equal, on_not_equal);
527
+ }
528
+
529
+
530
+ void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
531
+ Label* on_not_equal) {
532
+ __ cmpl(current_character(), Immediate(c));
533
+ BranchOrBacktrack(not_equal, on_not_equal);
534
+ }
535
+
536
+
537
+ void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c,
538
+ uint32_t mask,
539
+ Label* on_equal) {
540
+ __ movl(rax, current_character());
541
+ __ and_(rax, Immediate(mask));
542
+ __ cmpl(rax, Immediate(c));
543
+ BranchOrBacktrack(equal, on_equal);
544
+ }
545
+
546
+
547
+ void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c,
548
+ uint32_t mask,
549
+ Label* on_not_equal) {
550
+ __ movl(rax, current_character());
551
+ __ and_(rax, Immediate(mask));
552
+ __ cmpl(rax, Immediate(c));
553
+ BranchOrBacktrack(not_equal, on_not_equal);
554
+ }
555
+
556
+
557
+ void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd(
558
+ uc16 c,
559
+ uc16 minus,
560
+ uc16 mask,
561
+ Label* on_not_equal) {
562
+ ASSERT(minus < String::kMaxUC16CharCode);
563
+ __ lea(rax, Operand(current_character(), -minus));
564
+ __ and_(rax, Immediate(mask));
565
+ __ cmpl(rax, Immediate(c));
566
+ BranchOrBacktrack(not_equal, on_not_equal);
567
+ }
568
+
569
+
570
+ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
571
+ Label* on_no_match) {
572
+ // Range checks (c in min..max) are generally implemented by an unsigned
573
+ // (c - min) <= (max - min) check, using the sequence:
574
+ // lea(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min))
575
+ // cmp(rax, Immediate(max - min))
576
+ switch (type) {
577
+ case 's':
578
+ // Match space-characters
579
+ if (mode_ == ASCII) {
580
+ // ASCII space characters are '\t'..'\r' and ' '.
581
+ Label success;
582
+ __ cmpl(current_character(), Immediate(' '));
583
+ __ j(equal, &success);
584
+ // Check range 0x09..0x0d
585
+ __ lea(rax, Operand(current_character(), -'\t'));
586
+ __ cmpl(rax, Immediate('\r' - '\t'));
587
+ BranchOrBacktrack(above, on_no_match);
588
+ __ bind(&success);
589
+ return true;
590
+ }
591
+ return false;
592
+ case 'S':
593
+ // Match non-space characters.
594
+ if (mode_ == ASCII) {
595
+ // ASCII space characters are '\t'..'\r' and ' '.
596
+ __ cmpl(current_character(), Immediate(' '));
597
+ BranchOrBacktrack(equal, on_no_match);
598
+ __ lea(rax, Operand(current_character(), -'\t'));
599
+ __ cmpl(rax, Immediate('\r' - '\t'));
600
+ BranchOrBacktrack(below_equal, on_no_match);
601
+ return true;
602
+ }
603
+ return false;
604
+ case 'd':
605
+ // Match ASCII digits ('0'..'9')
606
+ __ lea(rax, Operand(current_character(), -'0'));
607
+ __ cmpl(rax, Immediate('9' - '0'));
608
+ BranchOrBacktrack(above, on_no_match);
609
+ return true;
610
+ case 'D':
611
+ // Match non ASCII-digits
612
+ __ lea(rax, Operand(current_character(), -'0'));
613
+ __ cmpl(rax, Immediate('9' - '0'));
614
+ BranchOrBacktrack(below_equal, on_no_match);
615
+ return true;
616
+ case '.': {
617
+ // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
618
+ __ movl(rax, current_character());
619
+ __ xor_(rax, Immediate(0x01));
620
+ // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
621
+ __ subl(rax, Immediate(0x0b));
622
+ __ cmpl(rax, Immediate(0x0c - 0x0b));
623
+ BranchOrBacktrack(below_equal, on_no_match);
624
+ if (mode_ == UC16) {
625
+ // Compare original value to 0x2028 and 0x2029, using the already
626
+ // computed (current_char ^ 0x01 - 0x0b). I.e., check for
627
+ // 0x201d (0x2028 - 0x0b) or 0x201e.
628
+ __ subl(rax, Immediate(0x2028 - 0x0b));
629
+ __ cmpl(rax, Immediate(0x2029 - 0x2028));
630
+ BranchOrBacktrack(below_equal, on_no_match);
631
+ }
632
+ return true;
633
+ }
634
+ case 'n': {
635
+ // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
636
+ __ movl(rax, current_character());
637
+ __ xor_(rax, Immediate(0x01));
638
+ // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
639
+ __ subl(rax, Immediate(0x0b));
640
+ __ cmpl(rax, Immediate(0x0c - 0x0b));
641
+ if (mode_ == ASCII) {
642
+ BranchOrBacktrack(above, on_no_match);
643
+ } else {
644
+ Label done;
645
+ BranchOrBacktrack(below_equal, &done);
646
+ // Compare original value to 0x2028 and 0x2029, using the already
647
+ // computed (current_char ^ 0x01 - 0x0b). I.e., check for
648
+ // 0x201d (0x2028 - 0x0b) or 0x201e.
649
+ __ subl(rax, Immediate(0x2028 - 0x0b));
650
+ __ cmpl(rax, Immediate(0x2029 - 0x2028));
651
+ BranchOrBacktrack(above, on_no_match);
652
+ __ bind(&done);
653
+ }
654
+ return true;
655
+ }
656
+ case 'w': {
657
+ if (mode_ != ASCII) {
658
+ // Table is 128 entries, so all ASCII characters can be tested.
659
+ __ cmpl(current_character(), Immediate('z'));
660
+ BranchOrBacktrack(above, on_no_match);
661
+ }
662
+ __ movq(rbx, ExternalReference::re_word_character_map());
663
+ ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char.
664
+ ExternalReference word_map = ExternalReference::re_word_character_map();
665
+ __ testb(Operand(rbx, current_character(), times_1, 0),
666
+ current_character());
667
+ BranchOrBacktrack(zero, on_no_match);
668
+ return true;
669
+ }
670
+ case 'W': {
671
+ Label done;
672
+ if (mode_ != ASCII) {
673
+ // Table is 128 entries, so all ASCII characters can be tested.
674
+ __ cmpl(current_character(), Immediate('z'));
675
+ __ j(above, &done);
676
+ }
677
+ __ movq(rbx, ExternalReference::re_word_character_map());
678
+ ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char.
679
+ ExternalReference word_map = ExternalReference::re_word_character_map();
680
+ __ testb(Operand(rbx, current_character(), times_1, 0),
681
+ current_character());
682
+ BranchOrBacktrack(not_zero, on_no_match);
683
+ if (mode_ != ASCII) {
684
+ __ bind(&done);
685
+ }
686
+ return true;
687
+ }
688
+
689
+ case '*':
690
+ // Match any character.
691
+ return true;
692
+ // No custom implementation (yet): s(UC16), S(UC16).
693
+ default:
694
+ return false;
695
+ }
696
+ }
697
+
698
+
699
+ void RegExpMacroAssemblerX64::Fail() {
700
+ ASSERT(FAILURE == 0); // Return value for failure is zero.
701
+ __ Set(rax, 0);
702
+ __ jmp(&exit_label_);
703
+ }
704
+
705
+
706
+ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
707
+ // Finalize code - write the entry point code now we know how many
708
+ // registers we need.
709
+ // Entry code:
710
+ __ bind(&entry_label_);
711
+ // Start new stack frame.
712
+ __ push(rbp);
713
+ __ movq(rbp, rsp);
714
+ // Save parameters and callee-save registers. Order here should correspond
715
+ // to order of kBackup_ebx etc.
716
+ #ifdef _WIN64
717
+ // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
718
+ // Store register parameters in pre-allocated stack slots,
719
+ __ movq(Operand(rbp, kInputString), rcx);
720
+ __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx.
721
+ __ movq(Operand(rbp, kInputStart), r8);
722
+ __ movq(Operand(rbp, kInputEnd), r9);
723
+ // Callee-save on Win64.
724
+ __ push(rsi);
725
+ __ push(rdi);
726
+ __ push(rbx);
727
+ #else
728
+ // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack).
729
+ // Push register parameters on stack for reference.
730
+ ASSERT_EQ(kInputString, -1 * kPointerSize);
731
+ ASSERT_EQ(kStartIndex, -2 * kPointerSize);
732
+ ASSERT_EQ(kInputStart, -3 * kPointerSize);
733
+ ASSERT_EQ(kInputEnd, -4 * kPointerSize);
734
+ ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
735
+ ASSERT_EQ(kStackHighEnd, -6 * kPointerSize);
736
+ __ push(rdi);
737
+ __ push(rsi);
738
+ __ push(rdx);
739
+ __ push(rcx);
740
+ __ push(r8);
741
+ __ push(r9);
742
+
743
+ __ push(rbx); // Callee-save
744
+ #endif
745
+
746
+ __ push(Immediate(0)); // Make room for "at start" constant.
747
+
748
+ // Check if we have space on the stack for registers.
749
+ Label stack_limit_hit;
750
+ Label stack_ok;
751
+
752
+ ExternalReference stack_limit =
753
+ ExternalReference::address_of_stack_limit(masm_.isolate());
754
+ __ movq(rcx, rsp);
755
+ __ movq(kScratchRegister, stack_limit);
756
+ __ subq(rcx, Operand(kScratchRegister, 0));
757
+ // Handle it if the stack pointer is already below the stack limit.
758
+ __ j(below_equal, &stack_limit_hit);
759
+ // Check if there is room for the variable number of registers above
760
+ // the stack limit.
761
+ __ cmpq(rcx, Immediate(num_registers_ * kPointerSize));
762
+ __ j(above_equal, &stack_ok);
763
+ // Exit with OutOfMemory exception. There is not enough space on the stack
764
+ // for our working registers.
765
+ __ Set(rax, EXCEPTION);
766
+ __ jmp(&exit_label_);
767
+
768
+ __ bind(&stack_limit_hit);
769
+ __ Move(code_object_pointer(), masm_.CodeObject());
770
+ CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
771
+ __ testq(rax, rax);
772
+ // If returned value is non-zero, we exit with the returned value as result.
773
+ __ j(not_zero, &exit_label_);
774
+
775
+ __ bind(&stack_ok);
776
+
777
+ // Allocate space on stack for registers.
778
+ __ subq(rsp, Immediate(num_registers_ * kPointerSize));
779
+ // Load string length.
780
+ __ movq(rsi, Operand(rbp, kInputEnd));
781
+ // Load input position.
782
+ __ movq(rdi, Operand(rbp, kInputStart));
783
+ // Set up rdi to be negative offset from string end.
784
+ __ subq(rdi, rsi);
785
+ // Set rax to address of char before start of the string
786
+ // (effectively string position -1).
787
+ __ movq(rbx, Operand(rbp, kStartIndex));
788
+ __ neg(rbx);
789
+ if (mode_ == UC16) {
790
+ __ lea(rax, Operand(rdi, rbx, times_2, -char_size()));
791
+ } else {
792
+ __ lea(rax, Operand(rdi, rbx, times_1, -char_size()));
793
+ }
794
+ // Store this value in a local variable, for use when clearing
795
+ // position registers.
796
+ __ movq(Operand(rbp, kInputStartMinusOne), rax);
797
+
798
+ if (num_saved_registers_ > 0) {
799
+ // Fill saved registers with initial value = start offset - 1
800
+ // Fill in stack push order, to avoid accessing across an unwritten
801
+ // page (a problem on Windows).
802
+ __ Set(rcx, kRegisterZero);
803
+ Label init_loop;
804
+ __ bind(&init_loop);
805
+ __ movq(Operand(rbp, rcx, times_1, 0), rax);
806
+ __ subq(rcx, Immediate(kPointerSize));
807
+ __ cmpq(rcx,
808
+ Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
809
+ __ j(greater, &init_loop);
810
+ }
811
+ // Ensure that we have written to each stack page, in order. Skipping a page
812
+ // on Windows can cause segmentation faults. Assuming page size is 4k.
813
+ const int kPageSize = 4096;
814
+ const int kRegistersPerPage = kPageSize / kPointerSize;
815
+ for (int i = num_saved_registers_ + kRegistersPerPage - 1;
816
+ i < num_registers_;
817
+ i += kRegistersPerPage) {
818
+ __ movq(register_location(i), rax); // One write every page.
819
+ }
820
+
821
+ // Initialize backtrack stack pointer.
822
+ __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
823
+ // Initialize code object pointer.
824
+ __ Move(code_object_pointer(), masm_.CodeObject());
825
+ // Load previous char as initial value of current-character.
826
+ Label at_start;
827
+ __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
828
+ __ j(equal, &at_start);
829
+ LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
830
+ __ jmp(&start_label_);
831
+ __ bind(&at_start);
832
+ __ Set(current_character(), '\n');
833
+ __ jmp(&start_label_);
834
+
835
+
836
+ // Exit code:
837
+ if (success_label_.is_linked()) {
838
+ // Save captures when successful.
839
+ __ bind(&success_label_);
840
+ if (num_saved_registers_ > 0) {
841
+ // copy captures to output
842
+ __ movq(rdx, Operand(rbp, kStartIndex));
843
+ __ movq(rbx, Operand(rbp, kRegisterOutput));
844
+ __ movq(rcx, Operand(rbp, kInputEnd));
845
+ __ subq(rcx, Operand(rbp, kInputStart));
846
+ if (mode_ == UC16) {
847
+ __ lea(rcx, Operand(rcx, rdx, times_2, 0));
848
+ } else {
849
+ __ addq(rcx, rdx);
850
+ }
851
+ for (int i = 0; i < num_saved_registers_; i++) {
852
+ __ movq(rax, register_location(i));
853
+ __ addq(rax, rcx); // Convert to index from start, not end.
854
+ if (mode_ == UC16) {
855
+ __ sar(rax, Immediate(1)); // Convert byte index to character index.
856
+ }
857
+ __ movl(Operand(rbx, i * kIntSize), rax);
858
+ }
859
+ }
860
+ __ Set(rax, SUCCESS);
861
+ }
862
+
863
+ // Exit and return rax
864
+ __ bind(&exit_label_);
865
+
866
+ #ifdef _WIN64
867
+ // Restore callee save registers.
868
+ __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
869
+ __ pop(rbx);
870
+ __ pop(rdi);
871
+ __ pop(rsi);
872
+ // Stack now at rbp.
873
+ #else
874
+ // Restore callee save register.
875
+ __ movq(rbx, Operand(rbp, kBackup_rbx));
876
+ // Skip rsp to rbp.
877
+ __ movq(rsp, rbp);
878
+ #endif
879
+ // Exit function frame, restore previous one.
880
+ __ pop(rbp);
881
+ __ ret(0);
882
+
883
+ // Backtrack code (branch target for conditional backtracks).
884
+ if (backtrack_label_.is_linked()) {
885
+ __ bind(&backtrack_label_);
886
+ Backtrack();
887
+ }
888
+
889
+ Label exit_with_exception;
890
+
891
+ // Preempt-code
892
+ if (check_preempt_label_.is_linked()) {
893
+ SafeCallTarget(&check_preempt_label_);
894
+
895
+ __ push(backtrack_stackpointer());
896
+ __ push(rdi);
897
+
898
+ CallCheckStackGuardState();
899
+ __ testq(rax, rax);
900
+ // If returning non-zero, we should end execution with the given
901
+ // result as return value.
902
+ __ j(not_zero, &exit_label_);
903
+
904
+ // Restore registers.
905
+ __ Move(code_object_pointer(), masm_.CodeObject());
906
+ __ pop(rdi);
907
+ __ pop(backtrack_stackpointer());
908
+ // String might have moved: Reload esi from frame.
909
+ __ movq(rsi, Operand(rbp, kInputEnd));
910
+ SafeReturn();
911
+ }
912
+
913
+ // Backtrack stack overflow code.
914
+ if (stack_overflow_label_.is_linked()) {
915
+ SafeCallTarget(&stack_overflow_label_);
916
+ // Reached if the backtrack-stack limit has been hit.
917
+
918
+ Label grow_failed;
919
+ // Save registers before calling C function
920
+ #ifndef _WIN64
921
+ // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
922
+ __ push(rsi);
923
+ __ push(rdi);
924
+ #endif
925
+
926
+ // Call GrowStack(backtrack_stackpointer())
927
+ static const int num_arguments = 3;
928
+ __ PrepareCallCFunction(num_arguments);
929
+ #ifdef _WIN64
930
+ // Microsoft passes parameters in rcx, rdx, r8.
931
+ // First argument, backtrack stackpointer, is already in rcx.
932
+ __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument
933
+ __ LoadAddress(r8, ExternalReference::isolate_address());
934
+ #else
935
+ // AMD64 ABI passes parameters in rdi, rsi, rdx.
936
+ __ movq(rdi, backtrack_stackpointer()); // First argument.
937
+ __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument.
938
+ __ LoadAddress(rdx, ExternalReference::isolate_address());
939
+ #endif
940
+ ExternalReference grow_stack =
941
+ ExternalReference::re_grow_stack(masm_.isolate());
942
+ __ CallCFunction(grow_stack, num_arguments);
943
+ // If return NULL, we have failed to grow the stack, and
944
+ // must exit with a stack-overflow exception.
945
+ __ testq(rax, rax);
946
+ __ j(equal, &exit_with_exception);
947
+ // Otherwise use return value as new stack pointer.
948
+ __ movq(backtrack_stackpointer(), rax);
949
+ // Restore saved registers and continue.
950
+ __ Move(code_object_pointer(), masm_.CodeObject());
951
+ #ifndef _WIN64
952
+ __ pop(rdi);
953
+ __ pop(rsi);
954
+ #endif
955
+ SafeReturn();
956
+ }
957
+
958
+ if (exit_with_exception.is_linked()) {
959
+ // If any of the code above needed to exit with an exception.
960
+ __ bind(&exit_with_exception);
961
+ // Exit with Result EXCEPTION(-1) to signal thrown exception.
962
+ __ Set(rax, EXCEPTION);
963
+ __ jmp(&exit_label_);
964
+ }
965
+
966
+ FixupCodeRelativePositions();
967
+
968
+ CodeDesc code_desc;
969
+ masm_.GetCode(&code_desc);
970
+ Isolate* isolate = ISOLATE;
971
+ Handle<Code> code = isolate->factory()->NewCode(
972
+ code_desc, Code::ComputeFlags(Code::REGEXP),
973
+ masm_.CodeObject());
974
+ PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
975
+ return Handle<HeapObject>::cast(code);
976
+ }
977
+
978
+
979
+ void RegExpMacroAssemblerX64::GoTo(Label* to) {
980
+ BranchOrBacktrack(no_condition, to);
981
+ }
982
+
983
+
984
+ void RegExpMacroAssemblerX64::IfRegisterGE(int reg,
985
+ int comparand,
986
+ Label* if_ge) {
987
+ __ cmpq(register_location(reg), Immediate(comparand));
988
+ BranchOrBacktrack(greater_equal, if_ge);
989
+ }
990
+
991
+
992
+ void RegExpMacroAssemblerX64::IfRegisterLT(int reg,
993
+ int comparand,
994
+ Label* if_lt) {
995
+ __ cmpq(register_location(reg), Immediate(comparand));
996
+ BranchOrBacktrack(less, if_lt);
997
+ }
998
+
999
+
1000
+ void RegExpMacroAssemblerX64::IfRegisterEqPos(int reg,
1001
+ Label* if_eq) {
1002
+ __ cmpq(rdi, register_location(reg));
1003
+ BranchOrBacktrack(equal, if_eq);
1004
+ }
1005
+
1006
+
1007
+ RegExpMacroAssembler::IrregexpImplementation
1008
+ RegExpMacroAssemblerX64::Implementation() {
1009
+ return kX64Implementation;
1010
+ }
1011
+
1012
+
1013
+ void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset,
1014
+ Label* on_end_of_input,
1015
+ bool check_bounds,
1016
+ int characters) {
1017
+ ASSERT(cp_offset >= -1); // ^ and \b can look behind one character.
1018
+ ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
1019
+ if (check_bounds) {
1020
+ CheckPosition(cp_offset + characters - 1, on_end_of_input);
1021
+ }
1022
+ LoadCurrentCharacterUnchecked(cp_offset, characters);
1023
+ }
1024
+
1025
+
1026
+ void RegExpMacroAssemblerX64::PopCurrentPosition() {
1027
+ Pop(rdi);
1028
+ }
1029
+
1030
+
1031
+ void RegExpMacroAssemblerX64::PopRegister(int register_index) {
1032
+ Pop(rax);
1033
+ __ movq(register_location(register_index), rax);
1034
+ }
1035
+
1036
+
1037
+ void RegExpMacroAssemblerX64::PushBacktrack(Label* label) {
1038
+ Push(label);
1039
+ CheckStackLimit();
1040
+ }
1041
+
1042
+
1043
+ void RegExpMacroAssemblerX64::PushCurrentPosition() {
1044
+ Push(rdi);
1045
+ }
1046
+
1047
+
1048
+ void RegExpMacroAssemblerX64::PushRegister(int register_index,
1049
+ StackCheckFlag check_stack_limit) {
1050
+ __ movq(rax, register_location(register_index));
1051
+ Push(rax);
1052
+ if (check_stack_limit) CheckStackLimit();
1053
+ }
1054
+
1055
+
1056
+ void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) {
1057
+ __ movq(rdi, register_location(reg));
1058
+ }
1059
+
1060
+
1061
+ void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
1062
+ __ movq(backtrack_stackpointer(), register_location(reg));
1063
+ __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
1064
+ }
1065
+
1066
+
1067
+ void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) {
1068
+ Label after_position;
1069
+ __ cmpq(rdi, Immediate(-by * char_size()));
1070
+ __ j(greater_equal, &after_position, Label::kNear);
1071
+ __ movq(rdi, Immediate(-by * char_size()));
1072
+ // On RegExp code entry (where this operation is used), the character before
1073
+ // the current position is expected to be already loaded.
1074
+ // We have advanced the position, so it's safe to read backwards.
1075
+ LoadCurrentCharacterUnchecked(-1, 1);
1076
+ __ bind(&after_position);
1077
+ }
1078
+
1079
+
1080
+ void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
1081
+ ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
1082
+ __ movq(register_location(register_index), Immediate(to));
1083
+ }
1084
+
1085
+
1086
+ void RegExpMacroAssemblerX64::Succeed() {
1087
+ __ jmp(&success_label_);
1088
+ }
1089
+
1090
+
1091
+ void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg,
1092
+ int cp_offset) {
1093
+ if (cp_offset == 0) {
1094
+ __ movq(register_location(reg), rdi);
1095
+ } else {
1096
+ __ lea(rax, Operand(rdi, cp_offset * char_size()));
1097
+ __ movq(register_location(reg), rax);
1098
+ }
1099
+ }
1100
+
1101
+
1102
+ void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) {
1103
+ ASSERT(reg_from <= reg_to);
1104
+ __ movq(rax, Operand(rbp, kInputStartMinusOne));
1105
+ for (int reg = reg_from; reg <= reg_to; reg++) {
1106
+ __ movq(register_location(reg), rax);
1107
+ }
1108
+ }
1109
+
1110
+
1111
+ void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) {
1112
+ __ movq(rax, backtrack_stackpointer());
1113
+ __ subq(rax, Operand(rbp, kStackHighEnd));
1114
+ __ movq(register_location(reg), rax);
1115
+ }
1116
+
1117
+
1118
+ // Private methods:
1119
+
1120
+ void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
1121
+ // This function call preserves no register values. Caller should
1122
+ // store anything volatile in a C call or overwritten by this function.
1123
+ static const int num_arguments = 3;
1124
+ __ PrepareCallCFunction(num_arguments);
1125
+ #ifdef _WIN64
1126
+ // Second argument: Code* of self. (Do this before overwriting r8).
1127
+ __ movq(rdx, code_object_pointer());
1128
+ // Third argument: RegExp code frame pointer.
1129
+ __ movq(r8, rbp);
1130
+ // First argument: Next address on the stack (will be address of
1131
+ // return address).
1132
+ __ lea(rcx, Operand(rsp, -kPointerSize));
1133
+ #else
1134
+ // Third argument: RegExp code frame pointer.
1135
+ __ movq(rdx, rbp);
1136
+ // Second argument: Code* of self.
1137
+ __ movq(rsi, code_object_pointer());
1138
+ // First argument: Next address on the stack (will be address of
1139
+ // return address).
1140
+ __ lea(rdi, Operand(rsp, -kPointerSize));
1141
+ #endif
1142
+ ExternalReference stack_check =
1143
+ ExternalReference::re_check_stack_guard_state(masm_.isolate());
1144
+ __ CallCFunction(stack_check, num_arguments);
1145
+ }
1146
+
1147
+
1148
+ // Helper function for reading a value out of a stack frame.
1149
+ template <typename T>
1150
+ static T& frame_entry(Address re_frame, int frame_offset) {
1151
+ return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
1152
+ }
1153
+
1154
+
1155
+ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
1156
+ Code* re_code,
1157
+ Address re_frame) {
1158
+ Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1159
+ ASSERT(isolate == Isolate::Current());
1160
+ if (isolate->stack_guard()->IsStackOverflow()) {
1161
+ isolate->StackOverflow();
1162
+ return EXCEPTION;
1163
+ }
1164
+
1165
+ // If not real stack overflow the stack guard was used to interrupt
1166
+ // execution for another purpose.
1167
+
1168
+ // If this is a direct call from JavaScript retry the RegExp forcing the call
1169
+ // through the runtime system. Currently the direct call cannot handle a GC.
1170
+ if (frame_entry<int>(re_frame, kDirectCall) == 1) {
1171
+ return RETRY;
1172
+ }
1173
+
1174
+ // Prepare for possible GC.
1175
+ HandleScope handles;
1176
+ Handle<Code> code_handle(re_code);
1177
+
1178
+ Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
1179
+ // Current string.
1180
+ bool is_ascii = subject->IsAsciiRepresentation();
1181
+
1182
+ ASSERT(re_code->instruction_start() <= *return_address);
1183
+ ASSERT(*return_address <=
1184
+ re_code->instruction_start() + re_code->instruction_size());
1185
+
1186
+ MaybeObject* result = Execution::HandleStackGuardInterrupt();
1187
+
1188
+ if (*code_handle != re_code) { // Return address no longer valid
1189
+ intptr_t delta = *code_handle - re_code;
1190
+ // Overwrite the return address on the stack.
1191
+ *return_address += delta;
1192
+ }
1193
+
1194
+ if (result->IsException()) {
1195
+ return EXCEPTION;
1196
+ }
1197
+
1198
+ // String might have changed.
1199
+ if (subject->IsAsciiRepresentation() != is_ascii) {
1200
+ // If we changed between an ASCII and an UC16 string, the specialized
1201
+ // code cannot be used, and we need to restart regexp matching from
1202
+ // scratch (including, potentially, compiling a new version of the code).
1203
+ return RETRY;
1204
+ }
1205
+
1206
+ // Otherwise, the content of the string might have moved. It must still
1207
+ // be a sequential or external string with the same content.
1208
+ // Update the start and end pointers in the stack frame to the current
1209
+ // location (whether it has actually moved or not).
1210
+ ASSERT(StringShape(*subject).IsSequential() ||
1211
+ StringShape(*subject).IsExternal());
1212
+
1213
+ // The original start address of the characters to match.
1214
+ const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
1215
+
1216
+ // Find the current start address of the same character at the current string
1217
+ // position.
1218
+ int start_index = frame_entry<int>(re_frame, kStartIndex);
1219
+ const byte* new_address = StringCharacterPosition(*subject, start_index);
1220
+
1221
+ if (start_address != new_address) {
1222
+ // If there is a difference, update the object pointer and start and end
1223
+ // addresses in the RegExp stack frame to match the new value.
1224
+ const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
1225
+ int byte_length = static_cast<int>(end_address - start_address);
1226
+ frame_entry<const String*>(re_frame, kInputString) = *subject;
1227
+ frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1228
+ frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1229
+ }
1230
+
1231
+ return 0;
1232
+ }
1233
+
1234
+
1235
+ Operand RegExpMacroAssemblerX64::register_location(int register_index) {
1236
+ ASSERT(register_index < (1<<30));
1237
+ if (num_registers_ <= register_index) {
1238
+ num_registers_ = register_index + 1;
1239
+ }
1240
+ return Operand(rbp, kRegisterZero - register_index * kPointerSize);
1241
+ }
1242
+
1243
+
1244
+ void RegExpMacroAssemblerX64::CheckPosition(int cp_offset,
1245
+ Label* on_outside_input) {
1246
+ __ cmpl(rdi, Immediate(-cp_offset * char_size()));
1247
+ BranchOrBacktrack(greater_equal, on_outside_input);
1248
+ }
1249
+
1250
+
1251
+ void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition,
1252
+ Label* to) {
1253
+ if (condition < 0) { // No condition
1254
+ if (to == NULL) {
1255
+ Backtrack();
1256
+ return;
1257
+ }
1258
+ __ jmp(to);
1259
+ return;
1260
+ }
1261
+ if (to == NULL) {
1262
+ __ j(condition, &backtrack_label_);
1263
+ return;
1264
+ }
1265
+ __ j(condition, to);
1266
+ }
1267
+
1268
+
1269
+ void RegExpMacroAssemblerX64::SafeCall(Label* to) {
1270
+ __ call(to);
1271
+ }
1272
+
1273
+
1274
+ void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) {
1275
+ __ bind(label);
1276
+ __ subq(Operand(rsp, 0), code_object_pointer());
1277
+ }
1278
+
1279
+
1280
+ void RegExpMacroAssemblerX64::SafeReturn() {
1281
+ __ addq(Operand(rsp, 0), code_object_pointer());
1282
+ __ ret(0);
1283
+ }
1284
+
1285
+
1286
+ void RegExpMacroAssemblerX64::Push(Register source) {
1287
+ ASSERT(!source.is(backtrack_stackpointer()));
1288
+ // Notice: This updates flags, unlike normal Push.
1289
+ __ subq(backtrack_stackpointer(), Immediate(kIntSize));
1290
+ __ movl(Operand(backtrack_stackpointer(), 0), source);
1291
+ }
1292
+
1293
+
1294
+ void RegExpMacroAssemblerX64::Push(Immediate value) {
1295
+ // Notice: This updates flags, unlike normal Push.
1296
+ __ subq(backtrack_stackpointer(), Immediate(kIntSize));
1297
+ __ movl(Operand(backtrack_stackpointer(), 0), value);
1298
+ }
1299
+
1300
+
1301
+ void RegExpMacroAssemblerX64::FixupCodeRelativePositions() {
1302
+ for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) {
1303
+ int position = code_relative_fixup_positions_[i];
1304
+ // The position succeeds a relative label offset from position.
1305
+ // Patch the relative offset to be relative to the Code object pointer
1306
+ // instead.
1307
+ int patch_position = position - kIntSize;
1308
+ int offset = masm_.long_at(patch_position);
1309
+ masm_.long_at_put(patch_position,
1310
+ offset
1311
+ + position
1312
+ + Code::kHeaderSize
1313
+ - kHeapObjectTag);
1314
+ }
1315
+ code_relative_fixup_positions_.Clear();
1316
+ }
1317
+
1318
+
1319
+ void RegExpMacroAssemblerX64::Push(Label* backtrack_target) {
1320
+ __ subq(backtrack_stackpointer(), Immediate(kIntSize));
1321
+ __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target);
1322
+ MarkPositionForCodeRelativeFixup();
1323
+ }
1324
+
1325
+
1326
+ void RegExpMacroAssemblerX64::Pop(Register target) {
1327
+ ASSERT(!target.is(backtrack_stackpointer()));
1328
+ __ movsxlq(target, Operand(backtrack_stackpointer(), 0));
1329
+ // Notice: This updates flags, unlike normal Pop.
1330
+ __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1331
+ }
1332
+
1333
+
1334
+ void RegExpMacroAssemblerX64::Drop() {
1335
+ __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1336
+ }
1337
+
1338
+
1339
+ void RegExpMacroAssemblerX64::CheckPreemption() {
1340
+ // Check for preemption.
1341
+ Label no_preempt;
1342
+ ExternalReference stack_limit =
1343
+ ExternalReference::address_of_stack_limit(masm_.isolate());
1344
+ __ load_rax(stack_limit);
1345
+ __ cmpq(rsp, rax);
1346
+ __ j(above, &no_preempt);
1347
+
1348
+ SafeCall(&check_preempt_label_);
1349
+
1350
+ __ bind(&no_preempt);
1351
+ }
1352
+
1353
+
1354
+ void RegExpMacroAssemblerX64::CheckStackLimit() {
1355
+ Label no_stack_overflow;
1356
+ ExternalReference stack_limit =
1357
+ ExternalReference::address_of_regexp_stack_limit(masm_.isolate());
1358
+ __ load_rax(stack_limit);
1359
+ __ cmpq(backtrack_stackpointer(), rax);
1360
+ __ j(above, &no_stack_overflow);
1361
+
1362
+ SafeCall(&stack_overflow_label_);
1363
+
1364
+ __ bind(&no_stack_overflow);
1365
+ }
1366
+
1367
+
1368
+ void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset,
1369
+ int characters) {
1370
+ if (mode_ == ASCII) {
1371
+ if (characters == 4) {
1372
+ __ movl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
1373
+ } else if (characters == 2) {
1374
+ __ movzxwl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
1375
+ } else {
1376
+ ASSERT(characters == 1);
1377
+ __ movzxbl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
1378
+ }
1379
+ } else {
1380
+ ASSERT(mode_ == UC16);
1381
+ if (characters == 2) {
1382
+ __ movl(current_character(),
1383
+ Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
1384
+ } else {
1385
+ ASSERT(characters == 1);
1386
+ __ movzxwl(current_character(),
1387
+ Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
1388
+ }
1389
+ }
1390
+ }
1391
+
1392
+ #undef __
1393
+
1394
+ #endif // V8_INTERPRETED_REGEXP
1395
+
1396
+ }} // namespace v8::internal
1397
+
1398
+ #endif // V8_TARGET_ARCH_X64