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

Adding Browser/WASM template for binding generator #5497

Closed
wants to merge 480 commits into from

Conversation

nhachicha
Copy link
Contributor

@nhachicha nhachicha commented Feb 24, 2023

WIP adding browser template for binding gen.

  • Build the browser target.
cd packages/realm
./build-browser-target.sh
  • Run the sample react app
cd packages/web-example
npm install
npm start 

observe the output in the Dev console

Copy link
Contributor

@RedBeard0531 RedBeard0531 left a comment

Choose a reason for hiding this comment

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

Posting initial feedback before reviewing the main browser.ts template file. I also skipped over the code in packages/realm since it looks like it isn't actually intended to be merged, and web-example since I know basically nothing about react.

@kraenhansen does it make sense to commit this change to package-lock.json or should we revert it for now. It seems like it is a full rewrite of that file. I never know how to handle that and usually just git checkout package-lock.json before committing.

packages/bindgen/CMakeLists.txt Show resolved Hide resolved
packages/bindgen/CMakeLists.txt Outdated Show resolved Hide resolved
packages/bindgen/CMakeLists.txt Show resolved Hide resolved
packages/bindgen/CMakeLists.txt Outdated Show resolved Hide resolved
packages/bindgen/package.json Outdated Show resolved Hide resolved
resolveOnly: ["@realm/network-transport", "path-browserify"],
}),
// We need to use `commonjs` because of "path-browserify"
commonjs(),
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems confusing that we need to use commonjs() when doing format: "es", which I think is the opposite of cjs. @kraenhansen can you look into this and suggest either removing it or wording for a comment that explains why this makes sense even when not output cjs?

Comment on lines +122 to +124
copy({
targets: [{ src: "./generated/ts/realm-js-wasm.wasm", dest: "./dist/" }],
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we instead just generate to the right place? I think this file is now being copied twice after generation which seems silly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the change introduced in #5497 (comment) the realm-js-wasm.was & realm-js-wasm.js will be generated from the bindgen without an extra copy step in cmake. These files will be under packages/realm/generated which is already used by other templates (node/react-native).
Rollup is already bundling realm-js-wasm.js but it's not aware of the wasm file, hence this manual copy to dist

src/browser/platform.cpp Show resolved Hide resolved
packages/bindgen/CMakeLists.txt Outdated Show resolved Hide resolved
${TS_FILES}
)

target_sources(realm-js PRIVATE browser_init.cpp ${CMAKE_JS_SRC} ../../src/browser/platform.cpp)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
target_sources(realm-js PRIVATE browser_init.cpp ${CMAKE_JS_SRC} ../../src/browser/platform.cpp)
target_sources(realm-js PRIVATE browser_init.cpp ../../src/browser/platform.cpp)

CMAKE_JS_SRC is only relevant to Node.js.

packages/bindgen/CMakeLists.txt Show resolved Hide resolved
packages/bindgen/src/templates/browser.ts Show resolved Hide resolved
Comment on lines +68 to +69
const nativeModule = await Module(); // loading WASM
nativeModule.browserInit();
Copy link
Member

Choose a reason for hiding this comment

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

I think this is a good spot to inject things like UUID and Decimal128 on Module and recall them with val::module_property() in C++ instead of relying on the injectables mechanic.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rather we stay consistent between the engines for now, unless there is a good reason to diverge. Is there some benefit to injecting them this way rather than using injectInjectables?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

browserInit(); exists solely to compensate for the lack of "engine registration phase" (i.e NODE_API_NAMED_ADDON(realm_cpp, RealmAddon) or realm_jsi_init which is called from Java_io_realm_react_RealmReactModule_install) which will trigger the creation of the RealmAddon instance.

Registering the JS type should still be done via injectInjectables IMO to keep the separation of concerns ...

@RedBeard0531
Copy link
Contributor

@nhachicha Is it possible to revert your bump of the core submodule for now? I think we are planning on doing the bump soon in the bindgen branch anyway, so I'd rather not do it here too A) so that we don't hit an extra merge conflict and B) to keep this review focused on what is needed to add emscripten/browser support.

...params,
asyncSig ? "_cb" : [],
].flat();
let call = `${native}([${args}])`;
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't notice this change at first. Please change this back to just (${args}). We shouldn't be making a new JS Array every time we call a native function!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's easier to access the args consistently this way in the generated C++ (we don't have a JS engine abstraction like in node and JSI that facilitate accessing the args). Also passing var args is not supported AFAIK from the Embind perspective.

Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to use varargs in C++. When generating the C++, we know exactly how many arguments are going to be passed, so we can just generate a function taking that many args. You can choose between naming the args arg1, arg2,.... so you just need to change arg[${i}] to arg${i}, or you can just use the arg names from the spec (a.name, with '_self' for the this parameter in non-static methods). Slight preference for using the meaningful names, but not a big deal either way.

Copy link
Contributor

Choose a reason for hiding this comment

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

You won't be able to check the number of passed args for error handling, but that is probably fine. I think we can get rid of that everywhere since it is probably unnecessary now that we have the generated JS code to ensure that we always pass the correct number of arguments (although some may be undefined)

nhachicha and others added 2 commits March 1, 2023 13:08
Co-authored-by: Mathias Stearn <redbeard0531@gmail.com>
Co-authored-by: Mathias Stearn <redbeard0531@gmail.com>
@nhachicha
Copy link
Contributor Author

@RedBeard0531 regarding

Posting initial feedback before reviewing the main browser.ts template file. I also skipped over the code in packages/realm since it looks like it isn't actually intended to be merged, and web-example since I know basically nothing about react.

@kraenhansen does it make sense to commit this change to package-lock.json or should we revert it for now. It seems like it is a full rewrite of that file. I never know how to handle that and usually just git checkout package-lock.json before committing.

note that I npm ejected the sample app that @kraenhansen created to access the webpack configuration which allows us to work around an issue see https://github.com/realm/realm-js/pull/5497/files#diff-37e3ecdc2a16d68439cd2d7f3cbf0c0e14b2ac20fc650cb0f1764768e264c921R191-R193
(adding experiments: { topLevelAwait: true})
This has caused all the extra files you see here (and the update to the package-lock)

@nhachicha
Copy link
Contributor Author

@RedBeard0531

@nhachicha Is it possible to revert your bump of the core submodule for now? I think we are planning on doing the bump soon in the bindgen branch anyway, so I'd rather not do it here too A) so that we don't hit an extra merge conflict and B) to keep this review focused on what is needed to add emscripten/browser support.

As discussed on slack, we should probably keep this PR as a feature branch until we have Emscripten support merged in Core/master.

Co-authored-by: Yavor Georgiev <fealebenpae@users.noreply.github.com>
@nhachicha
Copy link
Contributor Author

superseded by #5525

@nhachicha nhachicha closed this Mar 3, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants