ffi.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * @namespace Sk.ffi
  3. *
  4. */
  5. Sk.ffi = Sk.ffi || {};
  6. /**
  7. * maps from Javascript Object/Array/string to Python dict/list/str.
  8. *
  9. * only works on basic objects that are being used as storage, doesn't handle
  10. * functions, etc.
  11. */
  12. Sk.ffi.remapToPy = function (obj) {
  13. var k;
  14. var kvs;
  15. var i;
  16. var arr;
  17. if (Object.prototype.toString.call(obj) === "[object Array]") {
  18. arr = [];
  19. for (i = 0; i < obj.length; ++i) {
  20. arr.push(Sk.ffi.remapToPy(obj[i]));
  21. }
  22. return new Sk.builtin.list(arr);
  23. } else if (obj === null) {
  24. return Sk.builtin.none.none$;
  25. } else if (typeof obj === "object") {
  26. kvs = [];
  27. for (k in obj) {
  28. kvs.push(Sk.ffi.remapToPy(k));
  29. kvs.push(Sk.ffi.remapToPy(obj[k]));
  30. }
  31. return new Sk.builtin.dict(kvs);
  32. } else if (typeof obj === "string") {
  33. return new Sk.builtin.str(obj);
  34. } else if (typeof obj === "number") {
  35. return Sk.builtin.assk$(obj);
  36. } else if (typeof obj === "boolean") {
  37. return new Sk.builtin.bool(obj);
  38. }
  39. goog.asserts.fail("unhandled remap type " + typeof(obj));
  40. };
  41. goog.exportSymbol("Sk.ffi.remapToPy", Sk.ffi.remapToPy);
  42. /**
  43. * Maps from Python dict/list/str/number to Javascript Object/Array/string/number.
  44. *
  45. * If obj is a
  46. *
  47. * @param obj {Object} Any Python object (except a function)
  48. *
  49. */
  50. Sk.ffi.remapToJs = function (obj) {
  51. var i;
  52. var kAsJs;
  53. var v;
  54. var iter, k;
  55. var ret;
  56. if (obj instanceof Sk.builtin.dict) {
  57. ret = {};
  58. for (iter = obj.tp$iter(), k = iter.tp$iternext();
  59. k !== undefined;
  60. k = iter.tp$iternext()) {
  61. v = obj.mp$subscript(k);
  62. if (v === undefined) {
  63. v = null;
  64. }
  65. kAsJs = Sk.ffi.remapToJs(k);
  66. // todo; assert that this is a reasonble lhs?
  67. ret[kAsJs] = Sk.ffi.remapToJs(v);
  68. }
  69. return ret;
  70. } else if (obj instanceof Sk.builtin.list || obj instanceof Sk.builtin.tuple) {
  71. ret = [];
  72. for (i = 0; i < obj.v.length; ++i) {
  73. ret.push(Sk.ffi.remapToJs(obj.v[i]));
  74. }
  75. return ret;
  76. } else if (obj instanceof Sk.builtin.bool) {
  77. return obj.v ? true : false;
  78. } else if (obj instanceof Sk.builtin.int_) {
  79. return Sk.builtin.asnum$(obj);
  80. } else if (obj instanceof Sk.builtin.float_) {
  81. // If you use builtin.asnum, you'll let 0.0 -> 0
  82. //return Sk.builtin.asnum$(obj);
  83. return obj.v;
  84. } else if (obj instanceof Sk.builtin.lng) {
  85. return Sk.builtin.asnum$(obj);
  86. } else if (typeof obj === "number" || typeof obj === "boolean") {
  87. return obj;
  88. } else {
  89. return obj.v;
  90. }
  91. };
  92. goog.exportSymbol("Sk.ffi.remapToJs", Sk.ffi.remapToJs);
  93. Sk.ffi.callback = function (fn) {
  94. if (fn === undefined) {
  95. return fn;
  96. }
  97. return function () {
  98. return Sk.misceval.apply(fn, undefined, undefined, undefined, Array.prototype.slice.call(arguments, 0));
  99. };
  100. };
  101. goog.exportSymbol("Sk.ffi.callback", Sk.ffi.callback);
  102. Sk.ffi.stdwrap = function (type, towrap) {
  103. var inst = new type();
  104. inst["v"] = towrap;
  105. return inst;
  106. };
  107. goog.exportSymbol("Sk.ffi.stdwrap", Sk.ffi.stdwrap);
  108. /**
  109. * for when the return type might be one of a variety of basic types.
  110. * number|string, etc.
  111. */
  112. Sk.ffi.basicwrap = function (obj) {
  113. if (obj instanceof Sk.builtin.int_) {
  114. return Sk.builtin.asnum$(obj);
  115. }
  116. if (obj instanceof Sk.builtin.float_) {
  117. return Sk.builtin.asnum$(obj);
  118. }
  119. if (obj instanceof Sk.builtin.lng) {
  120. return Sk.builtin.asnum$(obj);
  121. }
  122. if (typeof obj === "number" || typeof obj === "boolean") {
  123. return obj;
  124. }
  125. if (typeof obj === "string") {
  126. return new Sk.builtin.str(obj);
  127. }
  128. goog.asserts.fail("unexpected type for basicwrap");
  129. };
  130. goog.exportSymbol("Sk.ffi.basicwrap", Sk.ffi.basicwrap);
  131. Sk.ffi.unwrapo = function (obj) {
  132. if (obj === undefined) {
  133. return undefined;
  134. }
  135. return obj["v"];
  136. };
  137. goog.exportSymbol("Sk.ffi.unwrapo", Sk.ffi.unwrapo);
  138. Sk.ffi.unwrapn = function (obj) {
  139. if (obj === null) {
  140. return null;
  141. }
  142. return obj["v"];
  143. };
  144. goog.exportSymbol("Sk.ffi.unwrapn", Sk.ffi.unwrapn);