SYS_NATIVE_DIR?=$(OBJDIR)/native/net5.0-Browser-$(CONFIG)-wasm/System.Native
BUILDS_BIN_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm
-all: build-native
+all: build-native timezone-data
#
# EMSCRIPTEN SETUP
$(MONO_BIN_DIR)/libmono-icall-table.a \
${SYS_NATIVE_DIR}/libSystem.Native.a
-EMCC_FLAGS=--profiling-funcs -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s ALIASING_FUNCTION_POINTERS=0 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'addFunction']" -s "EXPORTED_FUNCTIONS=['_putchar']" --source-map-base http://example.com -emit-llvm -s FORCE_FILESYSTEM=1 -s USE_ZLIB=1
+EMCC_FLAGS=--profiling-funcs -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s ALIASING_FUNCTION_POINTERS=0 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'UTF8ArrayToString', 'addFunction']" -s "EXPORTED_FUNCTIONS=['_putchar']" --source-map-base http://example.com -emit-llvm -s FORCE_FILESYSTEM=1 -s USE_ZLIB=1
EMCC_DEBUG_FLAGS =-g -Os -s ASSERTIONS=1 -DENABLE_NETCORE=1 -DDEBUG=1
EMCC_RELEASE_FLAGS=-Oz --llvm-opts 2 -DENABLE_NETCORE=1
# Helper targets
.PHONY: runtime
+timezone-data:
+ cp runtime/dotnet.timezones.blat $(BUILDS_BIN_DIR)
+
runtime:
EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh --subset mono --arch wasm --os Browser -c $(CONFIG)
}
function inspect_object (o) {
- var r = "";
- for(var p in o) {
- var t = typeof o[p];
- r += "'" + p + "' => '" + t + "', ";
- }
- return r;
+ var r = "";
+ for(var p in o) {
+ var t = typeof o[p];
+ r += "'" + p + "' => '" + t + "', ";
+ }
+ return r;
}
// Preprocess arguments
args = args.slice (1);
} else if (args [0] == "--enable-zoneinfo") {
enable_zoneinfo = true;
- args = args.slice (1);
+ args = args.slice (1);
} else {
break;
}
if (typeof window == "undefined")
load ("mono-config.js");
-var Module = {
+var Module = {
mainScriptUrlOrBlob: "dotnet.js",
print: print,
Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]);
}
if (enable_zoneinfo) {
- // Load the zoneinfo data into the VFS rooted at /zoneinfo
- FS.mkdir("zoneinfo");
- Module['FS_createPath']('/', 'zoneinfo', true, true);
- Module['FS_createPath']('/zoneinfo', 'Indian', true, true);
- Module['FS_createPath']('/zoneinfo', 'Atlantic', true, true);
- Module['FS_createPath']('/zoneinfo', 'US', true, true);
- Module['FS_createPath']('/zoneinfo', 'Brazil', true, true);
- Module['FS_createPath']('/zoneinfo', 'Pacific', true, true);
- Module['FS_createPath']('/zoneinfo', 'Arctic', true, true);
- Module['FS_createPath']('/zoneinfo', 'America', true, true);
- Module['FS_createPath']('/zoneinfo/America', 'Indiana', true, true);
- Module['FS_createPath']('/zoneinfo/America', 'Argentina', true, true);
- Module['FS_createPath']('/zoneinfo/America', 'Kentucky', true, true);
- Module['FS_createPath']('/zoneinfo/America', 'North_Dakota', true, true);
- Module['FS_createPath']('/zoneinfo', 'Australia', true, true);
- Module['FS_createPath']('/zoneinfo', 'Etc', true, true);
- Module['FS_createPath']('/zoneinfo', 'Asia', true, true);
- Module['FS_createPath']('/zoneinfo', 'Antarctica', true, true);
- Module['FS_createPath']('/zoneinfo', 'Europe', true, true);
- Module['FS_createPath']('/zoneinfo', 'Mexico', true, true);
- Module['FS_createPath']('/zoneinfo', 'Africa', true, true);
- Module['FS_createPath']('/zoneinfo', 'Chile', true, true);
- Module['FS_createPath']('/zoneinfo', 'Canada', true, true);
- var zoneInfoData = read ('zoneinfo.data', 'binary');
- var metadata = JSON.parse(read ("mono-webassembly-zoneinfo-fs-smd.js.metadata", 'utf-8'));
- var files = metadata.files;
- for (var i = 0; i < files.length; ++i) {
- var byteArray = zoneInfoData.subarray(files[i].start, files[i].end);
- writeContentToFile(byteArray, files[i].filename);
- }
+ // The timezone file is generated by https://github.com/dotnet/blazor/tree/master/src/TimeZoneData.
+ // The file format of the TZ file look like so
+ //
+ // [4-byte magic number]
+ // [4 - byte length of manifest]
+ // [json manifest]
+ // [data bytes]
+ //
+ // The json manifest is an array that looks like so:
+ //
+ // [...["America/Fort_Nelson",2249],["America/Glace_Bay",2206]..]
+ //
+ // where the first token in each array is the relative path of the file on disk, and the second is the
+ // length of the file. The starting offset of a file can be calculated using the lengths of all files
+ // that appear prior to it.
+ var zonedata = new Uint8Array(read ("dotnet.timezones.blat", "binary"));
+ MONO.mono_wasm_load_data (zonedata, "/usr/share/zoneinfo");
}
+
MONO.mono_load_runtime_and_bcl (
config.vfs_prefix,
config.deploy_prefix,
const IGNORE_PARAM_COUNT = -1;
var App = {
- init: function () {
+ init: function () {
var assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string'])
var find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string'])
} else {
fail_exec ("Unhanded argument: " + args [0]);
}
- },
+ },
};
// and nested class names like Foo/Bar to Foo.Bar
return className.replace(/\//g, '.').replace(/`\d+/g, '');
},
+
+ mono_wasm_load_data: function (data, prefix) {
+ var dataview = new DataView(data.buffer);
+ var magic = dataview.getUint32(0, true);
+ // get magic number
+ if (magic != 0x626c6174) {
+ throw new Error ("File is of wrong type");
+ }
+ var manifestSize = dataview.getUint32(4, true);
+ var manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize);
+ var manifest = JSON.parse(manifestContent);
+ data = data.slice(manifestSize+8);
+
+ // Create the folder structure
+ // /usr/share/zoneinfo
+ // /usr/share/zoneinfo/Africa
+ // /usr/share/zoneinfo/Asia
+ // ..
+ var p = prefix.slice(1).split('/');
+ p.forEach((v, i) => {
+ FS.mkdir(v);
+ Module['FS_createPath']("/" + p.slice(0, i).join('/'), v, true, true);
+ })
+ var folders = new Set()
+ manifest.filter(m => {
+ m = m[0].split('/')
+ if (m!= null) {
+ if (m.length > 2) folders.add(m.slice(0,m.length-1).join('/'));
+ folders.add(m[0]);
+ }
+ });
+ folders.forEach(folder => {
+ Module['FS_createPath'](prefix, folder, true, true);
+ });
+
+ for (row of manifest) {
+ var name = row[0];
+ var length = row[1];
+ var bytes = data.slice(0, length);
+ Module['FS_createDataFile'](`${prefix}/${name}`, null, bytes, true, true);
+ data = data.slice(length);
+ }
+ }
},
mono_wasm_add_typed_value: function (type, str_value, value) {
mono_wasm_fire_bp: function () {
console.log ("mono_wasm_fire_bp");
debugger;
- }
+ },
};
autoAddDeps(MonoSupportLib, '$MONO')