Skip to content
This repository was archived by the owner on Dec 16, 2020. It is now read-only.

Use Emscripten with STANDALONE_WASM=1. #260

Merged
merged 3 commits into from
Oct 19, 2019

Conversation

PiotrSikora
Copy link
Contributor

@PiotrSikora PiotrSikora commented Oct 18, 2019

This PR is a bit overloaded and includes a lot of changes,
but it would be impossible to split them up:

  1. Emscripten: update to 1.38.48.
  2. Emscripten: use "upstream" instead of "fastcomp".
  3. Emscripten: use STANDALONE_WASM=1.
  4. Emscripten: use __wasm_global_ctors.
  5. Emscripten: use WASI calls.
  6. Emscripten: drop underscore prefix.
  7. Emscripten: remove support for the JavaScript-flavored Emscripten.
  8. Runtimes: throw WasmException for function call errors.
  9. Tests: catch DivByZero (which is now an runtime error).
  10. WAVM: update to 2019-10-15.
  11. WAVM: stop using WAVM's Emscripten implementation, since we have our own.
  12. SDK: distribute static libraries instead of the bytecode.

Fixes #77, #212.

Signed-off-by: Piotr Sikora piotrsikora@google.com

This PR is a bit overloaded and includes a lot of changes,
but it would be impossible to split them up:

 1. Emscripten: update to 1.38.48.
 2. Emscripten: use "upstream" instead of "fastcomp".
 3. Emscripten: use STANDALONE_WASM=1.
 4. Emscripten: use __wasm_global_ctors.
 5. Emscripten: use WASI calls.
 6. Emscripten: drop underscore prefix.
 7. Emscripten: remove support for the JavaScript-flavored Emscripten.
 8. Runtimes: throw WasmException for function call errors.
 9. Tests: catch DivByZero (which is now an runtime error).
10. Tests: drop SEGV test, since it's compiled to "unreachable" call.
11. WAVM: update to 2019-10-15.
12. SDK: distribute static libraries instead of the bytecode.

Fixes envoyproxy#77, envoyproxy#212.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
@PiotrSikora PiotrSikora requested a review from jplevyak October 18, 2019 21:41
@PiotrSikora
Copy link
Contributor Author

@AndrewScheidecker WAVM isn't running as part of CI, so you cannot see it here, but when updating it from 2019-10-01 (WAVM/WAVM@6146b4e) to 2019-10-15 (WAVM/WAVM@1ec06cd), one of our tests started failing because tryCollectCompartment(std::move(compartment_)) started returning false in a test where WAVM compartment is cloned.

I've tried changing existing code:

std::unique_ptr<WasmVm> Wavm::clone() {
  auto wavm = std::make_unique<Wavm>();
  wavm->compartment_ = WAVM::Runtime::cloneCompartment(compartment_);
  wavm->memory_ = WAVM::Runtime::remapToClonedCompartment(memory_, wavm->compartment_);
  wavm->memory_base_ = WAVM::Runtime::getMemoryBaseAddress(wavm->memory_);
  wavm->context_ = WAVM::Runtime::createContext(wavm->compartment_);
  for (auto& p : intrinsic_module_instances_) {
    wavm->intrinsic_module_instances_.emplace(
        p.first, WAVM::Runtime::remapToClonedCompartment(p.second, wavm->compartment_));
  }
  wavm->module_instance_ =
      WAVM::Runtime::remapToClonedCompartment(module_instance_, wavm->compartment_);
  return wavm;
}

to clone the context instead, i.e.:

 std::unique_ptr<WasmVm> Wavm::clone() {
   auto wavm = std::make_unique<Wavm>();
   wavm->compartment_ = WAVM::Runtime::cloneCompartment(compartment_);
+  wavm->context_ = WAVM::Runtime::cloneContext(context_, wavm->compartment_);
   wavm->memory_ = WAVM::Runtime::remapToClonedCompartment(memory_, wavm->compartment_);
   wavm->memory_base_ = WAVM::Runtime::getMemoryBaseAddress(wavm->memory_);
-  wavm->context_ = WAVM::Runtime::createContext(wavm->compartment_);
   for (auto& p : intrinsic_module_instances_) {
     wavm->intrinsic_module_instances_.emplace(
         p.first, WAVM::Runtime::remapToClonedCompartment(p.second, wavm->compartment_));

but that didn't make any difference.

I've looked at all the commits, but nothing obvious jumps out... any ideas?

cc @jplevyak

@AndrewScheidecker
Copy link

I've looked at all the commits, but nothing obvious jumps out... any ideas?

I think what must be happening is:

  • Your initial Wavm object that you used as the source for the clone is still around, along with its Emscripten::Instance.
  • I added some GCPointer<Function> to Emscripten::Instance here.
  • The WAVM Function objects are strange objects that may be shared between cloned compartments: they are just pointers to a header that is emitted before the machine code for the function.
  • The GCPointer<Function> is treated as a GC root in all compartments that contain the function, and so none of the compartments that were cloned from the original can be collected until the GCPointer<Function> in the Emscripten::Instance is destroyed.

I should perhaps get rid of the GCPointer<Function> in Emscripten::Instance, but I think that there are likely other problems lurking here due to the Emscripten::Instance being shared between cloned compartments. To solve this I could add an API like this:

std::shared_ptr<Emscripten::Instance> remapToClonedCompartment(Emscripten::Instance&,
                                                               Compartment*)

However, I am wondering if you need the Emscripten::Instance at all. It looks like you have your own Emscripten emulation layer, so is it possible to remove WAVM's?

@PiotrSikora
Copy link
Contributor Author

However, I am wondering if you need the Emscripten::Instance at all. It looks like you have your own Emscripten emulation layer, so is it possible to remove WAVM's?

That's an excellent question! We don't need it anymore, and removing it fixes the issue.

Thanks a lot!

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
# basics
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get upgrade -y
apt-get install -y --no-install-recommends apt-utils ca-certificates
apt-get autoremove -y
apt-get clean
apt-get install -y --no-install-recommends software-properties-common apt-transport-https git wget curl libglib2.0-dev autoconf autotools-dev automake libtool cmake python
apt-get install -y --no-install-recommends software-properties-common apt-transport-https git wget curl pkg-config autoconf autotools-dev automake libtool cmake python zlib1g-dev
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious what caused these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed libglib2.0-dev which wasn't necessary (it used to be needed by V8, but it's not anymore, and I'm not sure why it was here in the first place), so I had to add pkg-config and zlib1g-dev directly, since those are needed and were previously installed as transitive dependencies of libglib2.0-dev.

@@ -29,8 +29,7 @@ struct NullVm : public WasmVm {
bool cloneable() override { return true; };
WasmVmPtr clone() override;
bool load(const std::string& code, bool allow_precompiled) override;
void link(absl::string_view debug_name, bool needs_emscripten) override;
void setMemoryLayout(uint64_t, uint64_t, uint64_t) override {}
void link(absl::string_view debug_name) override;
Copy link
Contributor

Choose a reason for hiding this comment

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

We are going to have to upstream this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, V8 isn't merged yet, so it's fine I think.

@PiotrSikora PiotrSikora merged commit e4250bc into envoyproxy:master Oct 19, 2019
PiotrSikora added a commit to PiotrSikora/envoy-wasm that referenced this pull request Oct 21, 2019
We don't need it anymore. Missed in envoyproxy#260.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
PiotrSikora added a commit that referenced this pull request Oct 21, 2019
We don't need it anymore. Missed in #260.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
PiotrSikora added a commit to PiotrSikora/envoy that referenced this pull request Oct 22, 2019
Remove functions that are no longer needed. For details, see:
- envoyproxy/envoy-wasm#260
- envoyproxy/envoy-wasm#262
- envoyproxy/envoy-wasm#263
- envoyproxy/envoy-wasm#268

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
lizan pushed a commit to envoyproxy/envoy that referenced this pull request Oct 24, 2019
Remove functions that are no longer needed. For details, see:
- envoyproxy/envoy-wasm#260
- envoyproxy/envoy-wasm#262
- envoyproxy/envoy-wasm#263
- envoyproxy/envoy-wasm#268

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
jplevyak pushed a commit to jplevyak/envoy-wasm that referenced this pull request Aug 25, 2020
Signed-off-by: gargnupur <gargnupur@google.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch Emscripten from "fastcomp" to "upstream"
3 participants