Skip to content

Commit b6731f6

Browse files
committed
[emscripten] Download the standalone capsule before running engine.
Emscripten provides a "run dependency" mechanism for preventing the program from being started until a set of dependencies are filled. This is used by Emscripten for downloading the initial memory image and any filesystem files provided via emcc's `--preload-file` argument. This patch makes the emscripten-js standalone engine use the same dependency mechanism for downloading the standalone capsule (which is expected to be a zip file containing the boot filesystem image for the engine). `em-preamble.js` is included at the start of the compiled JavaScript file and is run before anything else. The new code defines several new entries in the `Module` object: * `livecodeStandalone`: the filename for the standalone zip file * `livecodeStandalonePrefixURL`: prepended to `livecodeStandalone` to create a URL * `livecodeStandaloneRequest`: The `XMLHttpRequest` instance for downloading the standalone file.
1 parent 82a7fdb commit b6731f6

4 files changed

Lines changed: 112 additions & 1 deletion

File tree

engine/emscripten-javascriptify.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ input=$1
1616
output=$2
1717
exports=$3
1818
whitelist=$4
19-
shift 4
19+
preamble=$5
20+
shift 5
2021

2122
for lib in $@ ; do
2223
libs+=\ --js-library\ "${lib}"
@@ -34,5 +35,6 @@ emcc -O2 -g ${CFLAGS} \
3435
-s ALLOW_MEMORY_GROWTH=1 \
3536
-s TOTAL_MEMORY=67108864 \
3637
--preload-file boot \
38+
--pre-js "${preamble}" \
3739
${libs}
3840

engine/engine-sources.gypi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@
734734
'src/em-main.cpp',
735735
'src/em-osspec-misc.cpp',
736736
'src/em-osspec-network.cpp',
737+
'src/em-preamble.js',
737738
'src/em-resolution.cpp',
738739
'src/em-stack.cpp',
739740
'src/em-surface.h',

engine/engine.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@
772772
'<(PRODUCT_DIR)/standalone-community.bc',
773773
'src/em-exported.json',
774774
'src/em-whitelist.json',
775+
'src/em-preamble.js',
775776
'src/em-util.js',
776777
'src/em-async.js',
777778
'src/em-event.js',
@@ -792,6 +793,7 @@
792793
'<(PRODUCT_DIR)/standalone-community.html',
793794
'src/em-exported.json',
794795
'src/em-whitelist.json',
796+
'src/em-preamble.js',
795797
'src/em-util.js',
796798
'src/em-async.js',
797799
'src/em-event.js',

engine/src/em-preamble.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* -*-Javascript-*-
2+
3+
Copyright (C) 2015 Runtime Revolution Ltd.
4+
5+
This file is part of LiveCode.
6+
7+
LiveCode is free software; you can redistribute it and/or modify it under
8+
the terms of the GNU General Public License v3 as published by the Free
9+
Software Foundation.
10+
11+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
12+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
18+
19+
// The code in this file is run before the Emscripten engine starts.
20+
21+
// Ensure that there is a Module object.
22+
23+
var Module;
24+
if (!Module) {
25+
Module = (typeof Module !== 'undefined' ? Module : null) || {};
26+
}
27+
28+
// ----------------------------------------------------------------
29+
// Download standalone capsule
30+
// ----------------------------------------------------------------
31+
32+
// Ensure the Module object has a preRun list
33+
if (!Module['preRun']) {
34+
Module['preRun'] = [];
35+
}
36+
37+
// Before the engine is allowed to start, we download the standalone
38+
// capsule, which is a zip file containing the root filesystem to be
39+
// used by the engine.
40+
//
41+
// There are several entries in the Module object that are used when
42+
// downloading the capsule:
43+
//
44+
// * Module['livecodeStandalone'] is the filename of the standalone
45+
// zip file. If it's not provided, the default value is
46+
// 'standalone.zip'.
47+
//
48+
// * Module['locateFile'] is a function that takes a filename and
49+
// returns a corresponding URL.
50+
//
51+
// * Module['livecodeStandalonePrefixURL'] is prepended to the
52+
// standalone filename if there's no locateFile function available.
53+
//
54+
// * Module['livecodeStandaloneRequest'] stores the XMLHttpRequest()
55+
// object used to download the standalone file, for later use.
56+
57+
// FIXME Should this be moved into the engine?
58+
59+
Module['preRun'].push(function() {
60+
61+
// Block running the engine
62+
Module['addRunDependency']('livecodeStandalone');
63+
64+
// Compute the URL from which to download the capsule
65+
var standalone = 'standalone.zip';
66+
67+
if (Module['livecodeStandalone']) {
68+
standalone = Module['livecodeStandalone'];
69+
}
70+
71+
if (typeof Module['locateFile'] === 'function') {
72+
standalone = Module['locateFile'](standalone);
73+
} else if (Module['livecodeStandalonePrefixURL']) {
74+
standalone = Module['livecodeStandalonePrefixURL'] + standalone;
75+
}
76+
77+
// Download the capsule
78+
79+
// FIXME Can we cache the capsule locally?
80+
81+
if (!Module['livecodeStandaloneRequest']) {
82+
var xhr = new XMLHttpRequest();
83+
84+
xhr.addEventListener('load', function(e) {
85+
if (xhr.status !== 200 && xhr.status !== 0) {
86+
throw 'Could not download LiveCode standalone';
87+
}
88+
89+
if (!xhr.response ||
90+
typeof xhr.response !== 'object' ||
91+
!xhr.response.byteLength) {
92+
throw 'Bad result when downloading LiveCode standalone';
93+
}
94+
95+
// Unblock running the engine
96+
Module['removeRunDependency']('livecodeStandalone');
97+
});
98+
99+
xhr.open("GET", standalone);
100+
xhr.responseType = "arraybuffer";
101+
xhr.send();
102+
103+
// Save the request in the Module object for future reference.
104+
Module['livecodeStandaloneRequest'] = xhr;
105+
}
106+
});

0 commit comments

Comments
 (0)