lib.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. "use strict";
  2. var v86util = v86util || {};
  3. // pad string with spaces on the right
  4. v86util.pads = function(str, len)
  5. {
  6. str = (str || str === 0) ? str + "" : "";
  7. return str.padEnd(len, " ");
  8. };
  9. v86util.check_env_node = function()
  10. {
  11. return typeof process !== "undefined" && process.versions && process.versions.node;
  12. };
  13. // pad string with zeros on the left
  14. v86util.pad0 = function(str, len)
  15. {
  16. str = (str || str === 0) ? str + "" : "";
  17. return str.padStart(len, "0");
  18. };
  19. // generates array given size with zeros
  20. v86util.zeros = function(size)
  21. {
  22. return Array(size).fill(0);
  23. };
  24. // generates [0, 1, 2, ..., size-1]
  25. v86util.range = function(size)
  26. {
  27. return Array.from(Array(size).keys());
  28. };
  29. /**
  30. * number to hex
  31. * @param {number} n
  32. * @param {number=} len
  33. * @return {string}
  34. */
  35. function h(n, len)
  36. {
  37. if(!n)
  38. {
  39. var str = "";
  40. }
  41. else
  42. {
  43. var str = n.toString(16);
  44. }
  45. return "0x" + v86util.pad0(str.toUpperCase(), len || 1);
  46. }
  47. if(typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues)
  48. {
  49. let rand_data = new Int32Array(1);
  50. v86util.has_rand_int = function()
  51. {
  52. return true;
  53. };
  54. v86util.get_rand_int = function()
  55. {
  56. window.crypto.getRandomValues(rand_data);
  57. return rand_data[0];
  58. };
  59. }
  60. else
  61. {
  62. v86util.has_rand_int = function()
  63. {
  64. return false;
  65. };
  66. v86util.get_rand_int = function()
  67. {
  68. console.assert(false);
  69. };
  70. }
  71. /**
  72. * Synchronous access to ArrayBuffer
  73. * @constructor
  74. */
  75. function SyncBuffer(buffer)
  76. {
  77. this.buffer = buffer;
  78. this.byteLength = buffer.byteLength;
  79. this.onload = undefined;
  80. this.onprogress = undefined;
  81. }
  82. SyncBuffer.prototype.load = function()
  83. {
  84. this.onload && this.onload({ buffer: this.buffer });
  85. };
  86. /**
  87. * @param {number} start
  88. * @param {number} len
  89. * @param {function(!Uint8Array)} fn
  90. */
  91. SyncBuffer.prototype.get = function(start, len, fn)
  92. {
  93. dbg_assert(start + len <= this.byteLength);
  94. fn(new Uint8Array(this.buffer, start, len));
  95. };
  96. /**
  97. * @param {number} start
  98. * @param {!Uint8Array} slice
  99. * @param {function()} fn
  100. */
  101. SyncBuffer.prototype.set = function(start, slice, fn)
  102. {
  103. dbg_assert(start + slice.byteLength <= this.byteLength);
  104. new Uint8Array(this.buffer, start, slice.byteLength).set(slice);
  105. fn();
  106. };
  107. /**
  108. * @param {function(!ArrayBuffer)} fn
  109. */
  110. SyncBuffer.prototype.get_buffer = function(fn)
  111. {
  112. fn(this.buffer);
  113. };
  114. (function()
  115. {
  116. var int_log2_table = new Int8Array(256);
  117. for(var i = 0, b = -2; i < 256; i++)
  118. {
  119. if(!(i & i - 1))
  120. b++;
  121. int_log2_table[i] = b;
  122. }
  123. /**
  124. * calculate the integer logarithm base 2 of a byte
  125. * @param {number} x
  126. * @return {number}
  127. */
  128. v86util.int_log2_byte = function(x)
  129. {
  130. dbg_assert(x > 0);
  131. dbg_assert(x < 0x100);
  132. return int_log2_table[x];
  133. };
  134. /**
  135. * calculate the integer logarithm base 2
  136. * @param {number} x
  137. * @return {number}
  138. */
  139. v86util.int_log2 = function(x)
  140. {
  141. x >>>= 0;
  142. dbg_assert(x > 0);
  143. // http://jsperf.com/integer-log2/6
  144. var tt = x >>> 16;
  145. if(tt)
  146. {
  147. var t = tt >>> 8;
  148. if(t)
  149. {
  150. return 24 + int_log2_table[t];
  151. }
  152. else
  153. {
  154. return 16 + int_log2_table[tt];
  155. }
  156. }
  157. else
  158. {
  159. var t = x >>> 8;
  160. if(t)
  161. {
  162. return 8 + int_log2_table[t];
  163. }
  164. else
  165. {
  166. return int_log2_table[x];
  167. }
  168. }
  169. };
  170. })();
  171. /**
  172. * @constructor
  173. *
  174. * Queue wrapper around Uint8Array
  175. * Used by devices such as the PS2 controller
  176. */
  177. function ByteQueue(size)
  178. {
  179. var data = new Uint8Array(size),
  180. start,
  181. end;
  182. dbg_assert((size & size - 1) === 0);
  183. this.length = 0;
  184. this.push = function(item)
  185. {
  186. if(this.length === size)
  187. {
  188. // intentional overwrite
  189. }
  190. else
  191. {
  192. this.length++;
  193. }
  194. data[end] = item;
  195. end = end + 1 & size - 1;
  196. };
  197. this.shift = function()
  198. {
  199. if(!this.length)
  200. {
  201. return -1;
  202. }
  203. else
  204. {
  205. var item = data[start];
  206. start = start + 1 & size - 1;
  207. this.length--;
  208. return item;
  209. }
  210. };
  211. this.peek = function()
  212. {
  213. if(!this.length)
  214. {
  215. return -1;
  216. }
  217. else
  218. {
  219. return data[start];
  220. }
  221. };
  222. this.clear = function()
  223. {
  224. start = 0;
  225. end = 0;
  226. this.length = 0;
  227. };
  228. this.clear();
  229. }
  230. /**
  231. * Simple circular queue for logs
  232. *
  233. * @param {number} size
  234. * @constructor
  235. */
  236. function CircularQueue(size)
  237. {
  238. this.data = [];
  239. this.index = 0;
  240. this.size = size;
  241. }
  242. CircularQueue.prototype.add = function(item)
  243. {
  244. this.data[this.index] = item;
  245. this.index = (this.index + 1) % this.size;
  246. };
  247. CircularQueue.prototype.toArray = function()
  248. {
  249. return [].slice.call(this.data, this.index).concat([].slice.call(this.data, 0, this.index));
  250. };
  251. CircularQueue.prototype.clear = function()
  252. {
  253. this.data = [];
  254. this.index = 0;
  255. };
  256. /**
  257. * @param {Array} new_data
  258. */
  259. CircularQueue.prototype.set = function(new_data)
  260. {
  261. this.data = new_data;
  262. this.index = 0;
  263. };