Commit 61512f17 authored by Jason Stafford's avatar Jason Stafford Committed by GitHub

Merge pull request #1 from iodide-project/master

merge from root
parents 4166c00c 50f630c8
...@@ -29,7 +29,7 @@ LDFLAGS=\ ...@@ -29,7 +29,7 @@ LDFLAGS=\
-s EMULATE_FUNCTION_POINTER_CASTS=1 \ -s EMULATE_FUNCTION_POINTER_CASTS=1 \
-s LINKABLE=1 \ -s LINKABLE=1 \
-s EXPORT_ALL=1 \ -s EXPORT_ALL=1 \
-s EXPORTED_FUNCTIONS='["___cxa_guard_acquire"]' \ -s EXPORTED_FUNCTIONS='["___cxa_guard_acquire", "__ZNSt3__28ios_base4initEPv"]' \
-s WASM=1 \ -s WASM=1 \
-s SWAPPABLE_ASM_MODULE=1 \ -s SWAPPABLE_ASM_MODULE=1 \
-s USE_FREETYPE=1 \ -s USE_FREETYPE=1 \
......
...@@ -60,7 +60,7 @@ EM_JS(int, hiwire_string_ucs4, (int ptr, int len), { ...@@ -60,7 +60,7 @@ EM_JS(int, hiwire_string_ucs4, (int ptr, int len), {
var jsstr = ""; var jsstr = "";
var idx = ptr / 4; var idx = ptr / 4;
for (var i = 0; i < len; ++i) { for (var i = 0; i < len; ++i) {
jsstr += String.fromCharCode(Module.HEAPU32[idx + i]); jsstr += String.fromCodePoint(Module.HEAPU32[idx + i]);
} }
return Module.hiwire_new_value(jsstr); return Module.hiwire_new_value(jsstr);
}); });
......
...@@ -9,9 +9,15 @@ ...@@ -9,9 +9,15 @@
// bubble out to Python // bubble out to Python
int int
_js2python_string(char* val) _js2python_allocate_string(int size, int max_code_point)
{ {
return (int)PyUnicode_FromString(val); return (int)PyUnicode_New(size, max_code_point);
}
int
_js2python_get_ptr(int obj)
{
return (int)PyUnicode_DATA((PyObject*)obj);
} }
int int
...@@ -68,9 +74,50 @@ EM_JS(int, __js2python, (int id), { ...@@ -68,9 +74,50 @@ EM_JS(int, __js2python, (int id), {
var value = Module.hiwire_get_value(id); var value = Module.hiwire_get_value(id);
var type = typeof value; var type = typeof value;
if (type === 'string') { if (type === 'string') {
var charptr = allocate(intArrayFromString(value), 'i8', ALLOC_NORMAL); // The general idea here is to allocate a Python string and then
var result = __js2python_string(charptr); // have Javascript write directly into its buffer. We first need
_free(charptr); // to determine if is needs to be a 1-, 2- or 4-byte string, since
// Python handles all 3.
var max_code_point = 0;
var length = value.length;
for (var i = 0; i < value.length; i++) {
code_point = value.codePointAt(i);
max_code_point = Math.max(max_code_point, code_point);
if (code_point > 0xffff) {
// If we have a code point requiring UTF-16 surrogate pairs, the
// number of characters (codePoints) is less than value.length,
// so skip the next charCode and subtract 1 from the length.
i++;
length--;
}
}
var result = __js2python_allocate_string(length, max_code_point);
if (result == 0) {
return 0;
}
var ptr = __js2python_get_ptr(result);
if (max_code_point > 0xffff) {
ptr = ptr / 4;
for (var i = 0, j = 0; j < length; i++, j++) {
var code_point = value.codePointAt(i);
Module.HEAPU32[ptr + j] = code_point;
if (code_point > 0xffff) {
i++;
}
}
} else if (max_code_point > 0xff) {
ptr = ptr / 2;
for (var i = 0; i < length; i++) {
Module.HEAPU16[ptr + i] = value.codePointAt(i);
}
} else {
for (var i = 0; i < length; i++) {
Module.HEAPU8[ptr + i] = value.codePointAt(i);
}
}
return result; return result;
} else if (type === 'number') { } else if (type === 'number') {
return __js2python_number(value); return __js2python_number(value);
......
...@@ -200,13 +200,15 @@ JsProxy_IterNext(PyObject* o) ...@@ -200,13 +200,15 @@ JsProxy_IterNext(PyObject* o)
int iddone = hiwire_get_member_string(idresult, (int)"done"); int iddone = hiwire_get_member_string(idresult, (int)"done");
int done = hiwire_nonzero(iddone); int done = hiwire_nonzero(iddone);
hiwire_decref(iddone); hiwire_decref(iddone);
if (done) {
return NULL;
}
PyObject* pyvalue = NULL;
if (!done) {
int idvalue = hiwire_get_member_string(idresult, (int)"value"); int idvalue = hiwire_get_member_string(idresult, (int)"value");
PyObject* pyvalue = js2python(idvalue); pyvalue = js2python(idvalue);
hiwire_decref(idvalue); hiwire_decref(idvalue);
}
hiwire_decref(idresult);
return pyvalue; return pyvalue;
} }
......
...@@ -16,3 +16,15 @@ def test_svg(selenium): ...@@ -16,3 +16,15 @@ def test_svg(selenium):
content = selenium.run("fd.getvalue().decode('utf8')") content = selenium.run("fd.getvalue().decode('utf8')")
assert len(content) == 15752 assert len(content) == 15752
assert content.startswith("<?xml") assert content.startswith("<?xml")
def test_pdf(selenium):
selenium.load_package("matplotlib")
selenium.run("from matplotlib import pyplot as plt")
selenium.run("plt.figure()")
selenium.run("x = plt.plot([1,2,3])")
selenium.run("import io")
selenium.run("fd = io.BytesIO()")
selenium.run("plt.savefig(fd, format='pdf')")
content = selenium.run("fd.getvalue()")
assert len(content) == 5559
...@@ -34,6 +34,8 @@ def test_python2js(selenium): ...@@ -34,6 +34,8 @@ def test_python2js(selenium):
'return pyodide.runPython("\'ιωδιούχο\'") === "ιωδιούχο"') 'return pyodide.runPython("\'ιωδιούχο\'") === "ιωδιούχο"')
assert selenium.run_js( assert selenium.run_js(
'return pyodide.runPython("\'碘化物\'") === "碘化物"') 'return pyodide.runPython("\'碘化物\'") === "碘化物"')
assert selenium.run_js(
'return pyodide.runPython("\'🐍\'") === "🐍"')
assert selenium.run_js( assert selenium.run_js(
'let x = pyodide.runPython("b\'bytes\'");\n' 'let x = pyodide.runPython("b\'bytes\'");\n'
'return (x instanceof window.Uint8ClampedArray) && ' 'return (x instanceof window.Uint8ClampedArray) && '
...@@ -156,7 +158,9 @@ def test_pythonexc2js(selenium): ...@@ -156,7 +158,9 @@ def test_pythonexc2js(selenium):
def test_js2python(selenium): def test_js2python(selenium):
selenium.run_js( selenium.run_js(
""" """
window.jsstring = "碘化物"; window.jsstring_ucs1 = "pyodidé";
window.jsstring_ucs2 = "碘化物";
window.jsstring_ucs4 = "🐍";
window.jsnumber0 = 42; window.jsnumber0 = 42;
window.jsnumber1 = 42.5; window.jsnumber1 = 42.5;
window.jsundefined = undefined; window.jsundefined = undefined;
...@@ -170,8 +174,14 @@ def test_js2python(selenium): ...@@ -170,8 +174,14 @@ def test_js2python(selenium):
""" """
) )
assert selenium.run( assert selenium.run(
'from js import jsstring\n' 'from js import jsstring_ucs1\n'
'jsstring == "碘化物"') 'jsstring_ucs1 == "pyodidé"')
assert selenium.run(
'from js import jsstring_ucs2\n'
'jsstring_ucs2 == "碘化物"')
assert selenium.run(
'from js import jsstring_ucs4\n'
'jsstring_ucs4 == "🐍"')
assert selenium.run( assert selenium.run(
'from js import jsnumber0\n' 'from js import jsnumber0\n'
'jsnumber0 == 42') 'jsnumber0 == 42')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment