Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow for loading wasm without unsafe wasm execution #1793

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions javascript/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ set(COMPILE_OPTIONS

add_compile_options(${COMPILE_OPTIONS})

link_libraries(embind)

add_library(yogaObjLib OBJECT ${SOURCES})

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)

add_link_options(
${COMPILE_OPTIONS}
"SHELL:--closure 1"
Expand All @@ -45,15 +51,27 @@ add_link_options(
"SHELL:-s EXPORT_ES6=1"
"SHELL:-s WASM=1"
"SHELL:-s TEXTDECODER=0"
# SINGLE_FILE=1 combined with ENVIRONMENT='web' creates code that works on
# both bundlders and Node.
"SHELL:-s SINGLE_FILE=1"
"SHELL:-s ENVIRONMENT='web'")

link_libraries(embind)
add_executable(yoga-wasm-separate-esm $<TARGET_OBJECTS:yogaObjLib>)

add_library(yogaObjLib OBJECT ${SOURCES})

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
add_link_options(
${COMPILE_OPTIONS}
"SHELL:--closure 1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we avoid duplicating the bits here that are not different?

"SHELL:--memory-init-file 0"
"SHELL:--no-entry"
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s ASSERTIONS=0"
"SHELL:-s DYNAMIC_EXECUTION=0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I learned in the other threads, DYNAMIC_EXECUTION=0 might be making the bindings quite a bit slower, if we still end up using it anyways.

Might be worth removing this argument from the base64 variant, or seeing what happens if we add EMBIND_AOT to both (might require bumping emsdk here

const emsdkVersion = '3.1.28';
)

"SHELL:-s EXPORT_NAME='loadYoga'"
"SHELL:-s FETCH_SUPPORT_INDEXEDDB=0"
"SHELL:-s FILESYSTEM=0"
"SHELL:-s MALLOC='emmalloc'"
"SHELL:-s MODULARIZE=1"
"SHELL:-s EXPORT_ES6=1"
"SHELL:-s WASM=1"
"SHELL:-s TEXTDECODER=0"
"SHELL:-s SINGLE_FILE=1"
"SHELL:-s ENVIRONMENT='web'")

add_executable(yoga-wasm-base64-esm $<TARGET_OBJECTS:yogaObjLib>)
17 changes: 13 additions & 4 deletions javascript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ See more at https://yogalayout.dev
## Usage

```ts
import {Yoga, Align} from 'yoga-layout';
import { Align, Yoga } from "yoga-layout";

const node = Yoga.Node.create();
node.setAlignContent(Align.Center);
```

Objects created by `Yoga.<>.create()` are not automatically garbage collected and should be freed once they are no longer in use.
Objects created by `Yoga.<>.create()` are not automatically garbage collected
and should be freed once they are no longer in use.

```ts
// Free a config
Expand All @@ -30,11 +31,19 @@ node.free();

`yoga-layout` requires a toolchain that supports ES Modules and top-level await.

If top-level-await is not supported, use the `yoga-layout/load` entry point instead. This requires to load yoga manually:
If top-level-await is not supported, use the `yoga-layout/load` entry point
instead. This requires to load yoga manually:

```ts
import {loadYoga, Align} from 'yoga-layout/load';
import { Align, loadYoga } from "yoga-layout/load";

const node = (await loadYoga).Node.create();
node.setAlignContent(Align.Center);
```

You can also use `yoga-layout/loadSeparate`, which has the exactly same api as
`yoga-layout/load`, if you want the js and wasm in separate files, this can
useful in several scenarios such as avoiding
[unsafe-wasm-eval](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_webassembly_execution).
Do be aware that this option might not work out of the box with any and all
bundlers or frameworks
3 changes: 2 additions & 1 deletion javascript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./load": "./src/load.ts"
"./load": "./src/load.ts",
"./loadSeparate": "./src/loadSeparate.ts"
},
"files": [
"dist/binaries/**",
Expand Down
25 changes: 25 additions & 0 deletions javascript/src/loadSeparate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

// @ts-ignore untyped from Emscripten
import loadYogaImpl from '../binaries/yoga-wasm-separate-esm.js';
import wrapAssembly from './wrapAssembly.ts';

export type {
Config,
DirtiedFunction,
MeasureFunction,
Node,
Yoga,
} from './wrapAssembly.ts';

export async function loadYoga() {
return wrapAssembly(await loadYogaImpl());
}
export * from './generated/YGEnums.ts';
Loading