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,1832 @@
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 <assert.h>
29
+ #include <stdio.h>
30
+ #include <stdarg.h>
31
+
32
+ #include "v8.h"
33
+
34
+ #if defined(V8_TARGET_ARCH_X64)
35
+
36
+ #include "disasm.h"
37
+
38
+ namespace disasm {
39
+
40
+ enum OperandType {
41
+ UNSET_OP_ORDER = 0,
42
+ // Operand size decides between 16, 32 and 64 bit operands.
43
+ REG_OPER_OP_ORDER = 1, // Register destination, operand source.
44
+ OPER_REG_OP_ORDER = 2, // Operand destination, register source.
45
+ // Fixed 8-bit operands.
46
+ BYTE_SIZE_OPERAND_FLAG = 4,
47
+ BYTE_REG_OPER_OP_ORDER = REG_OPER_OP_ORDER | BYTE_SIZE_OPERAND_FLAG,
48
+ BYTE_OPER_REG_OP_ORDER = OPER_REG_OP_ORDER | BYTE_SIZE_OPERAND_FLAG
49
+ };
50
+
51
+ //------------------------------------------------------------------
52
+ // Tables
53
+ //------------------------------------------------------------------
54
+ struct ByteMnemonic {
55
+ int b; // -1 terminates, otherwise must be in range (0..255)
56
+ OperandType op_order_;
57
+ const char* mnem;
58
+ };
59
+
60
+
61
+ static ByteMnemonic two_operands_instr[] = {
62
+ { 0x00, BYTE_OPER_REG_OP_ORDER, "add" },
63
+ { 0x01, OPER_REG_OP_ORDER, "add" },
64
+ { 0x02, BYTE_REG_OPER_OP_ORDER, "add" },
65
+ { 0x03, REG_OPER_OP_ORDER, "add" },
66
+ { 0x08, BYTE_OPER_REG_OP_ORDER, "or" },
67
+ { 0x09, OPER_REG_OP_ORDER, "or" },
68
+ { 0x0A, BYTE_REG_OPER_OP_ORDER, "or" },
69
+ { 0x0B, REG_OPER_OP_ORDER, "or" },
70
+ { 0x10, BYTE_OPER_REG_OP_ORDER, "adc" },
71
+ { 0x11, OPER_REG_OP_ORDER, "adc" },
72
+ { 0x12, BYTE_REG_OPER_OP_ORDER, "adc" },
73
+ { 0x13, REG_OPER_OP_ORDER, "adc" },
74
+ { 0x18, BYTE_OPER_REG_OP_ORDER, "sbb" },
75
+ { 0x19, OPER_REG_OP_ORDER, "sbb" },
76
+ { 0x1A, BYTE_REG_OPER_OP_ORDER, "sbb" },
77
+ { 0x1B, REG_OPER_OP_ORDER, "sbb" },
78
+ { 0x20, BYTE_OPER_REG_OP_ORDER, "and" },
79
+ { 0x21, OPER_REG_OP_ORDER, "and" },
80
+ { 0x22, BYTE_REG_OPER_OP_ORDER, "and" },
81
+ { 0x23, REG_OPER_OP_ORDER, "and" },
82
+ { 0x28, BYTE_OPER_REG_OP_ORDER, "sub" },
83
+ { 0x29, OPER_REG_OP_ORDER, "sub" },
84
+ { 0x2A, BYTE_REG_OPER_OP_ORDER, "sub" },
85
+ { 0x2B, REG_OPER_OP_ORDER, "sub" },
86
+ { 0x30, BYTE_OPER_REG_OP_ORDER, "xor" },
87
+ { 0x31, OPER_REG_OP_ORDER, "xor" },
88
+ { 0x32, BYTE_REG_OPER_OP_ORDER, "xor" },
89
+ { 0x33, REG_OPER_OP_ORDER, "xor" },
90
+ { 0x38, BYTE_OPER_REG_OP_ORDER, "cmp" },
91
+ { 0x39, OPER_REG_OP_ORDER, "cmp" },
92
+ { 0x3A, BYTE_REG_OPER_OP_ORDER, "cmp" },
93
+ { 0x3B, REG_OPER_OP_ORDER, "cmp" },
94
+ { 0x63, REG_OPER_OP_ORDER, "movsxlq" },
95
+ { 0x84, BYTE_REG_OPER_OP_ORDER, "test" },
96
+ { 0x85, REG_OPER_OP_ORDER, "test" },
97
+ { 0x86, BYTE_REG_OPER_OP_ORDER, "xchg" },
98
+ { 0x87, REG_OPER_OP_ORDER, "xchg" },
99
+ { 0x88, BYTE_OPER_REG_OP_ORDER, "mov" },
100
+ { 0x89, OPER_REG_OP_ORDER, "mov" },
101
+ { 0x8A, BYTE_REG_OPER_OP_ORDER, "mov" },
102
+ { 0x8B, REG_OPER_OP_ORDER, "mov" },
103
+ { 0x8D, REG_OPER_OP_ORDER, "lea" },
104
+ { -1, UNSET_OP_ORDER, "" }
105
+ };
106
+
107
+
108
+ static ByteMnemonic zero_operands_instr[] = {
109
+ { 0xC3, UNSET_OP_ORDER, "ret" },
110
+ { 0xC9, UNSET_OP_ORDER, "leave" },
111
+ { 0xF4, UNSET_OP_ORDER, "hlt" },
112
+ { 0xCC, UNSET_OP_ORDER, "int3" },
113
+ { 0x60, UNSET_OP_ORDER, "pushad" },
114
+ { 0x61, UNSET_OP_ORDER, "popad" },
115
+ { 0x9C, UNSET_OP_ORDER, "pushfd" },
116
+ { 0x9D, UNSET_OP_ORDER, "popfd" },
117
+ { 0x9E, UNSET_OP_ORDER, "sahf" },
118
+ { 0x99, UNSET_OP_ORDER, "cdq" },
119
+ { 0x9B, UNSET_OP_ORDER, "fwait" },
120
+ { 0xA4, UNSET_OP_ORDER, "movs" },
121
+ { 0xA5, UNSET_OP_ORDER, "movs" },
122
+ { 0xA6, UNSET_OP_ORDER, "cmps" },
123
+ { 0xA7, UNSET_OP_ORDER, "cmps" },
124
+ { -1, UNSET_OP_ORDER, "" }
125
+ };
126
+
127
+
128
+ static ByteMnemonic call_jump_instr[] = {
129
+ { 0xE8, UNSET_OP_ORDER, "call" },
130
+ { 0xE9, UNSET_OP_ORDER, "jmp" },
131
+ { -1, UNSET_OP_ORDER, "" }
132
+ };
133
+
134
+
135
+ static ByteMnemonic short_immediate_instr[] = {
136
+ { 0x05, UNSET_OP_ORDER, "add" },
137
+ { 0x0D, UNSET_OP_ORDER, "or" },
138
+ { 0x15, UNSET_OP_ORDER, "adc" },
139
+ { 0x1D, UNSET_OP_ORDER, "sbb" },
140
+ { 0x25, UNSET_OP_ORDER, "and" },
141
+ { 0x2D, UNSET_OP_ORDER, "sub" },
142
+ { 0x35, UNSET_OP_ORDER, "xor" },
143
+ { 0x3D, UNSET_OP_ORDER, "cmp" },
144
+ { -1, UNSET_OP_ORDER, "" }
145
+ };
146
+
147
+
148
+ static const char* conditional_code_suffix[] = {
149
+ "o", "no", "c", "nc", "z", "nz", "na", "a",
150
+ "s", "ns", "pe", "po", "l", "ge", "le", "g"
151
+ };
152
+
153
+
154
+ enum InstructionType {
155
+ NO_INSTR,
156
+ ZERO_OPERANDS_INSTR,
157
+ TWO_OPERANDS_INSTR,
158
+ JUMP_CONDITIONAL_SHORT_INSTR,
159
+ REGISTER_INSTR,
160
+ PUSHPOP_INSTR, // Has implicit 64-bit operand size.
161
+ MOVE_REG_INSTR,
162
+ CALL_JUMP_INSTR,
163
+ SHORT_IMMEDIATE_INSTR
164
+ };
165
+
166
+
167
+ enum Prefixes {
168
+ ESCAPE_PREFIX = 0x0F,
169
+ OPERAND_SIZE_OVERRIDE_PREFIX = 0x66,
170
+ ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67,
171
+ REPNE_PREFIX = 0xF2,
172
+ REP_PREFIX = 0xF3,
173
+ REPEQ_PREFIX = REP_PREFIX
174
+ };
175
+
176
+
177
+ struct InstructionDesc {
178
+ const char* mnem;
179
+ InstructionType type;
180
+ OperandType op_order_;
181
+ bool byte_size_operation; // Fixed 8-bit operation.
182
+ };
183
+
184
+
185
+ class InstructionTable {
186
+ public:
187
+ InstructionTable();
188
+ const InstructionDesc& Get(byte x) const {
189
+ return instructions_[x];
190
+ }
191
+
192
+ private:
193
+ InstructionDesc instructions_[256];
194
+ void Clear();
195
+ void Init();
196
+ void CopyTable(ByteMnemonic bm[], InstructionType type);
197
+ void SetTableRange(InstructionType type, byte start, byte end, bool byte_size,
198
+ const char* mnem);
199
+ void AddJumpConditionalShort();
200
+ };
201
+
202
+
203
+ InstructionTable::InstructionTable() {
204
+ Clear();
205
+ Init();
206
+ }
207
+
208
+
209
+ void InstructionTable::Clear() {
210
+ for (int i = 0; i < 256; i++) {
211
+ instructions_[i].mnem = "(bad)";
212
+ instructions_[i].type = NO_INSTR;
213
+ instructions_[i].op_order_ = UNSET_OP_ORDER;
214
+ instructions_[i].byte_size_operation = false;
215
+ }
216
+ }
217
+
218
+
219
+ void InstructionTable::Init() {
220
+ CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
221
+ CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
222
+ CopyTable(call_jump_instr, CALL_JUMP_INSTR);
223
+ CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
224
+ AddJumpConditionalShort();
225
+ SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, false, "push");
226
+ SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, false, "pop");
227
+ SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, false, "mov");
228
+ }
229
+
230
+
231
+ void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {
232
+ for (int i = 0; bm[i].b >= 0; i++) {
233
+ InstructionDesc* id = &instructions_[bm[i].b];
234
+ id->mnem = bm[i].mnem;
235
+ OperandType op_order = bm[i].op_order_;
236
+ id->op_order_ =
237
+ static_cast<OperandType>(op_order & ~BYTE_SIZE_OPERAND_FLAG);
238
+ ASSERT_EQ(NO_INSTR, id->type); // Information not already entered
239
+ id->type = type;
240
+ id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0);
241
+ }
242
+ }
243
+
244
+
245
+ void InstructionTable::SetTableRange(InstructionType type,
246
+ byte start,
247
+ byte end,
248
+ bool byte_size,
249
+ const char* mnem) {
250
+ for (byte b = start; b <= end; b++) {
251
+ InstructionDesc* id = &instructions_[b];
252
+ ASSERT_EQ(NO_INSTR, id->type); // Information not already entered
253
+ id->mnem = mnem;
254
+ id->type = type;
255
+ id->byte_size_operation = byte_size;
256
+ }
257
+ }
258
+
259
+
260
+ void InstructionTable::AddJumpConditionalShort() {
261
+ for (byte b = 0x70; b <= 0x7F; b++) {
262
+ InstructionDesc* id = &instructions_[b];
263
+ ASSERT_EQ(NO_INSTR, id->type); // Information not already entered
264
+ id->mnem = NULL; // Computed depending on condition code.
265
+ id->type = JUMP_CONDITIONAL_SHORT_INSTR;
266
+ }
267
+ }
268
+
269
+
270
+ static InstructionTable instruction_table;
271
+
272
+
273
+ static InstructionDesc cmov_instructions[16] = {
274
+ {"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
275
+ {"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
276
+ {"cmovc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
277
+ {"cmovnc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
278
+ {"cmovz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
279
+ {"cmovnz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
280
+ {"cmovna", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
281
+ {"cmova", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
282
+ {"cmovs", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
283
+ {"cmovns", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
284
+ {"cmovpe", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
285
+ {"cmovpo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
286
+ {"cmovl", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
287
+ {"cmovge", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
288
+ {"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
289
+ {"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}
290
+ };
291
+
292
+ //------------------------------------------------------------------------------
293
+ // DisassemblerX64 implementation.
294
+
295
+ enum UnimplementedOpcodeAction {
296
+ CONTINUE_ON_UNIMPLEMENTED_OPCODE,
297
+ ABORT_ON_UNIMPLEMENTED_OPCODE
298
+ };
299
+
300
+ // A new DisassemblerX64 object is created to disassemble each instruction.
301
+ // The object can only disassemble a single instruction.
302
+ class DisassemblerX64 {
303
+ public:
304
+ DisassemblerX64(const NameConverter& converter,
305
+ UnimplementedOpcodeAction unimplemented_action =
306
+ ABORT_ON_UNIMPLEMENTED_OPCODE)
307
+ : converter_(converter),
308
+ tmp_buffer_pos_(0),
309
+ abort_on_unimplemented_(
310
+ unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE),
311
+ rex_(0),
312
+ operand_size_(0),
313
+ group_1_prefix_(0),
314
+ byte_size_operand_(false) {
315
+ tmp_buffer_[0] = '\0';
316
+ }
317
+
318
+ virtual ~DisassemblerX64() {
319
+ }
320
+
321
+ // Writes one disassembled instruction into 'buffer' (0-terminated).
322
+ // Returns the length of the disassembled machine instruction in bytes.
323
+ int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
324
+
325
+ private:
326
+ enum OperandSize {
327
+ BYTE_SIZE = 0,
328
+ WORD_SIZE = 1,
329
+ DOUBLEWORD_SIZE = 2,
330
+ QUADWORD_SIZE = 3
331
+ };
332
+
333
+ const NameConverter& converter_;
334
+ v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
335
+ unsigned int tmp_buffer_pos_;
336
+ bool abort_on_unimplemented_;
337
+ // Prefixes parsed
338
+ byte rex_;
339
+ byte operand_size_; // 0x66 or (if no group 3 prefix is present) 0x0.
340
+ byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0.
341
+ // Byte size operand override.
342
+ bool byte_size_operand_;
343
+
344
+ void setRex(byte rex) {
345
+ ASSERT_EQ(0x40, rex & 0xF0);
346
+ rex_ = rex;
347
+ }
348
+
349
+ bool rex() { return rex_ != 0; }
350
+
351
+ bool rex_b() { return (rex_ & 0x01) != 0; }
352
+
353
+ // Actual number of base register given the low bits and the rex.b state.
354
+ int base_reg(int low_bits) { return low_bits | ((rex_ & 0x01) << 3); }
355
+
356
+ bool rex_x() { return (rex_ & 0x02) != 0; }
357
+
358
+ bool rex_r() { return (rex_ & 0x04) != 0; }
359
+
360
+ bool rex_w() { return (rex_ & 0x08) != 0; }
361
+
362
+ OperandSize operand_size() {
363
+ if (byte_size_operand_) return BYTE_SIZE;
364
+ if (rex_w()) return QUADWORD_SIZE;
365
+ if (operand_size_ != 0) return WORD_SIZE;
366
+ return DOUBLEWORD_SIZE;
367
+ }
368
+
369
+ char operand_size_code() {
370
+ return "bwlq"[operand_size()];
371
+ }
372
+
373
+ const char* NameOfCPURegister(int reg) const {
374
+ return converter_.NameOfCPURegister(reg);
375
+ }
376
+
377
+ const char* NameOfByteCPURegister(int reg) const {
378
+ return converter_.NameOfByteCPURegister(reg);
379
+ }
380
+
381
+ const char* NameOfXMMRegister(int reg) const {
382
+ return converter_.NameOfXMMRegister(reg);
383
+ }
384
+
385
+ const char* NameOfAddress(byte* addr) const {
386
+ return converter_.NameOfAddress(addr);
387
+ }
388
+
389
+ // Disassembler helper functions.
390
+ void get_modrm(byte data,
391
+ int* mod,
392
+ int* regop,
393
+ int* rm) {
394
+ *mod = (data >> 6) & 3;
395
+ *regop = ((data & 0x38) >> 3) | (rex_r() ? 8 : 0);
396
+ *rm = (data & 7) | (rex_b() ? 8 : 0);
397
+ }
398
+
399
+ void get_sib(byte data,
400
+ int* scale,
401
+ int* index,
402
+ int* base) {
403
+ *scale = (data >> 6) & 3;
404
+ *index = ((data >> 3) & 7) | (rex_x() ? 8 : 0);
405
+ *base = (data & 7) | (rex_b() ? 8 : 0);
406
+ }
407
+
408
+ typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const;
409
+
410
+ int PrintRightOperandHelper(byte* modrmp,
411
+ RegisterNameMapping register_name);
412
+ int PrintRightOperand(byte* modrmp);
413
+ int PrintRightByteOperand(byte* modrmp);
414
+ int PrintRightXMMOperand(byte* modrmp);
415
+ int PrintOperands(const char* mnem,
416
+ OperandType op_order,
417
+ byte* data);
418
+ int PrintImmediate(byte* data, OperandSize size);
419
+ int PrintImmediateOp(byte* data);
420
+ const char* TwoByteMnemonic(byte opcode);
421
+ int TwoByteOpcodeInstruction(byte* data);
422
+ int F6F7Instruction(byte* data);
423
+ int ShiftInstruction(byte* data);
424
+ int JumpShort(byte* data);
425
+ int JumpConditional(byte* data);
426
+ int JumpConditionalShort(byte* data);
427
+ int SetCC(byte* data);
428
+ int FPUInstruction(byte* data);
429
+ int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
430
+ int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
431
+ void AppendToBuffer(const char* format, ...);
432
+
433
+ void UnimplementedInstruction() {
434
+ if (abort_on_unimplemented_) {
435
+ CHECK(false);
436
+ } else {
437
+ AppendToBuffer("'Unimplemented Instruction'");
438
+ }
439
+ }
440
+ };
441
+
442
+
443
+ void DisassemblerX64::AppendToBuffer(const char* format, ...) {
444
+ v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
445
+ va_list args;
446
+ va_start(args, format);
447
+ int result = v8::internal::OS::VSNPrintF(buf, format, args);
448
+ va_end(args);
449
+ tmp_buffer_pos_ += result;
450
+ }
451
+
452
+
453
+ int DisassemblerX64::PrintRightOperandHelper(
454
+ byte* modrmp,
455
+ RegisterNameMapping direct_register_name) {
456
+ int mod, regop, rm;
457
+ get_modrm(*modrmp, &mod, &regop, &rm);
458
+ RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
459
+ &DisassemblerX64::NameOfCPURegister;
460
+ switch (mod) {
461
+ case 0:
462
+ if ((rm & 7) == 5) {
463
+ int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1);
464
+ AppendToBuffer("[0x%x]", disp);
465
+ return 5;
466
+ } else if ((rm & 7) == 4) {
467
+ // Codes for SIB byte.
468
+ byte sib = *(modrmp + 1);
469
+ int scale, index, base;
470
+ get_sib(sib, &scale, &index, &base);
471
+ if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
472
+ // index == rsp means no index. Only use sib byte with no index for
473
+ // rsp and r12 base.
474
+ AppendToBuffer("[%s]", NameOfCPURegister(base));
475
+ return 2;
476
+ } else if (base == 5) {
477
+ // base == rbp means no base register (when mod == 0).
478
+ int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
479
+ AppendToBuffer("[%s*%d+0x%x]",
480
+ NameOfCPURegister(index),
481
+ 1 << scale, disp);
482
+ return 6;
483
+ } else if (index != 4 && base != 5) {
484
+ // [base+index*scale]
485
+ AppendToBuffer("[%s+%s*%d]",
486
+ NameOfCPURegister(base),
487
+ NameOfCPURegister(index),
488
+ 1 << scale);
489
+ return 2;
490
+ } else {
491
+ UnimplementedInstruction();
492
+ return 1;
493
+ }
494
+ } else {
495
+ AppendToBuffer("[%s]", NameOfCPURegister(rm));
496
+ return 1;
497
+ }
498
+ break;
499
+ case 1: // fall through
500
+ case 2:
501
+ if ((rm & 7) == 4) {
502
+ byte sib = *(modrmp + 1);
503
+ int scale, index, base;
504
+ get_sib(sib, &scale, &index, &base);
505
+ int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2)
506
+ : *reinterpret_cast<char*>(modrmp + 2);
507
+ if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
508
+ if (-disp > 0) {
509
+ AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp);
510
+ } else {
511
+ AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp);
512
+ }
513
+ } else {
514
+ if (-disp > 0) {
515
+ AppendToBuffer("[%s+%s*%d-0x%x]",
516
+ NameOfCPURegister(base),
517
+ NameOfCPURegister(index),
518
+ 1 << scale,
519
+ -disp);
520
+ } else {
521
+ AppendToBuffer("[%s+%s*%d+0x%x]",
522
+ NameOfCPURegister(base),
523
+ NameOfCPURegister(index),
524
+ 1 << scale,
525
+ disp);
526
+ }
527
+ }
528
+ return mod == 2 ? 6 : 3;
529
+ } else {
530
+ // No sib.
531
+ int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
532
+ : *reinterpret_cast<char*>(modrmp + 1);
533
+ if (-disp > 0) {
534
+ AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp);
535
+ } else {
536
+ AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);
537
+ }
538
+ return (mod == 2) ? 5 : 2;
539
+ }
540
+ break;
541
+ case 3:
542
+ AppendToBuffer("%s", (this->*register_name)(rm));
543
+ return 1;
544
+ default:
545
+ UnimplementedInstruction();
546
+ return 1;
547
+ }
548
+ UNREACHABLE();
549
+ }
550
+
551
+
552
+ int DisassemblerX64::PrintImmediate(byte* data, OperandSize size) {
553
+ int64_t value;
554
+ int count;
555
+ switch (size) {
556
+ case BYTE_SIZE:
557
+ value = *data;
558
+ count = 1;
559
+ break;
560
+ case WORD_SIZE:
561
+ value = *reinterpret_cast<int16_t*>(data);
562
+ count = 2;
563
+ break;
564
+ case DOUBLEWORD_SIZE:
565
+ value = *reinterpret_cast<uint32_t*>(data);
566
+ count = 4;
567
+ break;
568
+ case QUADWORD_SIZE:
569
+ value = *reinterpret_cast<int32_t*>(data);
570
+ count = 4;
571
+ break;
572
+ default:
573
+ UNREACHABLE();
574
+ value = 0; // Initialize variables on all paths to satisfy the compiler.
575
+ count = 0;
576
+ }
577
+ AppendToBuffer("%" V8_PTR_PREFIX "x", value);
578
+ return count;
579
+ }
580
+
581
+
582
+ int DisassemblerX64::PrintRightOperand(byte* modrmp) {
583
+ return PrintRightOperandHelper(modrmp,
584
+ &DisassemblerX64::NameOfCPURegister);
585
+ }
586
+
587
+
588
+ int DisassemblerX64::PrintRightByteOperand(byte* modrmp) {
589
+ return PrintRightOperandHelper(modrmp,
590
+ &DisassemblerX64::NameOfByteCPURegister);
591
+ }
592
+
593
+
594
+ int DisassemblerX64::PrintRightXMMOperand(byte* modrmp) {
595
+ return PrintRightOperandHelper(modrmp,
596
+ &DisassemblerX64::NameOfXMMRegister);
597
+ }
598
+
599
+
600
+ // Returns number of bytes used including the current *data.
601
+ // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
602
+ int DisassemblerX64::PrintOperands(const char* mnem,
603
+ OperandType op_order,
604
+ byte* data) {
605
+ byte modrm = *data;
606
+ int mod, regop, rm;
607
+ get_modrm(modrm, &mod, &regop, &rm);
608
+ int advance = 0;
609
+ const char* register_name =
610
+ byte_size_operand_ ? NameOfByteCPURegister(regop)
611
+ : NameOfCPURegister(regop);
612
+ switch (op_order) {
613
+ case REG_OPER_OP_ORDER: {
614
+ AppendToBuffer("%s%c %s,",
615
+ mnem,
616
+ operand_size_code(),
617
+ register_name);
618
+ advance = byte_size_operand_ ? PrintRightByteOperand(data)
619
+ : PrintRightOperand(data);
620
+ break;
621
+ }
622
+ case OPER_REG_OP_ORDER: {
623
+ AppendToBuffer("%s%c ", mnem, operand_size_code());
624
+ advance = byte_size_operand_ ? PrintRightByteOperand(data)
625
+ : PrintRightOperand(data);
626
+ AppendToBuffer(",%s", register_name);
627
+ break;
628
+ }
629
+ default:
630
+ UNREACHABLE();
631
+ break;
632
+ }
633
+ return advance;
634
+ }
635
+
636
+
637
+ // Returns number of bytes used by machine instruction, including *data byte.
638
+ // Writes immediate instructions to 'tmp_buffer_'.
639
+ int DisassemblerX64::PrintImmediateOp(byte* data) {
640
+ bool byte_size_immediate = (*data & 0x02) != 0;
641
+ byte modrm = *(data + 1);
642
+ int mod, regop, rm;
643
+ get_modrm(modrm, &mod, &regop, &rm);
644
+ const char* mnem = "Imm???";
645
+ switch (regop) {
646
+ case 0:
647
+ mnem = "add";
648
+ break;
649
+ case 1:
650
+ mnem = "or";
651
+ break;
652
+ case 2:
653
+ mnem = "adc";
654
+ break;
655
+ case 3:
656
+ mnem = "sbb";
657
+ break;
658
+ case 4:
659
+ mnem = "and";
660
+ break;
661
+ case 5:
662
+ mnem = "sub";
663
+ break;
664
+ case 6:
665
+ mnem = "xor";
666
+ break;
667
+ case 7:
668
+ mnem = "cmp";
669
+ break;
670
+ default:
671
+ UnimplementedInstruction();
672
+ }
673
+ AppendToBuffer("%s%c ", mnem, operand_size_code());
674
+ int count = PrintRightOperand(data + 1);
675
+ AppendToBuffer(",0x");
676
+ OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size();
677
+ count += PrintImmediate(data + 1 + count, immediate_size);
678
+ return 1 + count;
679
+ }
680
+
681
+
682
+ // Returns number of bytes used, including *data.
683
+ int DisassemblerX64::F6F7Instruction(byte* data) {
684
+ ASSERT(*data == 0xF7 || *data == 0xF6);
685
+ byte modrm = *(data + 1);
686
+ int mod, regop, rm;
687
+ get_modrm(modrm, &mod, &regop, &rm);
688
+ if (mod == 3 && regop != 0) {
689
+ const char* mnem = NULL;
690
+ switch (regop) {
691
+ case 2:
692
+ mnem = "not";
693
+ break;
694
+ case 3:
695
+ mnem = "neg";
696
+ break;
697
+ case 4:
698
+ mnem = "mul";
699
+ break;
700
+ case 7:
701
+ mnem = "idiv";
702
+ break;
703
+ default:
704
+ UnimplementedInstruction();
705
+ }
706
+ AppendToBuffer("%s%c %s",
707
+ mnem,
708
+ operand_size_code(),
709
+ NameOfCPURegister(rm));
710
+ return 2;
711
+ } else if (regop == 0) {
712
+ AppendToBuffer("test%c ", operand_size_code());
713
+ int count = PrintRightOperand(data + 1); // Use name of 64-bit register.
714
+ AppendToBuffer(",0x");
715
+ count += PrintImmediate(data + 1 + count, operand_size());
716
+ return 1 + count;
717
+ } else {
718
+ UnimplementedInstruction();
719
+ return 2;
720
+ }
721
+ }
722
+
723
+
724
+ int DisassemblerX64::ShiftInstruction(byte* data) {
725
+ byte op = *data & (~1);
726
+ if (op != 0xD0 && op != 0xD2 && op != 0xC0) {
727
+ UnimplementedInstruction();
728
+ return 1;
729
+ }
730
+ byte modrm = *(data + 1);
731
+ int mod, regop, rm;
732
+ get_modrm(modrm, &mod, &regop, &rm);
733
+ regop &= 0x7; // The REX.R bit does not affect the operation.
734
+ int imm8 = -1;
735
+ int num_bytes = 2;
736
+ if (mod != 3) {
737
+ UnimplementedInstruction();
738
+ return num_bytes;
739
+ }
740
+ const char* mnem = NULL;
741
+ switch (regop) {
742
+ case 0:
743
+ mnem = "rol";
744
+ break;
745
+ case 1:
746
+ mnem = "ror";
747
+ break;
748
+ case 2:
749
+ mnem = "rcl";
750
+ break;
751
+ case 3:
752
+ mnem = "rcr";
753
+ break;
754
+ case 4:
755
+ mnem = "shl";
756
+ break;
757
+ case 5:
758
+ mnem = "shr";
759
+ break;
760
+ case 7:
761
+ mnem = "sar";
762
+ break;
763
+ default:
764
+ UnimplementedInstruction();
765
+ return num_bytes;
766
+ }
767
+ ASSERT_NE(NULL, mnem);
768
+ if (op == 0xD0) {
769
+ imm8 = 1;
770
+ } else if (op == 0xC0) {
771
+ imm8 = *(data + 2);
772
+ num_bytes = 3;
773
+ }
774
+ AppendToBuffer("%s%c %s,",
775
+ mnem,
776
+ operand_size_code(),
777
+ byte_size_operand_ ? NameOfByteCPURegister(rm)
778
+ : NameOfCPURegister(rm));
779
+ if (op == 0xD2) {
780
+ AppendToBuffer("cl");
781
+ } else {
782
+ AppendToBuffer("%d", imm8);
783
+ }
784
+ return num_bytes;
785
+ }
786
+
787
+
788
+ // Returns number of bytes used, including *data.
789
+ int DisassemblerX64::JumpShort(byte* data) {
790
+ ASSERT_EQ(0xEB, *data);
791
+ byte b = *(data + 1);
792
+ byte* dest = data + static_cast<int8_t>(b) + 2;
793
+ AppendToBuffer("jmp %s", NameOfAddress(dest));
794
+ return 2;
795
+ }
796
+
797
+
798
+ // Returns number of bytes used, including *data.
799
+ int DisassemblerX64::JumpConditional(byte* data) {
800
+ ASSERT_EQ(0x0F, *data);
801
+ byte cond = *(data + 1) & 0x0F;
802
+ byte* dest = data + *reinterpret_cast<int32_t*>(data + 2) + 6;
803
+ const char* mnem = conditional_code_suffix[cond];
804
+ AppendToBuffer("j%s %s", mnem, NameOfAddress(dest));
805
+ return 6; // includes 0x0F
806
+ }
807
+
808
+
809
+ // Returns number of bytes used, including *data.
810
+ int DisassemblerX64::JumpConditionalShort(byte* data) {
811
+ byte cond = *data & 0x0F;
812
+ byte b = *(data + 1);
813
+ byte* dest = data + static_cast<int8_t>(b) + 2;
814
+ const char* mnem = conditional_code_suffix[cond];
815
+ AppendToBuffer("j%s %s", mnem, NameOfAddress(dest));
816
+ return 2;
817
+ }
818
+
819
+
820
+ // Returns number of bytes used, including *data.
821
+ int DisassemblerX64::SetCC(byte* data) {
822
+ ASSERT_EQ(0x0F, *data);
823
+ byte cond = *(data + 1) & 0x0F;
824
+ const char* mnem = conditional_code_suffix[cond];
825
+ AppendToBuffer("set%s%c ", mnem, operand_size_code());
826
+ PrintRightByteOperand(data + 2);
827
+ return 3; // includes 0x0F
828
+ }
829
+
830
+
831
+ // Returns number of bytes used, including *data.
832
+ int DisassemblerX64::FPUInstruction(byte* data) {
833
+ byte escape_opcode = *data;
834
+ ASSERT_EQ(0xD8, escape_opcode & 0xF8);
835
+ byte modrm_byte = *(data+1);
836
+
837
+ if (modrm_byte >= 0xC0) {
838
+ return RegisterFPUInstruction(escape_opcode, modrm_byte);
839
+ } else {
840
+ return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
841
+ }
842
+ }
843
+
844
+ int DisassemblerX64::MemoryFPUInstruction(int escape_opcode,
845
+ int modrm_byte,
846
+ byte* modrm_start) {
847
+ const char* mnem = "?";
848
+ int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte.
849
+ switch (escape_opcode) {
850
+ case 0xD9: switch (regop) {
851
+ case 0: mnem = "fld_s"; break;
852
+ case 3: mnem = "fstp_s"; break;
853
+ case 7: mnem = "fstcw"; break;
854
+ default: UnimplementedInstruction();
855
+ }
856
+ break;
857
+
858
+ case 0xDB: switch (regop) {
859
+ case 0: mnem = "fild_s"; break;
860
+ case 1: mnem = "fisttp_s"; break;
861
+ case 2: mnem = "fist_s"; break;
862
+ case 3: mnem = "fistp_s"; break;
863
+ default: UnimplementedInstruction();
864
+ }
865
+ break;
866
+
867
+ case 0xDD: switch (regop) {
868
+ case 0: mnem = "fld_d"; break;
869
+ case 3: mnem = "fstp_d"; break;
870
+ default: UnimplementedInstruction();
871
+ }
872
+ break;
873
+
874
+ case 0xDF: switch (regop) {
875
+ case 5: mnem = "fild_d"; break;
876
+ case 7: mnem = "fistp_d"; break;
877
+ default: UnimplementedInstruction();
878
+ }
879
+ break;
880
+
881
+ default: UnimplementedInstruction();
882
+ }
883
+ AppendToBuffer("%s ", mnem);
884
+ int count = PrintRightOperand(modrm_start);
885
+ return count + 1;
886
+ }
887
+
888
+ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
889
+ byte modrm_byte) {
890
+ bool has_register = false; // Is the FPU register encoded in modrm_byte?
891
+ const char* mnem = "?";
892
+
893
+ switch (escape_opcode) {
894
+ case 0xD8:
895
+ UnimplementedInstruction();
896
+ break;
897
+
898
+ case 0xD9:
899
+ switch (modrm_byte & 0xF8) {
900
+ case 0xC0:
901
+ mnem = "fld";
902
+ has_register = true;
903
+ break;
904
+ case 0xC8:
905
+ mnem = "fxch";
906
+ has_register = true;
907
+ break;
908
+ default:
909
+ switch (modrm_byte) {
910
+ case 0xE0: mnem = "fchs"; break;
911
+ case 0xE1: mnem = "fabs"; break;
912
+ case 0xE4: mnem = "ftst"; break;
913
+ case 0xE8: mnem = "fld1"; break;
914
+ case 0xEB: mnem = "fldpi"; break;
915
+ case 0xED: mnem = "fldln2"; break;
916
+ case 0xEE: mnem = "fldz"; break;
917
+ case 0xF1: mnem = "fyl2x"; break;
918
+ case 0xF5: mnem = "fprem1"; break;
919
+ case 0xF7: mnem = "fincstp"; break;
920
+ case 0xF8: mnem = "fprem"; break;
921
+ case 0xFE: mnem = "fsin"; break;
922
+ case 0xFF: mnem = "fcos"; break;
923
+ default: UnimplementedInstruction();
924
+ }
925
+ }
926
+ break;
927
+
928
+ case 0xDA:
929
+ if (modrm_byte == 0xE9) {
930
+ mnem = "fucompp";
931
+ } else {
932
+ UnimplementedInstruction();
933
+ }
934
+ break;
935
+
936
+ case 0xDB:
937
+ if ((modrm_byte & 0xF8) == 0xE8) {
938
+ mnem = "fucomi";
939
+ has_register = true;
940
+ } else if (modrm_byte == 0xE2) {
941
+ mnem = "fclex";
942
+ } else {
943
+ UnimplementedInstruction();
944
+ }
945
+ break;
946
+
947
+ case 0xDC:
948
+ has_register = true;
949
+ switch (modrm_byte & 0xF8) {
950
+ case 0xC0: mnem = "fadd"; break;
951
+ case 0xE8: mnem = "fsub"; break;
952
+ case 0xC8: mnem = "fmul"; break;
953
+ case 0xF8: mnem = "fdiv"; break;
954
+ default: UnimplementedInstruction();
955
+ }
956
+ break;
957
+
958
+ case 0xDD:
959
+ has_register = true;
960
+ switch (modrm_byte & 0xF8) {
961
+ case 0xC0: mnem = "ffree"; break;
962
+ case 0xD8: mnem = "fstp"; break;
963
+ default: UnimplementedInstruction();
964
+ }
965
+ break;
966
+
967
+ case 0xDE:
968
+ if (modrm_byte == 0xD9) {
969
+ mnem = "fcompp";
970
+ } else {
971
+ has_register = true;
972
+ switch (modrm_byte & 0xF8) {
973
+ case 0xC0: mnem = "faddp"; break;
974
+ case 0xE8: mnem = "fsubp"; break;
975
+ case 0xC8: mnem = "fmulp"; break;
976
+ case 0xF8: mnem = "fdivp"; break;
977
+ default: UnimplementedInstruction();
978
+ }
979
+ }
980
+ break;
981
+
982
+ case 0xDF:
983
+ if (modrm_byte == 0xE0) {
984
+ mnem = "fnstsw_ax";
985
+ } else if ((modrm_byte & 0xF8) == 0xE8) {
986
+ mnem = "fucomip";
987
+ has_register = true;
988
+ }
989
+ break;
990
+
991
+ default: UnimplementedInstruction();
992
+ }
993
+
994
+ if (has_register) {
995
+ AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
996
+ } else {
997
+ AppendToBuffer("%s", mnem);
998
+ }
999
+ return 2;
1000
+ }
1001
+
1002
+
1003
+
1004
+ // Handle all two-byte opcodes, which start with 0x0F.
1005
+ // These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix.
1006
+ // We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A.
1007
+ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
1008
+ byte opcode = *(data + 1);
1009
+ byte* current = data + 2;
1010
+ // At return, "current" points to the start of the next instruction.
1011
+ const char* mnemonic = TwoByteMnemonic(opcode);
1012
+ if (operand_size_ == 0x66) {
1013
+ // 0x66 0x0F prefix.
1014
+ int mod, regop, rm;
1015
+ if (opcode == 0x3A) {
1016
+ byte third_byte = *current;
1017
+ current = data + 3;
1018
+ if (third_byte == 0x17) {
1019
+ get_modrm(*current, &mod, &regop, &rm);
1020
+ AppendToBuffer("extractps "); // reg/m32, xmm, imm8
1021
+ current += PrintRightOperand(current);
1022
+ AppendToBuffer(", %s, %d", NameOfCPURegister(regop), (*current) & 3);
1023
+ current += 1;
1024
+ } else if (third_byte == 0x0b) {
1025
+ get_modrm(*current, &mod, &regop, &rm);
1026
+ // roundsd xmm, xmm/m64, imm8
1027
+ AppendToBuffer("roundsd %s, ", NameOfCPURegister(regop));
1028
+ current += PrintRightOperand(current);
1029
+ AppendToBuffer(", %d", (*current) & 3);
1030
+ current += 1;
1031
+ } else {
1032
+ UnimplementedInstruction();
1033
+ }
1034
+ } else {
1035
+ get_modrm(*current, &mod, &regop, &rm);
1036
+ if (opcode == 0x28) {
1037
+ AppendToBuffer("movapd %s, ", NameOfXMMRegister(regop));
1038
+ current += PrintRightXMMOperand(current);
1039
+ } else if (opcode == 0x29) {
1040
+ AppendToBuffer("movapd ");
1041
+ current += PrintRightXMMOperand(current);
1042
+ AppendToBuffer(", %s", NameOfXMMRegister(regop));
1043
+ } else if (opcode == 0x6E) {
1044
+ AppendToBuffer("mov%c %s,",
1045
+ rex_w() ? 'q' : 'd',
1046
+ NameOfXMMRegister(regop));
1047
+ current += PrintRightOperand(current);
1048
+ } else if (opcode == 0x6F) {
1049
+ AppendToBuffer("movdqa %s,",
1050
+ NameOfXMMRegister(regop));
1051
+ current += PrintRightXMMOperand(current);
1052
+ } else if (opcode == 0x7E) {
1053
+ AppendToBuffer("mov%c ",
1054
+ rex_w() ? 'q' : 'd');
1055
+ current += PrintRightOperand(current);
1056
+ AppendToBuffer(", %s", NameOfXMMRegister(regop));
1057
+ } else if (opcode == 0x7F) {
1058
+ AppendToBuffer("movdqa ");
1059
+ current += PrintRightXMMOperand(current);
1060
+ AppendToBuffer(", %s", NameOfXMMRegister(regop));
1061
+ } else if (opcode == 0xD6) {
1062
+ AppendToBuffer("movq ");
1063
+ current += PrintRightXMMOperand(current);
1064
+ AppendToBuffer(", %s", NameOfXMMRegister(regop));
1065
+ } else {
1066
+ const char* mnemonic = "?";
1067
+ if (opcode == 0x50) {
1068
+ mnemonic = "movmskpd";
1069
+ } else if (opcode == 0x54) {
1070
+ mnemonic = "andpd";
1071
+ } else if (opcode == 0x56) {
1072
+ mnemonic = "orpd";
1073
+ } else if (opcode == 0x57) {
1074
+ mnemonic = "xorpd";
1075
+ } else if (opcode == 0x2E) {
1076
+ mnemonic = "ucomisd";
1077
+ } else if (opcode == 0x2F) {
1078
+ mnemonic = "comisd";
1079
+ } else {
1080
+ UnimplementedInstruction();
1081
+ }
1082
+ AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
1083
+ current += PrintRightXMMOperand(current);
1084
+ }
1085
+ }
1086
+ } else if (group_1_prefix_ == 0xF2) {
1087
+ // Beginning of instructions with prefix 0xF2.
1088
+
1089
+ if (opcode == 0x11 || opcode == 0x10) {
1090
+ // MOVSD: Move scalar double-precision fp to/from/between XMM registers.
1091
+ AppendToBuffer("movsd ");
1092
+ int mod, regop, rm;
1093
+ get_modrm(*current, &mod, &regop, &rm);
1094
+ if (opcode == 0x11) {
1095
+ current += PrintRightXMMOperand(current);
1096
+ AppendToBuffer(",%s", NameOfXMMRegister(regop));
1097
+ } else {
1098
+ AppendToBuffer("%s,", NameOfXMMRegister(regop));
1099
+ current += PrintRightXMMOperand(current);
1100
+ }
1101
+ } else if (opcode == 0x2A) {
1102
+ // CVTSI2SD: integer to XMM double conversion.
1103
+ int mod, regop, rm;
1104
+ get_modrm(*current, &mod, &regop, &rm);
1105
+ AppendToBuffer("%sd %s,", mnemonic, NameOfXMMRegister(regop));
1106
+ current += PrintRightOperand(current);
1107
+ } else if (opcode == 0x2C) {
1108
+ // CVTTSD2SI:
1109
+ // Convert with truncation scalar double-precision FP to integer.
1110
+ int mod, regop, rm;
1111
+ get_modrm(*current, &mod, &regop, &rm);
1112
+ AppendToBuffer("cvttsd2si%c %s,",
1113
+ operand_size_code(), NameOfCPURegister(regop));
1114
+ current += PrintRightXMMOperand(current);
1115
+ } else if (opcode == 0x2D) {
1116
+ // CVTSD2SI: Convert scalar double-precision FP to integer.
1117
+ int mod, regop, rm;
1118
+ get_modrm(*current, &mod, &regop, &rm);
1119
+ AppendToBuffer("cvtsd2si%c %s,",
1120
+ operand_size_code(), NameOfCPURegister(regop));
1121
+ current += PrintRightXMMOperand(current);
1122
+ } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) {
1123
+ // XMM arithmetic. Mnemonic was retrieved at the start of this function.
1124
+ int mod, regop, rm;
1125
+ get_modrm(*current, &mod, &regop, &rm);
1126
+ AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
1127
+ current += PrintRightXMMOperand(current);
1128
+ } else {
1129
+ UnimplementedInstruction();
1130
+ }
1131
+ } else if (group_1_prefix_ == 0xF3) {
1132
+ // Instructions with prefix 0xF3.
1133
+ if (opcode == 0x11 || opcode == 0x10) {
1134
+ // MOVSS: Move scalar double-precision fp to/from/between XMM registers.
1135
+ AppendToBuffer("movss ");
1136
+ int mod, regop, rm;
1137
+ get_modrm(*current, &mod, &regop, &rm);
1138
+ if (opcode == 0x11) {
1139
+ current += PrintRightOperand(current);
1140
+ AppendToBuffer(",%s", NameOfXMMRegister(regop));
1141
+ } else {
1142
+ AppendToBuffer("%s,", NameOfXMMRegister(regop));
1143
+ current += PrintRightOperand(current);
1144
+ }
1145
+ } else if (opcode == 0x2A) {
1146
+ // CVTSI2SS: integer to XMM single conversion.
1147
+ int mod, regop, rm;
1148
+ get_modrm(*current, &mod, &regop, &rm);
1149
+ AppendToBuffer("%ss %s,", mnemonic, NameOfXMMRegister(regop));
1150
+ current += PrintRightOperand(current);
1151
+ } else if (opcode == 0x2C) {
1152
+ // CVTTSS2SI:
1153
+ // Convert with truncation scalar single-precision FP to dword integer.
1154
+ int mod, regop, rm;
1155
+ get_modrm(*current, &mod, &regop, &rm);
1156
+ AppendToBuffer("cvttss2si%c %s,",
1157
+ operand_size_code(), NameOfCPURegister(regop));
1158
+ current += PrintRightXMMOperand(current);
1159
+ } else if (opcode == 0x5A) {
1160
+ // CVTSS2SD:
1161
+ // Convert scalar single-precision FP to scalar double-precision FP.
1162
+ int mod, regop, rm;
1163
+ get_modrm(*current, &mod, &regop, &rm);
1164
+ AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
1165
+ current += PrintRightXMMOperand(current);
1166
+ } else if (opcode == 0x7E) {
1167
+ int mod, regop, rm;
1168
+ get_modrm(*current, &mod, &regop, &rm);
1169
+ AppendToBuffer("movq %s, ", NameOfXMMRegister(regop));
1170
+ current += PrintRightXMMOperand(current);
1171
+ } else {
1172
+ UnimplementedInstruction();
1173
+ }
1174
+ } else if (opcode == 0x1F) {
1175
+ // NOP
1176
+ int mod, regop, rm;
1177
+ get_modrm(*current, &mod, &regop, &rm);
1178
+ current++;
1179
+ if (regop == 4) { // SIB byte present.
1180
+ current++;
1181
+ }
1182
+ if (mod == 1) { // Byte displacement.
1183
+ current += 1;
1184
+ } else if (mod == 2) { // 32-bit displacement.
1185
+ current += 4;
1186
+ } // else no immediate displacement.
1187
+ AppendToBuffer("nop");
1188
+
1189
+ } else if (opcode == 0x28) {
1190
+ // movaps xmm, xmm/m128
1191
+ int mod, regop, rm;
1192
+ get_modrm(*current, &mod, &regop, &rm);
1193
+ AppendToBuffer("movaps %s, ", NameOfXMMRegister(regop));
1194
+ current += PrintRightXMMOperand(current);
1195
+
1196
+ } else if (opcode == 0x29) {
1197
+ // movaps xmm/m128, xmm
1198
+ int mod, regop, rm;
1199
+ get_modrm(*current, &mod, &regop, &rm);
1200
+ AppendToBuffer("movaps ");
1201
+ current += PrintRightXMMOperand(current);
1202
+ AppendToBuffer(", %s", NameOfXMMRegister(regop));
1203
+
1204
+ } else if (opcode == 0xA2 || opcode == 0x31) {
1205
+ // RDTSC or CPUID
1206
+ AppendToBuffer("%s", mnemonic);
1207
+
1208
+ } else if ((opcode & 0xF0) == 0x40) {
1209
+ // CMOVcc: conditional move.
1210
+ int condition = opcode & 0x0F;
1211
+ const InstructionDesc& idesc = cmov_instructions[condition];
1212
+ byte_size_operand_ = idesc.byte_size_operation;
1213
+ current += PrintOperands(idesc.mnem, idesc.op_order_, current);
1214
+
1215
+ } else if (opcode == 0x57) {
1216
+ // xorps xmm, xmm/m128
1217
+ int mod, regop, rm;
1218
+ get_modrm(*current, &mod, &regop, &rm);
1219
+ AppendToBuffer("xorps %s, ", NameOfXMMRegister(regop));
1220
+ current += PrintRightXMMOperand(current);
1221
+
1222
+ } else if ((opcode & 0xF0) == 0x80) {
1223
+ // Jcc: Conditional jump (branch).
1224
+ current = data + JumpConditional(data);
1225
+
1226
+ } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
1227
+ opcode == 0xB7 || opcode == 0xAF) {
1228
+ // Size-extending moves, IMUL.
1229
+ current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
1230
+
1231
+ } else if ((opcode & 0xF0) == 0x90) {
1232
+ // SETcc: Set byte on condition. Needs pointer to beginning of instruction.
1233
+ current = data + SetCC(data);
1234
+
1235
+ } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) {
1236
+ // SHLD, SHRD (double-precision shift), BTS (bit set).
1237
+ AppendToBuffer("%s ", mnemonic);
1238
+ int mod, regop, rm;
1239
+ get_modrm(*current, &mod, &regop, &rm);
1240
+ current += PrintRightOperand(current);
1241
+ if (opcode == 0xAB) {
1242
+ AppendToBuffer(",%s", NameOfCPURegister(regop));
1243
+ } else {
1244
+ AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
1245
+ }
1246
+ } else {
1247
+ UnimplementedInstruction();
1248
+ }
1249
+ return static_cast<int>(current - data);
1250
+ }
1251
+
1252
+
1253
+ // Mnemonics for two-byte opcode instructions starting with 0x0F.
1254
+ // The argument is the second byte of the two-byte opcode.
1255
+ // Returns NULL if the instruction is not handled here.
1256
+ const char* DisassemblerX64::TwoByteMnemonic(byte opcode) {
1257
+ switch (opcode) {
1258
+ case 0x1F:
1259
+ return "nop";
1260
+ case 0x2A: // F2/F3 prefix.
1261
+ return "cvtsi2s";
1262
+ case 0x31:
1263
+ return "rdtsc";
1264
+ case 0x51: // F2 prefix.
1265
+ return "sqrtsd";
1266
+ case 0x58: // F2 prefix.
1267
+ return "addsd";
1268
+ case 0x59: // F2 prefix.
1269
+ return "mulsd";
1270
+ case 0x5C: // F2 prefix.
1271
+ return "subsd";
1272
+ case 0x5E: // F2 prefix.
1273
+ return "divsd";
1274
+ case 0xA2:
1275
+ return "cpuid";
1276
+ case 0xA5:
1277
+ return "shld";
1278
+ case 0xAB:
1279
+ return "bts";
1280
+ case 0xAD:
1281
+ return "shrd";
1282
+ case 0xAF:
1283
+ return "imul";
1284
+ case 0xB6:
1285
+ return "movzxb";
1286
+ case 0xB7:
1287
+ return "movzxw";
1288
+ case 0xBE:
1289
+ return "movsxb";
1290
+ case 0xBF:
1291
+ return "movsxw";
1292
+ default:
1293
+ return NULL;
1294
+ }
1295
+ }
1296
+
1297
+
1298
+ // Disassembles the instruction at instr, and writes it into out_buffer.
1299
+ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
1300
+ byte* instr) {
1301
+ tmp_buffer_pos_ = 0; // starting to write as position 0
1302
+ byte* data = instr;
1303
+ bool processed = true; // Will be set to false if the current instruction
1304
+ // is not in 'instructions' table.
1305
+ byte current;
1306
+
1307
+ // Scan for prefixes.
1308
+ while (true) {
1309
+ current = *data;
1310
+ if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix.
1311
+ operand_size_ = current;
1312
+ } else if ((current & 0xF0) == 0x40) { // REX prefix.
1313
+ setRex(current);
1314
+ if (rex_w()) AppendToBuffer("REX.W ");
1315
+ } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3).
1316
+ group_1_prefix_ = current;
1317
+ } else { // Not a prefix - an opcode.
1318
+ break;
1319
+ }
1320
+ data++;
1321
+ }
1322
+
1323
+ const InstructionDesc& idesc = instruction_table.Get(current);
1324
+ byte_size_operand_ = idesc.byte_size_operation;
1325
+ switch (idesc.type) {
1326
+ case ZERO_OPERANDS_INSTR:
1327
+ if (current >= 0xA4 && current <= 0xA7) {
1328
+ // String move or compare operations.
1329
+ if (group_1_prefix_ == REP_PREFIX) {
1330
+ // REP.
1331
+ AppendToBuffer("rep ");
1332
+ }
1333
+ if (rex_w()) AppendToBuffer("REX.W ");
1334
+ AppendToBuffer("%s%c", idesc.mnem, operand_size_code());
1335
+ } else {
1336
+ AppendToBuffer("%s", idesc.mnem, operand_size_code());
1337
+ }
1338
+ data++;
1339
+ break;
1340
+
1341
+ case TWO_OPERANDS_INSTR:
1342
+ data++;
1343
+ data += PrintOperands(idesc.mnem, idesc.op_order_, data);
1344
+ break;
1345
+
1346
+ case JUMP_CONDITIONAL_SHORT_INSTR:
1347
+ data += JumpConditionalShort(data);
1348
+ break;
1349
+
1350
+ case REGISTER_INSTR:
1351
+ AppendToBuffer("%s%c %s",
1352
+ idesc.mnem,
1353
+ operand_size_code(),
1354
+ NameOfCPURegister(base_reg(current & 0x07)));
1355
+ data++;
1356
+ break;
1357
+ case PUSHPOP_INSTR:
1358
+ AppendToBuffer("%s %s",
1359
+ idesc.mnem,
1360
+ NameOfCPURegister(base_reg(current & 0x07)));
1361
+ data++;
1362
+ break;
1363
+ case MOVE_REG_INSTR: {
1364
+ byte* addr = NULL;
1365
+ switch (operand_size()) {
1366
+ case WORD_SIZE:
1367
+ addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
1368
+ data += 3;
1369
+ break;
1370
+ case DOUBLEWORD_SIZE:
1371
+ addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
1372
+ data += 5;
1373
+ break;
1374
+ case QUADWORD_SIZE:
1375
+ addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
1376
+ data += 9;
1377
+ break;
1378
+ default:
1379
+ UNREACHABLE();
1380
+ }
1381
+ AppendToBuffer("mov%c %s,%s",
1382
+ operand_size_code(),
1383
+ NameOfCPURegister(base_reg(current & 0x07)),
1384
+ NameOfAddress(addr));
1385
+ break;
1386
+ }
1387
+
1388
+ case CALL_JUMP_INSTR: {
1389
+ byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
1390
+ AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
1391
+ data += 5;
1392
+ break;
1393
+ }
1394
+
1395
+ case SHORT_IMMEDIATE_INSTR: {
1396
+ byte* addr =
1397
+ reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
1398
+ AppendToBuffer("%s rax, %s", idesc.mnem, NameOfAddress(addr));
1399
+ data += 5;
1400
+ break;
1401
+ }
1402
+
1403
+ case NO_INSTR:
1404
+ processed = false;
1405
+ break;
1406
+
1407
+ default:
1408
+ UNIMPLEMENTED(); // This type is not implemented.
1409
+ }
1410
+
1411
+ // The first byte didn't match any of the simple opcodes, so we
1412
+ // need to do special processing on it.
1413
+ if (!processed) {
1414
+ switch (*data) {
1415
+ case 0xC2:
1416
+ AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1));
1417
+ data += 3;
1418
+ break;
1419
+
1420
+ case 0x69: // fall through
1421
+ case 0x6B: {
1422
+ int mod, regop, rm;
1423
+ get_modrm(*(data + 1), &mod, &regop, &rm);
1424
+ int32_t imm = *data == 0x6B ? *(data + 2)
1425
+ : *reinterpret_cast<int32_t*>(data + 2);
1426
+ AppendToBuffer("imul%c %s,%s,0x%x",
1427
+ operand_size_code(),
1428
+ NameOfCPURegister(regop),
1429
+ NameOfCPURegister(rm), imm);
1430
+ data += 2 + (*data == 0x6B ? 1 : 4);
1431
+ break;
1432
+ }
1433
+
1434
+ case 0x81: // fall through
1435
+ case 0x83: // 0x81 with sign extension bit set
1436
+ data += PrintImmediateOp(data);
1437
+ break;
1438
+
1439
+ case 0x0F:
1440
+ data += TwoByteOpcodeInstruction(data);
1441
+ break;
1442
+
1443
+ case 0x8F: {
1444
+ data++;
1445
+ int mod, regop, rm;
1446
+ get_modrm(*data, &mod, &regop, &rm);
1447
+ if (regop == 0) {
1448
+ AppendToBuffer("pop ");
1449
+ data += PrintRightOperand(data);
1450
+ }
1451
+ }
1452
+ break;
1453
+
1454
+ case 0xFF: {
1455
+ data++;
1456
+ int mod, regop, rm;
1457
+ get_modrm(*data, &mod, &regop, &rm);
1458
+ const char* mnem = NULL;
1459
+ switch (regop) {
1460
+ case 0:
1461
+ mnem = "inc";
1462
+ break;
1463
+ case 1:
1464
+ mnem = "dec";
1465
+ break;
1466
+ case 2:
1467
+ mnem = "call";
1468
+ break;
1469
+ case 4:
1470
+ mnem = "jmp";
1471
+ break;
1472
+ case 6:
1473
+ mnem = "push";
1474
+ break;
1475
+ default:
1476
+ mnem = "???";
1477
+ }
1478
+ AppendToBuffer(((regop <= 1) ? "%s%c " : "%s "),
1479
+ mnem,
1480
+ operand_size_code());
1481
+ data += PrintRightOperand(data);
1482
+ }
1483
+ break;
1484
+
1485
+ case 0xC7: // imm32, fall through
1486
+ case 0xC6: // imm8
1487
+ {
1488
+ bool is_byte = *data == 0xC6;
1489
+ data++;
1490
+ if (is_byte) {
1491
+ AppendToBuffer("movb ");
1492
+ data += PrintRightByteOperand(data);
1493
+ int32_t imm = *data;
1494
+ AppendToBuffer(",0x%x", imm);
1495
+ data++;
1496
+ } else {
1497
+ AppendToBuffer("mov%c ", operand_size_code());
1498
+ data += PrintRightOperand(data);
1499
+ int32_t imm = *reinterpret_cast<int32_t*>(data);
1500
+ AppendToBuffer(",0x%x", imm);
1501
+ data += 4;
1502
+ }
1503
+ }
1504
+ break;
1505
+
1506
+ case 0x80: {
1507
+ data++;
1508
+ AppendToBuffer("cmpb ");
1509
+ data += PrintRightByteOperand(data);
1510
+ int32_t imm = *data;
1511
+ AppendToBuffer(",0x%x", imm);
1512
+ data++;
1513
+ }
1514
+ break;
1515
+
1516
+ case 0x88: // 8bit, fall through
1517
+ case 0x89: // 32bit
1518
+ {
1519
+ bool is_byte = *data == 0x88;
1520
+ int mod, regop, rm;
1521
+ data++;
1522
+ get_modrm(*data, &mod, &regop, &rm);
1523
+ if (is_byte) {
1524
+ AppendToBuffer("movb ");
1525
+ data += PrintRightByteOperand(data);
1526
+ AppendToBuffer(",%s", NameOfByteCPURegister(regop));
1527
+ } else {
1528
+ AppendToBuffer("mov%c ", operand_size_code());
1529
+ data += PrintRightOperand(data);
1530
+ AppendToBuffer(",%s", NameOfCPURegister(regop));
1531
+ }
1532
+ }
1533
+ break;
1534
+
1535
+ case 0x90:
1536
+ case 0x91:
1537
+ case 0x92:
1538
+ case 0x93:
1539
+ case 0x94:
1540
+ case 0x95:
1541
+ case 0x96:
1542
+ case 0x97: {
1543
+ int reg = (*data & 0x7) | (rex_b() ? 8 : 0);
1544
+ if (reg == 0) {
1545
+ AppendToBuffer("nop"); // Common name for xchg rax,rax.
1546
+ } else {
1547
+ AppendToBuffer("xchg%c rax, %s",
1548
+ operand_size_code(),
1549
+ NameOfCPURegister(reg));
1550
+ }
1551
+ data++;
1552
+ }
1553
+ break;
1554
+ case 0xB0:
1555
+ case 0xB1:
1556
+ case 0xB2:
1557
+ case 0xB3:
1558
+ case 0xB4:
1559
+ case 0xB5:
1560
+ case 0xB6:
1561
+ case 0xB7:
1562
+ case 0xB8:
1563
+ case 0xB9:
1564
+ case 0xBA:
1565
+ case 0xBB:
1566
+ case 0xBC:
1567
+ case 0xBD:
1568
+ case 0xBE:
1569
+ case 0xBF: {
1570
+ // mov reg8,imm8 or mov reg32,imm32
1571
+ byte opcode = *data;
1572
+ data++;
1573
+ bool is_32bit = (opcode >= 0xB8);
1574
+ int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
1575
+ if (is_32bit) {
1576
+ AppendToBuffer("mov%c %s, ",
1577
+ operand_size_code(),
1578
+ NameOfCPURegister(reg));
1579
+ data += PrintImmediate(data, DOUBLEWORD_SIZE);
1580
+ } else {
1581
+ AppendToBuffer("movb %s, ",
1582
+ NameOfByteCPURegister(reg));
1583
+ data += PrintImmediate(data, BYTE_SIZE);
1584
+ }
1585
+ break;
1586
+ }
1587
+ case 0xFE: {
1588
+ data++;
1589
+ int mod, regop, rm;
1590
+ get_modrm(*data, &mod, &regop, &rm);
1591
+ if (regop == 1) {
1592
+ AppendToBuffer("decb ");
1593
+ data += PrintRightByteOperand(data);
1594
+ } else {
1595
+ UnimplementedInstruction();
1596
+ }
1597
+ break;
1598
+ }
1599
+ case 0x68:
1600
+ AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
1601
+ data += 5;
1602
+ break;
1603
+
1604
+ case 0x6A:
1605
+ AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
1606
+ data += 2;
1607
+ break;
1608
+
1609
+ case 0xA1: // Fall through.
1610
+ case 0xA3:
1611
+ switch (operand_size()) {
1612
+ case DOUBLEWORD_SIZE: {
1613
+ const char* memory_location = NameOfAddress(
1614
+ reinterpret_cast<byte*>(
1615
+ *reinterpret_cast<int32_t*>(data + 1)));
1616
+ if (*data == 0xA1) { // Opcode 0xA1
1617
+ AppendToBuffer("movzxlq rax,(%s)", memory_location);
1618
+ } else { // Opcode 0xA3
1619
+ AppendToBuffer("movzxlq (%s),rax", memory_location);
1620
+ }
1621
+ data += 5;
1622
+ break;
1623
+ }
1624
+ case QUADWORD_SIZE: {
1625
+ // New x64 instruction mov rax,(imm_64).
1626
+ const char* memory_location = NameOfAddress(
1627
+ *reinterpret_cast<byte**>(data + 1));
1628
+ if (*data == 0xA1) { // Opcode 0xA1
1629
+ AppendToBuffer("movq rax,(%s)", memory_location);
1630
+ } else { // Opcode 0xA3
1631
+ AppendToBuffer("movq (%s),rax", memory_location);
1632
+ }
1633
+ data += 9;
1634
+ break;
1635
+ }
1636
+ default:
1637
+ UnimplementedInstruction();
1638
+ data += 2;
1639
+ }
1640
+ break;
1641
+
1642
+ case 0xA8:
1643
+ AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1));
1644
+ data += 2;
1645
+ break;
1646
+
1647
+ case 0xA9: {
1648
+ int64_t value = 0;
1649
+ switch (operand_size()) {
1650
+ case WORD_SIZE:
1651
+ value = *reinterpret_cast<uint16_t*>(data + 1);
1652
+ data += 3;
1653
+ break;
1654
+ case DOUBLEWORD_SIZE:
1655
+ value = *reinterpret_cast<uint32_t*>(data + 1);
1656
+ data += 5;
1657
+ break;
1658
+ case QUADWORD_SIZE:
1659
+ value = *reinterpret_cast<int32_t*>(data + 1);
1660
+ data += 5;
1661
+ break;
1662
+ default:
1663
+ UNREACHABLE();
1664
+ }
1665
+ AppendToBuffer("test%c rax,0x%"V8_PTR_PREFIX"x",
1666
+ operand_size_code(),
1667
+ value);
1668
+ break;
1669
+ }
1670
+ case 0xD1: // fall through
1671
+ case 0xD3: // fall through
1672
+ case 0xC1:
1673
+ data += ShiftInstruction(data);
1674
+ break;
1675
+ case 0xD0: // fall through
1676
+ case 0xD2: // fall through
1677
+ case 0xC0:
1678
+ byte_size_operand_ = true;
1679
+ data += ShiftInstruction(data);
1680
+ break;
1681
+
1682
+ case 0xD9: // fall through
1683
+ case 0xDA: // fall through
1684
+ case 0xDB: // fall through
1685
+ case 0xDC: // fall through
1686
+ case 0xDD: // fall through
1687
+ case 0xDE: // fall through
1688
+ case 0xDF:
1689
+ data += FPUInstruction(data);
1690
+ break;
1691
+
1692
+ case 0xEB:
1693
+ data += JumpShort(data);
1694
+ break;
1695
+
1696
+ case 0xF6:
1697
+ byte_size_operand_ = true; // fall through
1698
+ case 0xF7:
1699
+ data += F6F7Instruction(data);
1700
+ break;
1701
+
1702
+ default:
1703
+ UnimplementedInstruction();
1704
+ data += 1;
1705
+ }
1706
+ } // !processed
1707
+
1708
+ if (tmp_buffer_pos_ < sizeof tmp_buffer_) {
1709
+ tmp_buffer_[tmp_buffer_pos_] = '\0';
1710
+ }
1711
+
1712
+ int instr_len = static_cast<int>(data - instr);
1713
+ ASSERT(instr_len > 0); // Ensure progress.
1714
+
1715
+ int outp = 0;
1716
+ // Instruction bytes.
1717
+ for (byte* bp = instr; bp < data; bp++) {
1718
+ outp += v8::internal::OS::SNPrintF(out_buffer + outp, "%02x", *bp);
1719
+ }
1720
+ for (int i = 6 - instr_len; i >= 0; i--) {
1721
+ outp += v8::internal::OS::SNPrintF(out_buffer + outp, " ");
1722
+ }
1723
+
1724
+ outp += v8::internal::OS::SNPrintF(out_buffer + outp, " %s",
1725
+ tmp_buffer_.start());
1726
+ return instr_len;
1727
+ }
1728
+
1729
+ //------------------------------------------------------------------------------
1730
+
1731
+
1732
+ static const char* cpu_regs[16] = {
1733
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1734
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1735
+ };
1736
+
1737
+
1738
+ static const char* byte_cpu_regs[16] = {
1739
+ "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1740
+ "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
1741
+ };
1742
+
1743
+
1744
+ static const char* xmm_regs[16] = {
1745
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1746
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
1747
+ };
1748
+
1749
+
1750
+ const char* NameConverter::NameOfAddress(byte* addr) const {
1751
+ v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
1752
+ return tmp_buffer_.start();
1753
+ }
1754
+
1755
+
1756
+ const char* NameConverter::NameOfConstant(byte* addr) const {
1757
+ return NameOfAddress(addr);
1758
+ }
1759
+
1760
+
1761
+ const char* NameConverter::NameOfCPURegister(int reg) const {
1762
+ if (0 <= reg && reg < 16)
1763
+ return cpu_regs[reg];
1764
+ return "noreg";
1765
+ }
1766
+
1767
+
1768
+ const char* NameConverter::NameOfByteCPURegister(int reg) const {
1769
+ if (0 <= reg && reg < 16)
1770
+ return byte_cpu_regs[reg];
1771
+ return "noreg";
1772
+ }
1773
+
1774
+
1775
+ const char* NameConverter::NameOfXMMRegister(int reg) const {
1776
+ if (0 <= reg && reg < 16)
1777
+ return xmm_regs[reg];
1778
+ return "noxmmreg";
1779
+ }
1780
+
1781
+
1782
+ const char* NameConverter::NameInCode(byte* addr) const {
1783
+ // X64 does not embed debug strings at the moment.
1784
+ UNREACHABLE();
1785
+ return "";
1786
+ }
1787
+
1788
+ //------------------------------------------------------------------------------
1789
+
1790
+ Disassembler::Disassembler(const NameConverter& converter)
1791
+ : converter_(converter) { }
1792
+
1793
+ Disassembler::~Disassembler() { }
1794
+
1795
+
1796
+ int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1797
+ byte* instruction) {
1798
+ DisassemblerX64 d(converter_, CONTINUE_ON_UNIMPLEMENTED_OPCODE);
1799
+ return d.InstructionDecode(buffer, instruction);
1800
+ }
1801
+
1802
+
1803
+ // The X64 assembler does not use constant pools.
1804
+ int Disassembler::ConstantPoolSizeAt(byte* instruction) {
1805
+ return -1;
1806
+ }
1807
+
1808
+
1809
+ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1810
+ NameConverter converter;
1811
+ Disassembler d(converter);
1812
+ for (byte* pc = begin; pc < end;) {
1813
+ v8::internal::EmbeddedVector<char, 128> buffer;
1814
+ buffer[0] = '\0';
1815
+ byte* prev_pc = pc;
1816
+ pc += d.InstructionDecode(buffer, pc);
1817
+ fprintf(f, "%p", prev_pc);
1818
+ fprintf(f, " ");
1819
+
1820
+ for (byte* bp = prev_pc; bp < pc; bp++) {
1821
+ fprintf(f, "%02x", *bp);
1822
+ }
1823
+ for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) {
1824
+ fprintf(f, " ");
1825
+ }
1826
+ fprintf(f, " %s\n", buffer.start());
1827
+ }
1828
+ }
1829
+
1830
+ } // namespace disasm
1831
+
1832
+ #endif // V8_TARGET_ARCH_X64