ICU: enable on wasm

Change-Id: I0647f641d4716af39f4afb832cfcc9fa7d571880
Reviewed-on: https://skia-review.googlesource.com/c/192832
Commit-Queue: Hal Canary <halcanary@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/modules/skshaper/BUILD.gn b/modules/skshaper/BUILD.gn
index bd3e7cd..3db1b91d 100644
--- a/modules/skshaper/BUILD.gn
+++ b/modules/skshaper/BUILD.gn
@@ -19,7 +19,7 @@
     deps = [
       "../..:skia",
     ]
-    if (target_cpu == "wasm" || !skia_use_icu) {
+    if (!skia_use_icu) {
       sources = skia_shaper_primitive_sources
     } else {
       sources = skia_shaper_harfbuzz_sources
diff --git a/third_party/icu/BUILD.gn b/third_party/icu/BUILD.gn
index 0b770f3..34cf40c 100644
--- a/third_party/icu/BUILD.gn
+++ b/third_party/icu/BUILD.gn
@@ -18,9 +18,15 @@
       defines = [ "U_USING_ICU_NAMESPACE=0" ]
     }
   } else {
-    data_assembly = "$target_gen_dir/icudtl_dat.S"
+    if (target_cpu == "wasm") {
+      data_assembly = "$target_gen_dir/icudtl_dat.cpp"
+    } else {
+      data_assembly = "$target_gen_dir/icudtl_dat.S"
+    }
     data_dir = "../externals/icu/"
-    if (is_android) {
+    if (target_cpu == "wasm") {
+      data_dir += "flutter"
+    } else if (is_android) {
       data_dir += "android"
     } else if (is_ios) {
       data_dir += "ios"
@@ -28,19 +34,31 @@
       data_dir += "common"
     }
     action("make_data_assembly") {
-      script = "../externals/icu/scripts/make_data_assembly.py"
-      inputs = [
-        "$data_dir/icudtl.dat",
-      ]
-      outputs = [
-        "$data_assembly",
-      ]
-      args = [
-        rebase_path(inputs[0], root_build_dir),
-        rebase_path(data_assembly, root_build_dir),
-      ]
-      if (is_mac || is_ios) {
-        args += [ "--mac" ]
+      if (target_cpu == "wasm") {
+        _u_icu_version_major_num = "63"  # defined in source/common/unicode/uvernum.h
+        script = "make_data_cpp.py"
+        inputs = [ "$data_dir/icudtl.dat" ]
+        outputs = [ data_assembly ]
+        args = [
+          "icudt${_u_icu_version_major_num}_dat",
+          rebase_path(inputs[0], root_build_dir),
+          rebase_path(data_assembly, root_build_dir),
+        ]
+      } else {
+        script = "../externals/icu/scripts/make_data_assembly.py"
+        inputs = [
+          "$data_dir/icudtl.dat",
+        ]
+        outputs = [
+          "$data_assembly",
+        ]
+        args = [
+          rebase_path(inputs[0], root_build_dir),
+          rebase_path(data_assembly, root_build_dir),
+        ]
+        if (is_mac || is_ios) {
+          args += [ "--mac" ]
+        }
       }
     }
 
diff --git a/third_party/icu/make_data_cpp.py b/third_party/icu/make_data_cpp.py
new file mode 100755
index 0000000..127a495
--- /dev/null
+++ b/third_party/icu/make_data_cpp.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+# Copyright 2019 Google LLC.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+'''
+Generate a source file containing the given binary data.
+
+Output type is C++.
+'''
+
+import os
+import struct
+import sys
+import mmap
+
+def iterate_as_uint32(path):
+    with open(path, 'rb') as f:
+        s = struct.Struct('@I')
+        assert s.size == 4
+        mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
+        assert (len(mm) % s.size) == 0
+        for offset in xrange(0, len(mm), s.size):
+            yield s.unpack_from(mm, offset)[0]
+        mm.close()
+
+
+def convert(fmt, name, src_path, dst_path):
+    header, line_begin, line_end, footer = fmt
+    assert os.path.exists(src_path)
+    src = iterate_as_uint32(src_path)
+    with open(dst_path, 'w') as o:
+        o.write(header.format(name))
+        while True:
+            line = ','.join('%d' % v for _, v in zip(range(8), src))
+            if not line:
+                break
+            o.write('%s%s%s\n' % (line_begin, line, line_end))
+        o.write(footer.format(name))
+
+
+cpp = ('#include <cstdint>\nextern "C" uint32_t {0}[] __attribute__((aligned(16))) = {{\n',
+       '', ',', '}};\n')
+
+if __name__ == '__main__':
+    print '\n'.join('>>>  %r' % x for x in sys.argv)
+    convert(cpp, sys.argv[1], sys.argv[2], sys.argv[3])