Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pyodide
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
pyodide
Commits
8e8ac26b
Commit
8e8ac26b
authored
Jan 30, 2019
by
Jason Stafford
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first cut at supporting web workers
parent
61512f17
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
64 additions
and
49 deletions
+64
-49
src/hiwire.c
src/hiwire.c
+1
-1
src/pyodide.js
src/pyodide.js
+59
-44
src/pyproxy.c
src/pyproxy.c
+3
-3
src/runpython.c
src/runpython.c
+1
-1
No files found.
src/hiwire.c
View file @
8e8ac26b
...
@@ -183,7 +183,7 @@ EM_JS(void, hiwire_push_object_pair, (int idobj, int idkey, int idval), {
...
@@ -183,7 +183,7 @@ EM_JS(void, hiwire_push_object_pair, (int idobj, int idkey, int idval), {
EM_JS
(
int
,
hiwire_get_global
,
(
int
idname
),
{
EM_JS
(
int
,
hiwire_get_global
,
(
int
idname
),
{
var
jsname
=
UTF8ToString
(
idname
);
var
jsname
=
UTF8ToString
(
idname
);
return
Module
.
hiwire_new_value
(
window
[
jsname
]);
return
Module
.
hiwire_new_value
(
self
[
jsname
]);
});
});
EM_JS
(
int
,
hiwire_get_member_string
,
(
int
idobj
,
int
idkey
),
{
EM_JS
(
int
,
hiwire_get_member_string
,
(
int
idobj
,
int
idkey
),
{
...
...
src/pyodide.js
View file @
8e8ac26b
...
@@ -6,7 +6,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -6,7 +6,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
// This is filled in by the Makefile to be either a local file or the
// This is filled in by the Makefile to be either a local file or the
// deployed location. TODO: This should be done in a less hacky
// deployed location. TODO: This should be done in a less hacky
// way.
// way.
var
baseURL
=
window
.
languagePluginUrl
||
'
{{DEPLOY}}
'
;
var
baseURL
=
self
.
languagePluginUrl
||
'
{{DEPLOY}}
'
;
baseURL
=
baseURL
.
substr
(
0
,
baseURL
.
lastIndexOf
(
'
/
'
))
+
'
/
'
;
baseURL
=
baseURL
.
substr
(
0
,
baseURL
.
lastIndexOf
(
'
/
'
))
+
'
/
'
;
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
...
@@ -50,7 +50,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -50,7 +50,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
}
catch
{
}
catch
{
return
;
return
;
}
}
for
(
entry
of
dirs
)
{
for
(
let
entry
of
dirs
)
{
if
(
entry
.
startsWith
(
'
.
'
))
{
if
(
entry
.
startsWith
(
'
.
'
))
{
continue
;
continue
;
}
}
...
@@ -76,10 +76,31 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -76,10 +76,31 @@ var languagePluginLoader = new Promise((resolve, reject) => {
}
}
// clang-format on
// clang-format on
function
loadScript
(
url
,
onload
,
onerror
)
{
if
(
self
.
document
)
{
// browser
const
script
=
self
.
document
.
createElement
(
'
script
'
);
script
.
src
=
url
;
script
.
onload
=
(
e
)
=>
{
onload
();
};
script
.
onerror
=
(
e
)
=>
{
onerror
();
};
self
.
document
.
body
.
appendChild
(
script
);
}
else
if
(
self
.
importScripts
)
{
// webworker
try
{
self
.
importScripts
(
url
);
onload
();
}
catch
{
onerror
();
}
}
}
let
_loadPackage
=
(
names
,
messageCallback
)
=>
{
let
_loadPackage
=
(
names
,
messageCallback
)
=>
{
// DFS to find all dependencies of the requested packages
// DFS to find all dependencies of the requested packages
let
packages
=
window
.
pyodide
.
_module
.
packages
.
dependencies
;
let
packages
=
self
.
pyodide
.
_module
.
packages
.
dependencies
;
let
loadedPackages
=
window
.
pyodide
.
loadedPackages
;
let
loadedPackages
=
self
.
pyodide
.
loadedPackages
;
let
queue
=
[].
concat
(
names
||
[]);
let
queue
=
[].
concat
(
names
||
[]);
let
toLoad
=
new
Array
();
let
toLoad
=
new
Array
();
while
(
queue
.
length
)
{
while
(
queue
.
length
)
{
...
@@ -124,7 +145,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -124,7 +145,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
}
}
}
}
window
.
pyodide
.
_module
.
locateFile
=
(
path
)
=>
{
self
.
pyodide
.
_module
.
locateFile
=
(
path
)
=>
{
// handle packages loaded from custom URLs
// handle packages loaded from custom URLs
let
package
=
path
.
replace
(
/
\.
data$/
,
""
);
let
package
=
path
.
replace
(
/
\.
data$/
,
""
);
if
(
package
in
toLoad
)
{
if
(
package
in
toLoad
)
{
...
@@ -152,14 +173,14 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -152,14 +173,14 @@ var languagePluginLoader = new Promise((resolve, reject) => {
// exactly "toLoad * 2" times.
// exactly "toLoad * 2" times.
var
packageCounter
=
Object
.
keys
(
toLoad
).
length
*
2
;
var
packageCounter
=
Object
.
keys
(
toLoad
).
length
*
2
;
window
.
pyodide
.
_module
.
monitorRunDependencies
=
()
=>
{
self
.
pyodide
.
_module
.
monitorRunDependencies
=
()
=>
{
packageCounter
--
;
packageCounter
--
;
if
(
packageCounter
===
0
)
{
if
(
packageCounter
===
0
)
{
for
(
let
package
in
toLoad
)
{
for
(
let
package
in
toLoad
)
{
window
.
pyodide
.
loadedPackages
[
package
]
=
toLoad
[
package
];
self
.
pyodide
.
loadedPackages
[
package
]
=
toLoad
[
package
];
}
}
delete
window
.
pyodide
.
_module
.
monitorRunDependencies
;
delete
self
.
pyodide
.
_module
.
monitorRunDependencies
;
window
.
removeEventListener
(
'
error
'
,
windowErrorHandler
);
self
.
removeEventListener
(
'
error
'
,
windowErrorHandler
);
if
(
!
isFirefox
)
{
if
(
!
isFirefox
)
{
preloadWasm
().
then
(()
=>
{
resolve
(
`Loaded
${
packageList
}
`
)});
preloadWasm
().
then
(()
=>
{
resolve
(
`Loaded
${
packageList
}
`
)});
}
else
{
}
else
{
...
@@ -171,42 +192,41 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -171,42 +192,41 @@ var languagePluginLoader = new Promise((resolve, reject) => {
// Add a handler for any exceptions that are thrown in the process of
// Add a handler for any exceptions that are thrown in the process of
// loading a package
// loading a package
var
windowErrorHandler
=
(
err
)
=>
{
var
windowErrorHandler
=
(
err
)
=>
{
delete
window
.
pyodide
.
_module
.
monitorRunDependencies
;
delete
self
.
pyodide
.
_module
.
monitorRunDependencies
;
window
.
removeEventListener
(
'
error
'
,
windowErrorHandler
);
self
.
removeEventListener
(
'
error
'
,
windowErrorHandler
);
// Set up a new Promise chain, since this one failed
// Set up a new Promise chain, since this one failed
loadPackagePromise
=
new
Promise
((
resolve
)
=>
resolve
());
loadPackagePromise
=
new
Promise
((
resolve
)
=>
resolve
());
reject
(
err
.
message
);
reject
(
err
.
message
);
};
};
window
.
addEventListener
(
'
error
'
,
windowErrorHandler
);
self
.
addEventListener
(
'
error
'
,
windowErrorHandler
);
for
(
let
package
in
toLoad
)
{
for
(
let
package
in
toLoad
)
{
let
script
=
document
.
createElement
(
'
script
'
)
;
let
script
Src
;
let
package_uri
=
toLoad
[
package
];
let
package_uri
=
toLoad
[
package
];
if
(
package_uri
==
'
default channel
'
)
{
if
(
package_uri
==
'
default channel
'
)
{
script
.
s
rc
=
`
${
baseURL
}${
package
}
.js`
;
script
S
rc
=
`
${
baseURL
}${
package
}
.js`
;
}
else
{
}
else
{
script
.
s
rc
=
`
${
package_uri
}
`
;
script
S
rc
=
`
${
package_uri
}
`
;
}
}
script
.
onerror
=
(
e
)
=>
{
loadScript
(
scriptSrc
,
()
=>
{},
(
)
=>
{
// If the package_uri fails to load, call monitorRunDependencies twice
// If the package_uri fails to load, call monitorRunDependencies twice
// (so packageCounter will still hit 0 and finish loading), and remove
// (so packageCounter will still hit 0 and finish loading), and remove
// the package from toLoad so we don't mark it as loaded.
// the package from toLoad so we don't mark it as loaded.
console
.
error
(
`Couldn't load package from URL
${
script
.
s
rc
}
`
)
console
.
error
(
`Couldn't load package from URL
${
script
S
rc
}
`
)
let
index
=
toLoad
.
indexOf
(
package
);
let
index
=
toLoad
.
indexOf
(
package
);
if
(
index
!==
-
1
)
{
if
(
index
!==
-
1
)
{
toLoad
.
splice
(
index
,
1
);
toLoad
.
splice
(
index
,
1
);
}
}
for
(
let
i
=
0
;
i
<
2
;
i
++
)
{
for
(
let
i
=
0
;
i
<
2
;
i
++
)
{
window
.
pyodide
.
_module
.
monitorRunDependencies
();
self
.
pyodide
.
_module
.
monitorRunDependencies
();
}
}
};
});
document
.
body
.
appendChild
(
script
);
}
}
// We have to invalidate Python's import caches, or it won't
// We have to invalidate Python's import caches, or it won't
// see the new files. This is done here so it happens in parallel
// see the new files. This is done here so it happens in parallel
// with the fetching over the network.
// with the fetching over the network.
window
.
pyodide
.
runPython
(
'
import importlib as _importlib
\n
'
+
self
.
pyodide
.
runPython
(
'
import importlib as _importlib
\n
'
+
'
_importlib.invalidate_caches()
\n
'
);
'
_importlib.invalidate_caches()
\n
'
);
});
});
...
@@ -275,7 +295,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -275,7 +295,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
// Loading Pyodide
// Loading Pyodide
let
wasmURL
=
`
${
baseURL
}
pyodide.asm.wasm`
;
let
wasmURL
=
`
${
baseURL
}
pyodide.asm.wasm`
;
let
Module
=
{};
let
Module
=
{};
window
.
Module
=
Module
;
self
.
Module
=
Module
;
Module
.
noImageDecoding
=
true
;
Module
.
noImageDecoding
=
true
;
Module
.
noAudioDecoding
=
true
;
Module
.
noAudioDecoding
=
true
;
...
@@ -303,15 +323,15 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -303,15 +323,15 @@ var languagePluginLoader = new Promise((resolve, reject) => {
Module
.
locateFile
=
(
path
)
=>
baseURL
+
path
;
Module
.
locateFile
=
(
path
)
=>
baseURL
+
path
;
var
postRunPromise
=
new
Promise
((
resolve
,
reject
)
=>
{
var
postRunPromise
=
new
Promise
((
resolve
,
reject
)
=>
{
Module
.
postRun
=
()
=>
{
Module
.
postRun
=
()
=>
{
delete
window
.
Module
;
delete
self
.
Module
;
fetch
(
`
${
baseURL
}
packages.json`
)
fetch
(
`
${
baseURL
}
packages.json`
)
.
then
((
response
)
=>
response
.
json
())
.
then
((
response
)
=>
response
.
json
())
.
then
((
json
)
=>
{
.
then
((
json
)
=>
{
fixRecursionLimit
(
window
.
pyodide
);
fixRecursionLimit
(
self
.
pyodide
);
window
.
pyodide
.
globals
=
self
.
pyodide
.
globals
=
window
.
pyodide
.
runPython
(
'
import sys
\n
sys.modules["__main__"]
'
);
self
.
pyodide
.
runPython
(
'
import sys
\n
sys.modules["__main__"]
'
);
window
.
pyodide
=
makePublicAPI
(
window
.
pyodide
,
PUBLIC_API
);
self
.
pyodide
=
makePublicAPI
(
self
.
pyodide
,
PUBLIC_API
);
window
.
pyodide
.
_module
.
packages
=
json
;
self
.
pyodide
.
_module
.
packages
=
json
;
resolve
();
resolve
();
});
});
};
};
...
@@ -329,28 +349,23 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -329,28 +349,23 @@ var languagePluginLoader = new Promise((resolve, reject) => {
Promise
.
all
([
postRunPromise
,
dataLoadPromise
]).
then
(()
=>
resolve
());
Promise
.
all
([
postRunPromise
,
dataLoadPromise
]).
then
(()
=>
resolve
());
let
data_script
=
document
.
createElement
(
'
script
'
);
const
data_script_src
=
`
${
baseURL
}
pyodide.asm.data.js`
;
data_script
.
src
=
`
${
baseURL
}
pyodide.asm.data.js`
;
loadScript
(
data_script_src
,
()
=>
{
data_script
.
onload
=
(
event
)
=>
{
const
scriptSrc
=
`
${
baseURL
}
pyodide.asm.js`
;
let
script
=
document
.
createElement
(
'
script
'
);
loadScript
(
scriptSrc
,
()
=>
{
script
.
src
=
`
${
baseURL
}
pyodide.asm.js`
;
script
.
onload
=
()
=>
{
// The emscripten module needs to be at this location for the core
// The emscripten module needs to be at this location for the core
// filesystem to install itself. Once that's complete, it will be replaced
// filesystem to install itself. Once that's complete, it will be replaced
// by the call to `makePublicAPI` with a more limited public API.
// by the call to `makePublicAPI` with a more limited public API.
window
.
pyodide
=
pyodide
(
Module
);
self
.
pyodide
=
pyodide
(
Module
);
window
.
pyodide
.
loadedPackages
=
new
Array
();
self
.
pyodide
.
loadedPackages
=
new
Array
();
window
.
pyodide
.
loadPackage
=
loadPackage
;
self
.
pyodide
.
loadPackage
=
loadPackage
;
};
},
()
=>
{});
document
.
head
.
appendChild
(
script
);
},
()
=>
{});
};
document
.
head
.
appendChild
(
data_script
);
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Iodide-specific functionality, that doesn't make sense
// Iodide-specific functionality, that doesn't make sense
// if not using with Iodide.
// if not using with Iodide.
if
(
window
.
iodide
!==
undefined
)
{
if
(
self
.
iodide
!==
undefined
)
{
// Load the custom CSS for Pyodide
// Load the custom CSS for Pyodide
let
link
=
document
.
createElement
(
'
link
'
);
let
link
=
document
.
createElement
(
'
link
'
);
link
.
rel
=
'
stylesheet
'
;
link
.
rel
=
'
stylesheet
'
;
...
@@ -359,7 +374,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
...
@@ -359,7 +374,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
document
.
getElementsByTagName
(
'
head
'
)[
0
].
appendChild
(
link
);
document
.
getElementsByTagName
(
'
head
'
)[
0
].
appendChild
(
link
);
// Add a custom output handler for Python objects
// Add a custom output handler for Python objects
window
.
iodide
.
addOutputHandler
({
self
.
iodide
.
addOutputHandler
({
shouldHandle
:
(
val
)
=>
{
shouldHandle
:
(
val
)
=>
{
return
(
typeof
val
===
'
function
'
&&
return
(
typeof
val
===
'
function
'
&&
pyodide
.
_module
.
PyProxy
.
isPyProxy
(
val
));
pyodide
.
_module
.
PyProxy
.
isPyProxy
(
val
));
...
...
src/pyproxy.c
View file @
8e8ac26b
...
@@ -159,10 +159,10 @@ EM_JS(int, pyproxy_init, (), {
...
@@ -159,10 +159,10 @@ EM_JS(int, pyproxy_init, (), {
get:
function
(
jsobj
,
jskey
)
{
get:
function
(
jsobj
,
jskey
)
{
if
(
jskey
===
'
toString
'
)
{
if
(
jskey
===
'
toString
'
)
{
return
function
()
{
return
function
()
{
if
(
window
.
pyodide
.
repr
===
undefined
)
{
if
(
self
.
pyodide
.
repr
===
undefined
)
{
window
.
pyodide
.
repr
=
window
.
pyodide
.
pyimport
(
'
repr
'
);
self
.
pyodide
.
repr
=
self
.
pyodide
.
pyimport
(
'
repr
'
);
}
}
return
window
.
pyodide
.
repr
(
jsobj
);
return
self
.
pyodide
.
repr
(
jsobj
);
}
}
}
else
if
(
jskey
===
'$$'
)
{
}
else
if
(
jskey
===
'$$'
)
{
return
jsobj
[
'$$'
];
return
jsobj
[
'$$'
];
...
...
src/runpython.c
View file @
8e8ac26b
...
@@ -88,7 +88,7 @@ EM_JS(int, runpython_init_js, (), {
...
@@ -88,7 +88,7 @@ EM_JS(int, runpython_init_js, (), {
if
(
jsimports
.
length
)
{
if
(
jsimports
.
length
)
{
var
packageNames
=
var
packageNames
=
window
.
pyodide
.
_module
.
packages
.
import_name_to_package_name
;
self
.
pyodide
.
_module
.
packages
.
import_name_to_package_name
;
var
packages
=
{};
var
packages
=
{};
for
(
var
i
=
0
;
i
<
jsimports
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
jsimports
.
length
;
++
i
)
{
var
name
=
jsimports
[
i
];
var
name
=
jsimports
[
i
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment