Skip to content

Latest commit

 

History

History
1965 lines (1057 loc) · 118 KB

CG-10.md

File metadata and controls

1965 lines (1057 loc) · 118 KB

WebAssembly logo

Table of Contents

Agenda for the October meeting of WebAssembly's Community Group

  • Host: Google, München, Germany
  • Dates: Wednesday-Thursday, October 11-12, 2023
  • Times: 9:00AM - 5:00PM
  • Agenda items:
    • Please use the github issue to discuss agenda items.
  • Video Meeting:
    • Link sent to registered attendees.
  • Location:
    • Erika-Mann-Straße 33, 80636 München, Germany
  • Wifi: TBD
  • Code of conduct:

Research Day

Registration

Registration closed, email the WebAssembly CG chairs if you would like to attend.

Logistics

Getting to the venue

The event will take place in the Munich Google office, Erika-Mann-Straße 33, 80636 Munich, Germany.

Coming from the main station, you can take the tram lines 16 (direction "Romanplatz") and 17 (direction "Amalienburgstraße") every 5 mins and leave at "Marsstraße". From there you can cross the street and continue walking across Arnulfpark and you should see the Google building from there. You can also take any S-Bahn train (S1-S8, approximately every 2~mins) from the main station in the direction of "Hackerbrücke" and leave at "Donnersbergerbrücke". From the platform, walk backwards from the direction of travel, walk up the stairs, turn left and exit the pedestrian bridge. The Google building will then be to your right.

If you come straight from the airport, you can take the S-Bahn trains S1 or S8 (it's their respective final stop, so there is only one direction to go) and leave at "Donnersbergerbrücke" as described above.

There is no guest parking at Google and public parking spots are sparse around the office. So we don't recommend going there by car.

On arrival

After entering the inner yard, turn right in the yard and go to the reception where you can pick up your guest badge. If the door is closed, ring the bell and they will open for you. Someone from the organization committee will wait there for you and lead you to the conference room.

Social

  • Adress: Augustiner-Keller, Arnulfstrasse 52 80335 München
  • Date and time: Thursday, Oct 12th from 6:00PM - 8:00PM
  • Details: This event is not sponsored, we should have space for the folks who expressed that they will be available Thursday evening.

Discord channel

This CG meeting has a discord channel for use during the meeting.

Schedule

Wednesday, 11th October

  • Multi-Memory Phase 4 Vote
    • 15 mins (Andreas Rossberg, Ashley Nelson)
  • Extended Name Section: Update and discussion on name declarations
    • 15 mins (Ashley Nelson)
  • Profiles: Introducing new profiles, artifacts, and procedural discussion
    • 60 mins (Andreas Rossberg)
  • Relaxed SIMD: Phase 4 vote
    • 10 mins (Deepti Gandluri)
  • Type Reflection for WebAssembly JavaScript API: Update, tentative poll for Phase 4
    • 30 mins (Ilya Rezvov)
  • Exception handling: Vote on the proposed spec for reintroducing exnref
    • 30 mins (Heejin Ahn, Ben Titzer)
  • Initial work on a DSL for the specification document
    • 40 mins (Andreas Rossberg, Sukyoung Ryu, Conrad Watt)
    • Prefer Wednesday, October 11th
  • Update on threads proposal (with possible phase 4 vote)
    • 30 mins (Conrad Watt)
    • Any day after 3pm Munich time
  • Post-MVP threads discussion (with phase 1 vote) (slides)
    • 60 mins (Andrew Brown, Conrad Watt)
    • Any day after 3pm Munich time

Thursday, 12th October

  • Component Model / WASI status update and next steps (Preview 2) (slides)
    • 30 mins (Luke Wagner)
  • Wasm for Embedded Systems
    • 40 mins (Chris Woods)
    • To end before 12pm Munich time, either day
  • PGO experiments, and compilation hints
    • 30 mins (Emanuel Ziegler)
  • JS string builtins proposal update
    • 30 minutes (Ryan Hunt)
  • WebAssembly Benchmarking Task Force
    • 15 mins (Ben Titzer)
  • DSL for specification: Next steps
    • 30 mins (Andreas Rossberg, Sukyoung Ryu, Conrad Watt)
  • Spritely's use of GC as a target for Scheme compilation
    • 45 mins (Andy Wingo)
  • Wasm_of_ocaml: compiling OCaml bytecode to WasmGC
    • 45 mins (Jérôme Vouillon)
    • Prefer Thursday, October 12th
  • Post-MVP GC discussion
    • 60 mins (Andreas Rossberg)
    • Schedule in the afternoon, US overlap prefered
  • Memory control: Proposal update and Implementation report
    • 45 mins (Deepti Gandluri, Ryan Hunt)

Proposed agenda items (to be scheduled if time permits)

Use this space to add any agenda items that need to be scheduled, and scheduling constraints here, especially if you're not able to travel, but would like to contribute to one of the agenda items. If you are adding a scheduling constraint, add the agenda item you are interested in attending, and timeslots that would work. Adding a constraint doesn't guarantee that we will be able to accommodate it, but we will attempt to make sure interested folks can attend and contribute.

  • Freezable/Sealable GC values and globals proposal for phase 1 (10-15min)

Meeting notes

Attendees

  • Hannes Payer
  • Jakob Kummerow
  • Conrad Watt
  • Adam Klein
  • Chris Woods
  • Thomas Trenner
  • Dan Gohman
  • Marco Kuoni
  • Paolo Severini
  • Philip Pfaffe
  • Sangeeta Kakati
  • Takashi Yamamoto
  • Toni Bofarull Cabello
  • Till Schneidereit
  • Alex Crichton
  • Eva Herencsárová
  • Clemens Backes
  • Daniel Lehmann
  • Edoardo Vacchi
  • Pierre Chambart
  • Thomas Steiner
  • Heejin Ahn
  • Tianshu Huang
  • Arjun Ramesh
  • Elizabeth Gilbert
  • Sukyoung Ryu
  • Wonho Shin
  • Jaehyun Lee
  • Dongjun Youn
  • Emanuel Ziegler
  • Ilya Rezvov
  • Francis McCabe
  • Keith Winstein
  • Zalim Bashorov
  • Paulo Matos
  • Dmitry
  • Ioanna Dimitriou
  • Ayako Akasaka
  • Andy Wingo
  • Ulan Degenbaev
  • Sam Lindley
  • Andreas Rossberg
  • Ryan Hunt
  • Ben Titzer
  • Leo Andres
  • Deepti Gandluri
  • Derek Schuff
  • Yuri Iozzelli
  • Tom Olivier Tartarin
  • Justin Michaud
  • Luke Wagner
  • Brendan Dahl
  • Ashley Nelson
  • Thomas Lively
  • Daniel Hillerstorm
  • Shravan Narayan
  • Mats Brorsson
  • Christine Lemmer-Webber
  • Slava Kuzmich
  • Dan Phillips

Proposals & Discussions (Day 1)

Multi-memory

AR presenting slides

RH: What is the toolchain support in Binaryen?

AN: The IR supports it, we can read and write it.

TL: We use it in wasm-merge, wasm-split. Also as a way lower instrumentation data in a second memory: better than primary memory or globals.

RH: Is that production-ready?

TL: Yes. We also use it for wasm-split instrumentation.

CW: The component bundling tool (JCO?) also has a mode which assumes the presence of multi-memory.

AW: The scheme compiler also supports multiple memories.

RH: The other question is about performance characteristics. In SpiderMonkey we bias toward memory 0.

AR: Right, there is no regression if you pin memory zero to a register. I think wasmtime has special support for multi-memory.

AC: We just use the register allocator for all memories. We definitely need it for the component model / jco.

CB: V8 does not pin the memory to a register, but it caches one memory per function as an SSA value Doesn’t have to be memory 0.

DG: For the vote, we will count hands in the room and chat votes as well.

Poll: Should multi-memory move to phase 4?

SF F N A SA
38 4 1 0 0

(applause)

AR: Thanks.

Extended name section

AN presents. No slides.

AN: Extended name section adds subsections for all module items to the binary name section.

AN: The annotations proposal has a name decorator, "@name". This decorator provides unicode support for names. There was concern from implementors that perhaps it would be better to simply expand the valid character set to UTF-8, instead of the @-prefix.

Andreas pointed out that there might be security issues about unique spoofing and the unicode group published recommendations about that. Wanted to see what people thought about removing the name annotation and extending the extended name section proposal with unicode identifiers.

AR: Desire to avoid e.g. a requirement to normalize unicode before comparing identifiers. We should just compare bytes.

AN: There is some usefulness around normalization: e.g. line break chars that don’t look like line breaks. But I think it doesn’t matter for identifiers.

AR: Line breaks! Let’s disallow them. There are recommendations from Unicode around them and I actually just opened a PR around that, inspired by OCaml’s output, to update the text format.

YI: In the binary format, a name can be an arbitrary binary string? Thinking about round-tripping. What would you do if a name contains a line break char?

AN: We would like to extend identifiers to have unicode, so round-tripping would be fine. (Modulo the discussion about line breaks.)

AR: Not arbitrary byte sequences that we are proposing: rather valid UTF-8. Also in name section. Round-tripping no problem.

TL: Text format also includes escapes for text strings. If there is a “forbidden” char you can introduce it with an escape code.

LW: More generally, Unicode has a definition of what an identifier is. Forbids a number of things. Perhaps we should use that?

AR: Another line that we don’t want to cross. That would require unicode tables in our tools, and that would be a step too far. Also, these aren’t bare identifiers, but well-delimited by quotes with escape sequences.

LW: It seems that surgically removing a few ad-hoc cases like line breaks might not be enough. It would be good to more completely forbid bad things, especially if we can do so without unicode tables?

PC: Does it matter to say that it’s unicode in the format? Binary is not sufficient? Recommendations, of course.

AN: I suspect that is what AR would prefer. Is an option.

AR: Text format does have to be valid UTF-8, for example. No point in allowing arbitrary raw bytes; at that point it’s not text any more.

TL: Builds on things that already exist.

BT: Only current restriction is valid UTF-8. Is this another restriction?

AN: Restriction is for ASCII.

BT: That is just text format. Binary is just bytes.

AR: Names in binary format (import and exports) need to be valid UTF-8.

TL: Let’s take further discussion offline, especially as regards which parts of Unicode to use.

TL: Propose to remove @ prefix from extended names proposal, and hash out the details later. I think we can agree on that at least.

(no objection; applause)

Profiles

AR presenting slides

DG: This is saying that we accept profiles as a part of our spec infrastructure, is that the proposal?

AR: that is part of the discussion, do we want to go there and if so, what is our process

RH: Editorial question: A couple slides ago you said the number of profiles should be small. We also want them to be composable. In the spec are we going to mention every combination as a valid profile? Is there a combinatorial explosion?

AR: Profiles composability is a requirement as far as I’m concerned, but that falls out for free from the subtractive approach of the proposed framework.

RH: Seems like it grows the valid profiles over time because every combination has more than linear growth.

AR: Yes, depending on what you count there, yes. Number of profiles should be defined and small, implicitly the number of combinations grows exponentially with the number of profiles, yes.

RH: Should be motivated by real ecosystems. Some combinations of profiles will not ever be deployed.

AR: I don’t think it matters. Specification stays the same, profiles just remove subsets. No additional spec work as they should compose.

DG: Also seems like that might be defined by who defines profiles to target things. So if you have a toolchain used in a particular ecosystem you can define valid subsets.

AR: Good question though, this is the motivation for “definition by subtraction”: define the whole spec, as one entity, then profiles subtract from it.

TT:: I like the proposal of having profiles because we will need it, e.g. for the relaxed SIMD proposal. How does this interact with orchestration? Deployment tools will need to know where a module can be run.

AR: First answer: this is already the case. Some platforms don’t support certain features. Toolchains already have to adapt, if they want those platforms. Profiles just bless some restrictions, make it clear to toolchains.

TT: If we agree to go on that route, are there any action items or proposals to make it work with other existing tooling, e.g. kubernetes.

AR: Ecosystem is diverse right now. In a single deployment, e.g. Kubernetes, all nodes should have same profile support. This proposal is about different deployment environments.

TT: Last remark: may be possible that different runtimes are in place on different compute nodes, consider edge vs core compute, etc; heterogeneity not unreasonable.

AR: If you want a heterogeneous deployment, your ecosystem will need specific support to indicate which node supports what.

DG: Let’s move to github for this discussion.

FM: Whose job is it to enforce a profile?

AR: It's not about enforcing. It's about engines choosing and providing a profile. It's enforced in the sense that if a producer uses a feature that is not provided, then the module will fail to validate.

FM: Will go offline for rest.

CW: Highlights difference between profiles that semantically subsets wasm vs syntactic subset. OK for producer to target syntactic subset rather than semantic subset.

AR: It’s not like they depend on it. I think that’s a different axis actually

KW: I’m confused, it seems like if a user is targeting a GC-less profile, would we call that invalid or malformed?

AR: Probably disallow the entire syntax or something like that

KW: Would we have negative tests? Would we test that the GC-less profile rejects programs that use GC?

AR: Good question, part of the intent is having a test suite that engines interpret profiles in a standard way.

KW: Flipside for something like deterministic profile it feels like a restriction on the consumer and a consumer which implements the full profile would not be expected to pass the deterministic profile test suite.

AR: Technically you are right there are generic profiles and there are different flavors that come up in practice. Semantic restriction is something that producers can completely ignore, they are not constrained in any way. Just something where consumers restrict semantics. The way you specify that is with reduction rules that are taken out the specification for that profile. Nondeterministicm means overlapping rules that can all apply. Determinism means there are unique rules that apply.

KW: Consumers that implement full profile would fail a test that e.g. wasm is deterministic. How to test?

AR: Yes, but that’s true for all profiles, right?

KW: Implementation with GC would fail GC-less profile tests.

AR: It would not correctly implement the GC profile because that’s supposed to reject the GC instructions. I think I see what you’re getting at but that’s the point where I said that you should never depend on the absence of certain things. The producer should never depend on the consumer being deterministic. The code it generates should always be correct, regardless of whether there is determinism on the consumer side. Under this kind of policy, it shouldn’t matter. If you’re implementing the full thing there are certain behaviors the consumer might not have expected. But the consumer should never expect them to not have. There’s no way to enforce that but that’s what you would want.

JM: I like the proposal. Couple questions: working by subtraction, great. But what are we subtracting? Subtracting production rules is not the right abstraction for implementations. E.g. deterministic profile. If it acted like other profiles, e.g. can’t use instructions that might be nondeterministic, that would work. It would play well with a future feature detection proposal, which the Web sorely needs. I propose that the deterministic profile subsets instructions.

AR: Ideal but it would restrict floating point instructions, the NaN encoding. That’s something people really want to use but in a deterministic fashion. That’s one area where you can’t get around restricting the semantics not the syntax.

JM: That is an example whereby as an implementer I wouldn’t want to provide deterministic floating-point for the web.

AR: For the web, you don’t have to.

JM: You have to because if you support the full language, you should support subsets of the language.

AR: Each consumer picks a fixed profile. This is what I implement. Just one profile. Presumably web is full profile. Blockchain, pick deterministic. But you still support floats on blockchain.

JM; But producers have to be able to work in the full language so picking the detemrinistic profile as a producer means don’t reply on nondeterminism.

AR: For producer determinism is irrelevant.

LW: The producer is

JM: If I assume nondeterminism, and use FP insts… what does that mean to be deterministic?

AR: They normalize NaNs for example.

JM: That would also mean something for the deterministic profile.

AR: For a consumer it means it picks specific well-defined semantics rather than nondeterminism.

TL: Key point is that for every engine that needs to be deterministic, that it is deterministic in the same way.

AR: Improves portability.

JM: That’s the piece

TL: Going back to something we talked about a while ago, deployment engines with different features. Binaryen and LLVM and lots of engines have these sort of feature flags already and in a way these profiles are a way of grouping those together and standardizing them, as a matter of development we are still going to have feature flags because we’ll have new proposals that are experimental so you want to opt-in to them on the consumer/producer side. I think for engines, they can just turn on by default after it’s standardized. For producers, it might not be as easy because you want to support older engines. I don’t see these feature flags going away. Binaryen and engines are not going to delete their feature flags for in production experimental/developmental features. We might add flags for profiles to Binaryen and perhaps to LLVM but I expect that the feature flags are going to remain the primary interface there. You really need to know which engines you’re targeting and which features they support. The profile is a spec to say in the fullness of time a profile may support full features in time, but the tools need to still be ready for there. Questions about deployment as well, if you are deploying kubernetes stuff and different profiles support different features. And different engines have different features, profiles can’t help and you’ll still need feature flags.

AR: Profiles still help but not sufficient. You can still associate profiles with nodes, and agreed there is a closer relation to feature flags at that point. At least it gives you a vocabulary.

YI: Producer is not concerned about profiles… For deterministic, OK, but SIMD? As producer you need to choose, e.g. to explicitly allow or disable the toolchain to produce SIMD.

BT: I think the pressing thing is we need to define the deterministic profile because that’s blocking relaxed SIMD. I think there should be a # of these things, like 5 the spec blesses. The discussion should revolve around ??? embedded are a different thing. Couple years out. We need to make progress on this now.

AR: Goes back to main point: two questions, do we want the mechanism, and then which profiles specifically do we want.

NV: Two consumers, two runtimes one implement a profile and another ??? . Producers should not care about profiles to produce a complete binary but the host application in the runtime knows its in profile 1. Host application assumes host application calls certain functions. But the runtime which implements profile 1, how do you actually panic?

AR: Maybe my phrasing was wrong. “Producer doesn’t care” refers to semantic subsets. For syntactic subsets, sure, the producer has to know what it targets and generate code appropriately.

NV: So compilers should expose profiles as feature flags.

AR: Depends on what compilers you have, if it wants to support multiple profiles, sure. If it's specific to an ecosystem, then you might not need flags.

NV: For a specific wasm library, you might allow it to be compiled for different profiles. For example for a math library that may or may not be able to use SIMD.

CW: Producers signal which instructions they produce based on syntactic profiles. We must never rely on semantic profiles. Let’s keep this distinction clear.

(general agreement.)

TS: I think profiles make sense, including in heterogeneous deployments (k8s). Makes sense to have shared vocabulary. Also, if we give people the ability to make these choices (semantic subsets), then toolchains will support it and we will not like it. One other thing that I don't like too much about this is that I think people will be tempted to just target one profile for one environment, but that relies on a fictional notion of how people choose what to target. Providers will be under pressure to run e.g. Kotlin code, and therefore GC. Languages make these choices and platforms have to follow, not just stick with a profile they think makes sense.

AR: To be clear, this is not a magic solution to make things easier, it is to make things more defined.

TS: Platform providers won’t be able to impose profiles on users. Users will have their own way.

AR: Like if Kotlin wants to run on blockchain, and Kotlin uses threads, there’s just no way that’s going to happen. No magic bullet.

BT: Producers gonna produce. If we give them guidance not to, they will anyway.

CW: Do we avoid this scenario if we say we’re not going to define a deterministic profile?

AR: Going to have deterministic platforms anyway, right?

DG: Break until 11h15. Emphasize AR’s point: this is a way to specify profiles. Incremental improvement. After break: is this an acceptable first step?

– break –

DG: OK, let’s continue with profiles. Is this (a) something we are willing to adopt, knowing that it won’t solve everything? (b) Deterministic profile. Add to spec. Small change. WDYT? What does this group need to see to accept the profiles framework as part of the spec?

AR: Are there concerns to the profiles framework? Setting aside question of specific profiles.

DG: If we accept this framework, profile definition has to follow spec process.

FM: I’m personally vague as to what this profile is intended for. I would suggest doing a low risk experiment. If one wants to know whether the community wants to go down this road. It would be good to have a broad view of the larger scope of profile feature detections, what is it that we would think would be under the scope of this? If it’s minimal, no one is going to be interested but still a business problem worth addressing. Identifying what that is, is easier to decide whether to do it or not.

RH: In terms of adding subset machinery to spec: low-risk. I support it. Especially to unblock relaxed SIMD. If we do that, I would hope we can extend the process doc with a note on how to define additional profiles. Define requirements roughly.

UD: Just wanted to add about business value. Concretely, it would be useful explicitly what is there as a construct between runtime/engine and the user. Right now, we need determinisism and you need for each feature what the runtime flag has to determine determinism. A profile would be a very nice feature

DG: Following from this, are there any objections to accepting the profiles framework and experimenting with the deterministic profile? The prerequisite is to have a process documented, as Ryan mentioned.

ZB: Not objection, but just an observation: for producers it shouldn’t change anything, but semantic things would be observable at runtime and users will start to depend on it. Regarding producers, they will have to support profiles because they will want to target different profiles. It does affect users.

DG: Let’s do a full poll. Seems to me to be valuable to do something in this space, this does sound like an incremental step forward; let’s vote to accept the profiles framework into the specification.

Poll: Should we move forward with experimenting with the profiles framework in the spec syntax?

SF F N A SA
13 22 9 0 0

DG: Let’s move on to a discussion about the deterministic profile. UD mentioned business case to respond to FM’s question; are there other points to discuss?

RH: Clarifying, I know there was an issue about the determinism of threading and numeric instructions. Does this solve that?

DG: Is a reasonable start. Not sure if we want to see anything specific in the threads proposal.

CW: The solution we came to on GitHub is that the deterministic profile would not exclude threads. Many platforms would want to compose the non-deterministic profile with a no-threads profile.

AR: This means that we also have to introduce a no-threads profile at this point.

CW: Do you really mean at this point?

AR: When we move threads to stage 4.

CW: Do we really think that’s true? It’s essentially a defensive measure to avoid fragmentation of the ecosystem. Waiting a few months for all the profiles we expect people to need doesn’t seem like it’ll cause more damage.

DG: Theoretically we know there are ecosystems that care about a no-thread profile. Are there others?

CW: people already dealing with feature flags.

LW: How does deterministic profile support threads? Doesn’t it have to subtract them, to be deterministic?

AR: The suggestion was to rebrand to deterministic numerics or something. You don’t like that ;) I am a bit skeptical of it. It is a conservative starting point to exclude threads and extend it later to include threads.

TL: Not up to date, what’s the background of the rebranding and splitting threads out?

RH: Background is, issue on relaxed SIMD, the actual determinism they were caring about was just in numerics. Threads not an issue for that use case. Some cloud platforms may want deterministic NaNs and so on but also allow threads. How to identify profiles that matter? I am fine with having a plain deterministic profile with no threads plus deterministic numbers. But in fullness of time the concerns might be separable. We could just start with numerics. Fine either way.

BT: Profiles are a part of the spec

TS: You said we can always add things to profiles. During standardization or afterwards?

AR: Afterwards.

TS: Versions of profiles?

AR: It is similar to how you can add instructions to wasm over time.

TL: This is why I said feature flags aren’t going away.

TS: Changes nature of profiles. In this case I would expect versioned profiles to emerge over time.

AR: I would like to avoid this situation if we can. But it’s not a deadend.

BT: Merging things in spec is serialization point: what profiles does a feature go in.

CW: A discomfort I have of deterministic profile of threads immediately is I think it’s messy to have our first profile be a very semantic and syntactic restriction. Or do you think threads would reduce in some way?

AR: Yes I would imagine that

CW: How does a spawn instruction interact with a profile that semantically restricted threads?

AR: Something to figure out. Semantic restriction vs a syntactic restriction. Probably need to account for the possibility of a spawn fail. Unconditionally fails always is one possibility. Not sure if it’s ideal but it’s an option.

TL: Might be neat if nondetermistic profile syntactically forbade shared memories. What other semantic profiles might we ever have? Can we avoid them entirely?

CW: Difficult from composition POV. +deterministic NaN, but still has threads.

AR: Goes back to the question before. With NaNs, no way to have a syntactic restriction.

TL: Which platforms would want to have nondeterministic threads but deterministic NaNs?

CW: The whole Cloud thing. I remember this derailing relaxed SIMD last time.

DS: Cloud system that is heterogeneous. Hypothetical. Migrating workload from one node to another with different semantics.

DG: It was also clarified to be hypothetical at that meeting

DS: That’s why I said “what if”

CW: Against blocking proposals with real-world impact. We can always introduce proposals that need profiles in the future. we can get by with feature flags for a while, if that’s what we want.

AR: We know, it’s not future. It’s now. Consider blockchain.

CW: Nothing is going to blow up because we don’t have profiles today

AR: Just want to remind we had a long discussion about relaxed SIMD a year ago and we said we shouldn’t ship it without deterministic mode.

CW: Fine but if you bring threads into the argument as well, I think that’s too far.

DG: Think that the way we decouple profiles as well as the proposals. Having these proposals advance but having them merge into the spec and figure out determinisim. There’s a way to say that, we have proposals that are at phase 4, and that satisfy the requirements at the time we had them at pbase 4. And as we’re introducing a new spec framework for profiles, we can figure out how to put them into profiles. It’s not built-in to any requirements right now and there is a way to do this where we allow proposals to advance. We’ve had two proposals that have met the requirements for threads and relaxed SIMD. And I don’t think we should block on an orthogonal idea.

AR: Comes down to sequentilization. If we decide to have X and it interacts with Y, we have to solve that. We can’t have a limbo state. No different from regular proposals.

DG: Disagree that it leaves it well-defined, but can take this offline.

CWoods: Yes, determinism is nice, and yes, determinism + threads is nicer.

SL: Can profiles remove features post-release?

AR: Conservative if we disallow threads for now and we can add them later. Desirable maybe, but technically conservative.

RH: Would this allow us to refactor profiles? For blockchain, they can’t remove things. But refactoring the way profiles are expressed in spec is possible.

AR: Could have deterministic exclude threads now and in the future we could refine it to have numeric-deterministic and no-threads and "deterministic" would become an alias for their composition.

RH: I propose we start with that, agree, and refactor that later. That would unblock both proposals. And unless anyone speaks up, I don’t think we have any disagreement.

DG: Refactoring portion of that appears to be a requirement to minimize number of profiles. +1 to that. Seems that it should be implied as a desideratum, to keep ecosystem unfragmented.

KW: I had a different category of question. When you're choosing the deterministic semantics, you could choose semantics that are favorable to one arch or another. What will the philosophy be for choosing the semantics?

AR: Same as picking instruction semantics. Use value judgments if you have to make a choice. We had to do that a lot in the SIMD proposal.

KW: Concretely when the relaxed SIMD determined, what did they do? Determine more Intel than ARM? Or more ARM than Intel? What did they do?

DG: Can answer: for 128-bit SIMD, it was a mix of both but leaning more towards ARM, because without direct instruction mappings you need to emulate with shuffles. On intel chips are fast enough that codegen can produce instructions that are fast enough. Goal was to avoid unintuitive performance cliffs.

JM: I guess surrounding this discussion. I would love if relaxed SIMD was excluded from the deterministic profile. I can’t imagine any use case where you would want deterministic relaxed SIMD semantics because you care about perf so much but the determinisim is also important. It would be like to know who wants deterministic floating point semantics and also require that they have the performance defined by the engine and not just implemented by things.

DG: Quick response, instructions from relaxed SIMD are quite niche and not general; if you don’t want vector insts and don’t want relaxed semantics, there are deterministic fallbacks for everything except FMA. Only thing that would explicitly disallow is relaxed multiply-add. Proposal addresses 40-50% performance probs in specific cases.

JM: Thanks that goes a long way to addressing concerns. If you pick the wrong semantics for your platform, are you going to be in position where you will reach the performance you want at all?

BT: As I recall, part of the point of having documented, deterministic relaxed SIMD semantics is to encourage future hardware to converge on the chosen semantics.

Dan G (chat): The ability to use the FMA instruction in the deterministic profile is valuable.

RH: If goal with profiles is to minimize fragmentation, deterministic profile still allows relaxed simd, syntactically, just with a canonical impl. Would be nice to have not so many modules floating around.

DG: Any other concerns? Thinking of poll for deterministic profile, that we know we may refine in future.

AR: That excludes threads.

DG: Actually we don’t specify that now: let’s address over time.

JM: Sounds like we still have discussion in this area. What exactly are we voting for? Are we voting that we discuss this more?

DG: Vote: deterministic profile, that excludes some subset of relaxed SIMD instructions that are already spec’d.

JM: Exact semantics we can discuss in the future. Not going to vote on the semantics today.

AR: I’m surprised that you switched to excluding relaxed SIMD

DG: Excludes just the behavior

AK: We do have specified relaxed SIMD behavior. No change there.

RH: Is the idea that whether the deterministic mode will or will not include relaxed SIMD instructions will be discussed later?

CW: How later is later for discussing? In future or later today when voting phase 4 for threads?

DG: Later today to address it, but we also said that later because we shouldn’t be blocking these phase 4 proposals because these profiles can be refactored.

Poll: Add a deterministic profile that determines the result of the relaxed SIMD instructions as specified, allowing room for future refactoring. We are explicitly not voting on the relation between the deterministic profile and threads.

SF F N A SA
12 18 11 0 0

DG: Going to do a relaxed SIMD phase 4 vote now.

Poll: Should we move relaxed SIMD to phase 4

SF F N A SA
18 9 15 0 0

CW: I only care about that I call a phase 4 vote for threads and someone said we can’t do this because we haven’t worked out the threads profile yet. If we can have the phase 4 vote without profiles, then that’s okay with me.

RH: Would you be OK with merging profiles first, then have threads disabled in deterministic profile, with the option for re-adding threads later to the deterministic profile?

CW: Fine with that story, I am taking it the phase 4 vote for threads will not be blocked.

DG: What would this look like in the spec, would you not have atomics?

CW: Thanks to TL’s intervention you would not have shared memory. A deterministic-profile host can never create a thread.

DG: Reasonable

AR: Minimal syntactic or semantic restrictions. Anyone who disagrees with that?

:If you just syntactically disallow the shared attribute on memories, then that's sufficient, right?

AR: Proposal is more minimal: you can write “shared” but you can never have more than one threads. Keeps profile semantic without syntactic restrictions.

BT: Guarantees that someone will introduce no-threads profile.

AR: That’s fine. We’re OK with refactoring

BT: Each profile spends something from mental budget.

AR: We want profiles for all major language extensions anyway. Corresponds to what platforms want.

DG: Ok thank you.

(applause)

Type Reflection for WebAssembly JavaScript API: Update, tentative poll for Phase 4

IR presents (TODO: slides)

AR: What was the interaction with typed function references?

IR: We can take function references so we can be more precise as regards function types.

RH: I don't know if we have consensus on the resolution for issue #13, which was about passing WebAssembly exported functions to WebAssembly.Function. Also, we shouldn't have invalid WebIDL in the spec. We should either extend WebIDL or discuss it in some other way, e.g. in ECMAScript terms.

IR: Valid point. Let’s focus on how we address issue #13, WebAssembly/js-types#13 Does anyone object to behavior?

AR: RH and I suggested that you unconditionally create a wrapper function, whether the function is exported or not. Simplest solution.

RH: I agree.

IR: OK. We can consider.

JM: Along those lines, motivation for this spec for me is that this is the most expressive way if you have JS to generate an entry thunk and pass to a module. Better than the alternative: creating a module, instantiating it, and passing value from that module. For issue #13 it does seem that it is something that we should resolve, going forward, if it has performance implications.

IR: Regarding WebIDL, I found that this is a difficult task. Perhaps we can find some workarounds.

TL: What does current spec say regarding Wasm GC values?

IR: externref. Only two reference types: funcref and externref.

AR: Did GC add anyref to JS reflection?

TL: I don’t recall us adding anything

RH: If you call type() on a function that’s a subtype of funcref. What happens in that case?

IR: funcref.

RH: Better to throw for a supertype. For the mocking example, you couldn’t mock a subtype.

AR: Agree, the type is inaccurate in that it’s not a supertype of what refined type would be returned in the future, so it could break programs that rely on this now. So we should just throw in cases where you can’t represent the type. Including for globals and tables.

IR: OK. This only affects the future funcref and GC proposals though

AR: we serialize the proposals, so unfortunately since funcrefs and GC are already in, then this proposal needs to handle that

IR: OK that’s fair :)

RH: Regarding WebIDL. No need to extend WebIDL itself, necessarily, we just need precision. typeof, prototype chains, that sort of thing needs to be defined.

IR: Ok, thank you for the feedback.

Exception Handling: Vote on proposal to re-introduce exnref

BT and HA present slides

PC: When you rethrow, do you specify the backtrace that should be displayed?

BT: Nothing about backtraces. No difference regarding the current proposal.

TL: Couple questions about syntax. Can you have multiple catch_all / catch_all_ref in the vector of catches?

HA: Yes, we generalized the design, there’s no restriction that catch_all happen at the end, or how many times it happens. It’s

TL: Right, not more useful than a restriction, but simpler to implement.

CW: After the first catch_all you won’t hit any of the subsequent catch_alls?

HA: Correct.

RH: Already the case you can have multiple catches for the same tag. Previous state was redundant also. Also this saves one byte for a single catch-all in the binary encoding, which is nice.

(HA continues to present binary encoding)

ID: What is the difference between rethrow_ref and throw_ref?

HA: Typo :) (edits slide to be throw_ref)

FM: Is there any implementation effort right now?

HA: Yes. VMs are currently in progress (SM, V8). Toolchain in progress.

BT: Also the spec interpreter.

(HA continues to present migration plan)

AC: Could you talk more about the plan for specifying the old design in addition to the new spec?

BT: Has been work on formalizing phase 3 spec. We would like to re-use that work. Whether it is in the actual spec document as an appendix or an external document, we don’t know. We would like to specify it to the level of rigor that makes engine implementers comfortable. Also we need the full test suite.

KW: Consensus that there will be a GC-less profile for exception handling. E.g. tag types can’t contain an exnref, limitation on size of exns. No conversions between exnref and externref. That would be a no-gc profile. But if we are on the same page…

CW: On board.

HA: That is a very reasonable exception. No exnref-inside-exnref, limitations on the number of parameters, etc.

CWoods: Tooling side, we are working on it in wamr, wouldn't want to support both. Want to avoid a situation where we switch, but then we have a WASI SDK that emits the old exception handling.

HA: No concrete timeline. Quick :) laughter I hope by EOY or hopefully sooner, for translator.

CWoods: libunwind for C++ in embedded space, should we take the hit now… when can we do C++ with exceptions in embedded code.

HA: You ask, is better to impl old or new?

CWoods: Trying to understand the timeline risk between now and EH in the embedded space. Probably in 2.5 months we’ll have something that works if we continue working on the existing EH. If we go with B’, then it’ll take longer, but we want to know what will be ready because people will ask me.

DS: Regarding libunwind, one virtue of this is that libunwind doesn’t need to change: interaction between toolchain and lib will be same. As soon as HA finishes translator, that will be enough. Toolchain on WASI side to package this up. Upstream already, HA did this a couple weeks ago.

SL: The EH proposal is at stage 3, doesn’t that mean that we should be allowed to changed the proposal since it hasn’t been standardized yet.

BT: Different opinions. My feelings arephase 3 is an implementation feedback phase and there is nothing in the spec process that says we can’t change the proposal, that’s why phase 4 requirements are 2 implementations. But the implementation reality we are in, due to a lot of reasons, long history, is a bit unusual.

HA: ACK. Not a fan of big changes. Has been a tumultuous history. But, we have lots of feedback, and the reasons are good. While writing formal spec and so on, encountered problems specifiying current proposal. Hinders certain compiler optimizations. Hard decision, let’s put it that way.

ZB: Back to timeline things, I tried to support. It would be nice to have specific metrics instead of "low enough" in terms of usage. What is foreseeable future. We don’t need specific dates but something relative would be helpful for producers. We would like both support in VMs in stable before starting to move to EH. We need time for our users to have both. If browsers release in a month, we usually deliver in 3 months, it could take time.

HA: Toolchains and VMs will support both versions for the foreseeable future, so there won't be pressure for other toolchain authors to switch quickly. The whole process is going to take time.

FM: Can you share? You said you had usage statistics the other day.

BT: 0.004% of page loads or something.

AK: There’s no number that’s low enough. The # is a feeling. Then you try to deprecate it and see who complains. Then you turn it back on. Used to use 0.002% in Chrome when you try to try, but we have things much lower than that that we failed to deprecate and things much higher than that we were able to deprecate. Not a guarantee.

BT: We have an advantage in that we are in compiler-land, it’s a toolchain process and there are fewer of those.

CW: The question of whether we can successfully deprecate thor not is a question of web reality. We’re not going to break websites, we are hoping to encourage you naturally using the new instructions if you are using Binaryen and optimizing.

FM: Given that we got into this mess by shipping in stage 3, are we going to avoid the problem by delaying shipping until phase 4?

ID: Who is going to write the formal spec for the new thing?

BT: What are you doing? :)

ID: I’m here, I’d love to. Who's going to pay us?

AR: should mostly be about throwing out stuff :)

LW: Regarding the earlier strategy for defining EH in a no-gc profile, is there an additional goal to not have to dynamically allocate + refcount the exnref payload?

BT: Partially motivated by wasm2c, which has an elegant solution for the current proposal. Reference counting would be significantly more complicated for them.

LW: Just going to inline the payload, whatever max size that is, pass that around

BT: Yep.

DG: Time check, 2 minutes left.

(ocamlopt dev): Performance specification in any way? O(1) vs O(n) in terms of how many frames you are throwing over?

BT: The question is definitely orthogonal to the design here, but there are issues that are multiple years old about that. We should discuss it, maybe post-MVP.

(ocamlopt dev): Do you want to squeeze out every possible byte?

BT: No, actually when we wrote this spec, we use whole bytes instead of just two bits.

Poll: Should we update the exception handling proposal to include a try_table control construct, throw_ref and the exnref Wasm type?

SF F N A SA
24 12 4 1 0

Initial work on a DSL for the specification document

SR presenting slides [TODO: SR to link slides]

TL: very cool, want to write less latex. Would be nice to have better spec-tests. Would it be possible to generate tests that don’t just find bugs, but look pretty and organized well and could be checked in.

SR: 100% pass rate in the current spec test. Next step is to find what kind of coverage metrics are useful and better sense of correctness.

FM: some work on specs that are an intersection of wasm and JS, suggestions how to improve that process. JS types that are very simple which go to and fro. JS API is not Wasm or JS but between them.

SR: we like those problems, branch of research for those problems. Interaction between DOM and JS, or embedded. In beginning when working on JS, it was difficult to find bugs. JS devs disagreed on what were bugs. Interested in interaction between wasm and JS. Until march of this year, we did not know about wasm. We’re now on top of wasm 2.0, working on SIMD now. Research on interaction, component-model, benchmark(?). During break will ask more questions.

??: on JS part of talk, found bugs in the spec. Was minor with variable name gone wrong. What else did you find?

SR: I think to me, helping spec editors to identify wrong sentences. May not be core issues in semantics, we only check four easy things. If we want to know more heavy semantics, we could do that too.We haven’t done that yet.

CW presenting slides [TODO: CW to link slides]

AR: Question about rebasing threads on top of GC, is it necessary, what there is to do?

CW: Main concern is that formal definitions will change, editorial problem

BT: Question about changing main branch to the branch with actual current spec ‘upstream-rebuild’

CW: Trying to be careful to not break something.

AR: Wast format also added syntax to pass shared module to another thread

CW: part of thread construct in my opinion

AR: anything we would want to change?

CW: no, nothing we would want to change, and even if someone wanted to change XYZ, we would have to say it’s not possible

??: I don’t understand how you test weak ordering when you don’t have parallel activities

CW: one thing we added to wast was the ability to have parallel activities. Not exhaustive, but non-deterministic.

??: follow up, they’re not executing as threads.

CW: in reference interpreter, they’re green threads, but engines can run them directly and see genuine behavior.

AR: You can have any interleaving of the small step semantics, using RNG.

CW: This does not expose all possible behaviors.

**Poll: Threads to Phase 4

SF F N A SA
37 7 2 0 0

(wild applause)

Post-MVP threads discussion (with phase 1 vote)

Conrad Watt and Andrew Brown presenting slides

AR: question, think there is a bug in the example, the table should have a shared funcref in it

AB: yes, just to know that the syntax is not fully worked out.

CW: table is shared, table can only contain shared things

AR: what does it mean for a function to be shared?

CW: in the web, it could be postMessage’ed and shared across threads

CW: cannot close over anything in JS

AR: shared function cannot reference a non-shared global

CW: When I say functions i mean function instances.

AR: function instances are closure in wasm, close over the module instance

AB: A key point is that function …

PC: do you expect subtyping on shared annotations

CW: definitely not, as web engines implement shared/non-shared in disjoint ways We had web engines implement shared accesses(?) with bounds checks and non-shared accesses with guard pages.

FM: Is this going to show up in the type signature of the function?

CW: yes

BT: are we going to have shared exnref

CW: in principle you can have shared any kind of reference.

Two philosophies, why bother sharing, 2nd if we ??

BT: what about catch_ref, is there a catch_shared_ref

CW: the only way you make a shared exnref is to have a shared only payload

CW: the easiest solution would be to not have shared exnref

TL: can you catch a non-shared exnref in a shared function?

CW: good question, need to think about it

JM: can you have a shared externref?

CW: no, that would be bad. We don’t want to allow JS values to be shared across threads

KW: can a shared function have non-shared parameters?

CW: perfect point, will discuss later

[AB resumes presenting slides]

AW: so no return values, join through memory, can a thread communicate a shared GC object, can a thread join with a shared GC object?

CW: So, no, with the bare bones version of this proposal no. You’d need shared structs, arrays to be able to be communicated across threads.

AW: are there atomic operations on tables? CW: there would be in this world

Resume presentation

DT: one of things noted in browser context is that hwCurrency isn’t the best metric to decide. M1/M2s have different types of threads. Scale in that way, you get performance regressions.

AB: I haven’t though much about that, we should follow up on this with a discussion group

FM: they are not virtualizable, you want to manage how many threads your child can spawn

AB: Are you saying an argument to make an instruction?

FM: rather an import

CW: you could view the threads an internal detail of the component, like other resources like memory

FM: seems controversial

LW: I agree with CW

AB: last slide

AK: on first slide, this proposal could improve main/worker thread inconsistencies. How would this proposal improve this? Atomics.wait on the main thread

AB: that was a hope, maybe more discussion is needed

CW: If you’re existing in a pure Wasm world you wouldn’t need to worry about going into JS (??)

Conrad presenting now

RT (online): What about spawning a function and passing it a non shared arg?

CW: Can be disallowed by validation

RH: what about function bind?

CW: creates a new function reference, could create shared result depending on params

FM: The reason that shared continuations cannot exist is work stealing. Situation of blocking a thread with a task that ??

RT: right now you’re using shared to refer to whether a shared function is going to access things of module instance that are shared. Resumption types could mark whether frame is shareable or not at suspension.

CW: interesting idea, in that scenario you can .., I’ll think about this idea

RH: It’s the whole stack that’s suspended, not just your local frame

??: isn’t the shared attribute too virus like? No way to ever access non-shared from shared

CW: yes, so i have some slides about this, we need to solve this.

[presentation continues]

AR: is thread.terminate a worker.close?

CW: yes

AR: then I agree with all your hot takes. And if we don’t have it as an instruction, what are we actually adding in this proposal?

FM: accessing JS, this is going to be important and ubiquitous. Will be calling an import on a thread

CW: on the web yes. I totally agree with you.

TL: Add a colour how it will work in emscripten. .. we spawn threads using a worker thread pool.

TL: TLS is not an issue, as globals are all thread_local because instance-per-thread. In a world where we want to move to everything shared in emscripten, we would need a brand new thing for TLS.

AB: fundamental thing that emscripten and wasi do is an instance-per-thread. Allows you to do TLS in that fashion

TL: proxying.. Emscripten sometimes sends work to another thread for it to be done. Call JS to another thread, wait on the result. However we try to do this as little as possible. So not every JS call import is proxied to another thread. Console.log will do no proxying whatsoever. Compute only thread would need to proxy. Infrastructure problem for emscripten to make that work, would be annoying. Probably won’t use this on the web.

CW: what about fast dlopen?

TL: shared tables would be nice…

CW: then you need shared functions

AB: quick followup to thomas, how do you decide which functions you need to proxy?

TL: it’s about whether they access any shared state in JS

AB: only emscripten functions that don’t access any state

TL: filesystem import needs to access state in JS held on the emscripten side. Users are allowed to do whatever they want in their function.

Yuri: Cheerp, same or worse, if cannot call JS from .., offscreen canvas

DT: lightweight threads can mean very different things in different contexts

CW: i was putting up lightweight in the hot takes.. Do I believe I can do 100 threads …? So are threads like hardware threads or are they more like lightweight threads.

EV: since you mentioned Java, Java originally had lightweight threads when CPUs were single core, then moved to OS threads, now back to lightweight threads. Might be possible in favor of not having native instruction, as they had a library approach to spawning threads. User code could only create them through API’s.

AR: Can you elaborate on how this depend on it being an import?

CW: Imagine having a program on web with 100 threads, migrated to use OS threads. Different namespace for different approaches.

AR: you can do that with multiple instructions. Having direct access to hw threads is not really meaningful in a wasm level/pov

ChW: in industrial, OS threads are important. We see benefit of both. Would there be a profile that would allow you to pick?

AR: The difference is not semantically observable. What are you optimizing for essentially in your engine?

CW: I don’t have a clear picture on how this fits in the wasm threads story, we need to think about this?

ChrisW: the real reason for the hardware threading is HW backed timing and scheduling in the hardware.

CW: I can imagine a world where this is an extra import.

ChrisW: Code complexity, just want to pick one.

CW good point

KW: I could imagine a world where separating determinism from threads is valuable. Threads could be useful without any shared state, by using an actor model or other algorithm.

CW: not sure if there is value in having this in the wasm type system

KW: E.g. if the runtime uses the deterministic profile, it will probably need to enforce determinism at verification time.

MB: I like that model with like erlang actor models. Concern: at wasm level do you need to know if these map to the hardware level?

CW: in wasm spec, it would say nothing. But as a community we should try to document the cost model.

MB: in favor of decoupling threads from OS thread. Also we should carefully consider thread.id

RT: trying to figure out JS interop. It seems like only way to make model work is with a new web worker that calls into shared module instance.

CW: right that if your thread needs JS context then you need a worker. But sometimes you need compute only, or very rare JS access.

[presentation resumes]

TL: is this any harder than native TLS?

CW: it’s the worst case of native TLS, which some people do attempt. Affects everything on the web. Shared worker for just JS needs to handle this as it could access wasm sometime.

TL: if app has one worker that are spawning instances. If separate part of app has a worker with a separate module, then that would force TLS init?

CW: that’s my understanding

AK: did you take with Shu about this? (CW: yes) He is working on a form of TLS for JS for thread local methods. Is attached to each object

CW: can you arbitrarily create new objects with this?

AK: unsure, this is new in the last month or two, talk to him

BT: expectation of cost model, if it’s constant time with single or couple indirection, or if it’s slow hash table lookup

AW: why not push this off to the toolchain?

CW: (shows slide that will show up next)

AW: there could be many of these threads, with many allocation needs, why not allocate a TLS storage for all these threads at their root and pass that to the threads as a param?

[presentation resumes]

AW: why not have toolchains pass the TLS as the first parameter to each function?

CW: need to think about this

RT: this won’t be able to support thread local methods

CW: won’t support any GC things until support is added

RT: set up web worker with it’s own JS context, call into shared code, no way to access thread local references

CW: We’ll do the JS context after this. To some extend this is an orthogonal problem. There is some interaction but you need a separate solution.

PC: you could push that a bit further in the toolchain and expect that TLS is just the first argument

CW: would that work for toolchains? Give each function a parameter that is the TLS’s index into linear memory

TL: we try to avoid any kind of global transformations, but it could be do-able. At link time we could determine it’s a multi-threaded program, then transform it. C library doesn’t know it’s in threaded code until link time. Wouldn’t want to change

AC: example of TLS variable is shadow stack pointer. Shared continuations need new shadow stack pointer when moved.

CW: that is a compilation scheme problem.

RT: can I spec out a thread local thing that’s two instructions? tls.set $tag will update hashmap of TLS, tls.get can get the value

AR: instead of passing everything down, you’re really looking up your dynamic context, it's an example of an effect handler

RH: So it’s a hash map with a thread id and a pointer to a TLS?

…back and forth with hash map and TLS ideas…

TL: we need to support TLS for shared GC programs. Earlier we said that hottake assuming there will be shared continuations, seems like we’ll need some form of builtin TLS thing. Unhappy if we had to couple shared wasm GC to builtin TLS thing.

CW: even in a world where we ..

TL: I think we need two level of shared functions, if just one level and it’s strict, then cannot do the

RT: possibly two different problems here

BT: weakptr in a TLS hashmap could be difficult, we should be careful here

CW:.... Let’s see the JS solution in slides later, does not use hash map ….

[presentation resumes]

AR: Are these going to be atomic so the threads will lock?

CW: yes but those threads will be active (?) one at a time …. (?)

AK: maybe the more important thing is having an event loop in a web worker?

… discussion over the JS interaction mechanism …

AW: what about Math.sine? Engines specialize code to well-known builtins

LW: Math.sine could be shareable

BT: functionally equivalent is a wasm shared function that can be bound to multiple thread’s local function and will dispatch

AR: all these calls are multiplexed to the original thread?

CW: no

CW: this is specifically for a world where you’re creating a JS context on each thread

Confusion about the semantics of the blessed callback

SYG: original sin is that JS cannot share code, everything in JS is a closure deep down (including global). Solution we’re thinking on JS side is that there is the same code on all threads. Set of syscalls is actually the same, give special tls view to all the different syscalls.

LW: Why this makes sense, and thread.spawn, wasm is coupled to the JS it’s going to call. Other scenarios where wasm wants to make just do compute, thread.spawn makes sense.

TL: I’d be interested in more eagerly than not splitting out the shared everything from thread.spawn.

Discussion about proposal name and splitting it.

Name TBD

Closure (Day 1)

Proposals & Discussions (Day 2)

Component Model / WASI status update and next steps (Preview 2) (Luke Wagner)

LW presenting slides

TL: This is a lot of infrastructure to get feedback. The culmination of all this is a stage 2 proposal. We expect even more feedback at that point and maybe changes. For smaller proposals, its very lightweight to change in phase 2 or 3. Especially in phase 2 there's not much need for backward compatibility. You have a lot more of that here. How do you expect feedback to be incorporated in phase 2 or 3?

LW: Good point. What color do we paint bikeshed? Not the great time. Two years from now. That sort of commentary. The best time to get involved is now. Type of feedback is that this is fundamentally a problem, one thing we do is make sure to make browsers compatible by polyfill. Tricky thing is to advance to phase 2 is that you need a feature set and we don’t have it unless we change the process. If you are interested, now is the time to get involved.

FM: there’s another aspect worth thinking about: this looks a lot like the Java standardization process. Also about the same size

LW: it’s a lot less!

FM: What is it you want the CG to standardize? Just the component model or also the interfaces?

LW: WASI opens new questions. More nuanced what standardization means.

DG: Thanks for laying out the plan. Also curious how you're thinking about developers targeting the previews, 1.0. What kind of compatibility do you expect, or how do you expect apps to migrate?

LW: Idea is once we hit preview 2, toolchain defaults to emitting preview 2 binaries but not later versions. We keep this binary working by automatic transformation going on. We keep the preview 2 binaries working until the next version.

BT: how are you thinking about determining what APIs are in scope for WASI and what’s out?

LW: That gets back to the standardization thing. No limit on standard interface. We don’t think about user agents. It’s potentially a much bigger scope than just the web, so it’s a longer running conversion than the component model part.

LW: (presenting preview 2: what’s covered?)

RH: Maybe a dumb question. You said about modularizing interfaces. One language has a standard library, where everything is available. Files system? ??

LW: There's some subtle developer experience issues. Lots of assume FS and some hosts don't have. There are ways to virtualize, wasi-virt. How exactly this gets implemented is in progress. There are descriptions that say what world I want to target, and if an interface is missing from the world, it can be virtualized. Moving to open standards helps here. In some places upstream maintainers might not be interested in contributions for just a company, but if we have standardized interfaces, which might make it easier to contribute support for those. There’s still a lot of code that doesn’ know what world it targets, so the challenge is how to manage that.

XW: We agreed to explore the co-module interface from a weak file. ??

LW: Yes. for background, for existing core wasm tools you can take wit interface and derive which core wasm it can call according to the canonical ABI. so we need a tool that can do that. The exact form of what a toolchain wants varies, so we haven’t built exactly that, but hope that whoever needs this concretely, we can work with them to see what exactly they need, and we can help them build that.

XW: Yeah I think in previous discussions there were some users who didn’t need a component model. They need to use some basic part of the WASI interface like clock / file IO, so we need to support to ??? their product development. Before we look at the current interface definition there are two ??? some key values, some instandHiardication some middleware what we think about really low level things that need standardize comodule interface?

LW: I think potentially all of these you want the core interface, for low level or higher. It’s always core wasm calling imports defined by the canonical ABI, so hopefully whatever we build applies to all of those. We probably haven’t built exactly what you want yet but we can work with you to help you build what you need and reuse what’s available.

XW: Thank you.

RH: Canonical ABIs. In the roadmap, are full adapting functions in lowering ??

LW: those are very much in the post-1.0. The big thing we don’t have yet is some sort of native async that’s composable?

RH: What do you think will motivate you in the future?

LW: that people are using it and we have profile info, e.g. which copies need to be eliminated RH: What sort of things happen to immediate copies be avoided

LW: Let’s say you’re passing a JS array of strings. We have a pretty good solution for an array of bytes, but if you e.g. have a rope, you'll have to flatten before copy. Hypothetically an adapter could traverse the rope because it could be arbitrary code. Just an example. If you have compound data types, you might not have to copy the leaves but the interior nodes you may very well have to make intermediate copies. Most interfaces don’t have big complex types, so we’re waiting to see when it’s a top priority to optimize that kind of thing

RH: Makes sense.

LW: (presenting, implementation status)

KW: What does the future hold for WASI libc?

LW: currently works using the preview1 to 2 adapter. Work coming soon to make it workF directly with preview 2. Definitely the goal is to keep it a common maintained thing that people use. Especially for the low level parts, stdio, etc

BT: The principal thing is, Java is so big so one JVM implements all of it. ??

LW: There's a lot of stuff: one thing is that the interface translates to modularity of the host code that implements it. It’s now more possible to have separate crates that implement the interface, they could share wasi implementations. Most of the work is on core wasm, mostly what you do with a component is fuse into core wasm. That fusion step could be reused. Otherwise, having multiple runtime implementations are in progress. Wasm edge is the most public but i think there are others in progress, there will be more native implementations coming soo,. Much smaller than Java overall.

TS: Project can’t find this moment but there's project that basically that all targeting native runtimes and that might require multi memory and compiles down to native down or core wasm that support right feature sets to execute and separate from what we’re doing in thesis projects

LW: Another important part is that modularity means that it’s not all or nothing. Some small hosts will just implement a subset of wasi interfaces. It makes it need less code to implement a wasm environment. With Java 9 they did a big modules project to try to fix the problem that you need to implement so much. So we’re trying to get that sooner.

LW: (presenting, what’s next)

FM: Can you give an idea on how many people are working on wasi interfaces?

LW: just wasi interfaces? Sort of amorphous, some people are working on related stuff but not wasi exactly. But in total, in CM, WASI and related stuff, maybe 40 in some capacity, maybe 10 intensely.

AC: Let’s say dozens.

FM: Very impressive, by the way.

LW: (presenting, open questions regarding standardization)

AK: IO vs not IO. agree component model should stay. this is assumed future thing, how cross language interact? That's not in scope, that’s component model thing. component model is close inought to core wasm thing.

LW: I totally agree. CM is definitely fully in scope and should stay in the CG

DG: For precedent, speccing WASI, maybe other groups, ??

LW: yeah i’ve started talking to some of the W3C liaisons, and further back into the W3C. a lot of it is still too speculative to push hard on yet

DG: Curious about what your ideal of organization is this. There is precedent for this kind of system standardization.

LW: I like the idea of keeping it closely associated with wasm, it puts it in a good context, as opposed to make some wholly separate thing to standardize interfaces. We'd have lots of random people with random requirements show up. Keeping it close to wasm seems good. But some of these will never be implemented natively by the browser. But teh 2 web VM thing makes a lot of sense for core wasm. So fi we change the process, maybe we have different criteria for phase advancement for some kinds of things.

TS: To me another weird aspect is where the expertise is? In CG / WG we have this funny setup where CG is doing standard. I have a hard time seeing how we would apply that one level further down. Expertise in deep design is involved in WASI subgroup and actual subgroup process, let’s bring it to the CG. Expectation would be significant part of people wouldn’t be involved in what it means to design and specify APIs. It’s just rubberstampting exercise. Maybe having them as siblings, more close, instead of this scoped relationship right now.

LW: one other relevant thing is that some of these interfaces are coupled to another standard. HTTP is closely tied to that standard and not trying to do anything new. So we aren’t defining things out of nothing like wasm itself, but other interfaces are very different.

RH: How many wasi apis will be natively implemented in the browsers? 0%? 50%?

LW: I assumed zero for a long time because the polyfill should work really well, the JS can just call web APIs. but maybe sometime we’ll say it's dumb to have a bunch of layers of polyfill just to call JS APIs, but maybe it will be driven by seeing lots of layers and performance problems, that could maybe motivate something like that. Maybe some of them could make sense motivated that way.

RH: Just on the expertise thing. A lot of web browsers expertise here. separate wasi group. But all those are expected to be polyfills, and browsers don’t have a lot of engagement there. It’s fine if we don’t expect them to be implemented natively, that’s fine, but otherwise…

LW: One thing that helps mitigate is that in the web we want versionless, about WASI can have versions and breaking changes. If we change things to make them more browser friendly we could just have a new major version.

DG: We are now way over time, lets continue the discussion in future CG meetings.

Wasm for Embedded Systems (Chris Woods)

CW presenting slides [TODO: CW to add a link to slides]

CW: What is the market share of industrial IoT?

CWatt: 1.4 trillion.

CW: software cost is big, but amortized over a lot of devices. So it’s often better to spend more on software and cheaper devices. It can result in SW being asked to solve hard questions, sometimes without good resources or good hardware.

CW: (presenting the appeal of webassembly for industrial iot) Lots of use cases for intelligence in these devices, but embedded C is a barrier. But the devices are very constrained. And they are often components embedded in bigger products, e.g. industrial machines, so a lot of our stuff is about system integration, software integration, hosting 3rd party code, so the extra isolation of wasm is important. It's like in a datacenter (CPU contention e.g.) but the result is worse with e.g. a milling machine than if a service crashes and can just be restarted.

TL: I have a question. Do you have an idea of whether it is a limitation of wasm itself in hardware, or is it the runtime issue; i.e., existing runtimes aren’t thinking about the issue.

CW: We haven't thought about that specifically. The solutions in that space use custom silicon and custom OS

TL: It would be hard to match.

CW: if you mention the word “real-time” you can argue about that for half an hour, there are subtleties about what it means. It would be a large engineering effort to get wasm in there. Generally the standardization is important for us because our products last decades sometimes. And often do important things. E.g. the train and ticket system, building controls here probably use Siemens HW and/or SW. but as the memory footprint increases (or clock speed, cores etc). But as computation increases we move away from the sweet spot. We want to host multiple applications on the hardware. On a bigger system you can run containers in Linux and maybe don’t need wasm. But there are a lot of variables that affect whether it makes sense to do it.

KW: Thanks for the matrix. About the bottom row of the matrix. In the world of offline VMs, it’s possible to make runtime essentially zero space, e.g. by rejecting all memory/table.grow requests and having no allocator. So I think the bottom row is within reach of some of today’s implementations.

CW: would be interesting to explore.

AR: Same remark. What makes wasm runtimes so large? if you have suitable profiles, it’d be possible to make zero size runtimes.

CW: that data point came from experiments with the smallest hardware we could get and WAMR. but it sounds interesting.

BT: Do people still care about 8 and 16 bit processors in this space?

CW: no. we using 32 or 64 pretty much everywhere

CW: presenting about the “sweet spot” where wasm is most applicable

FM: what about other aspects such as security running oem software or update over the air software?

CW: It’s a compromise. You can’t have everything. It’s about getting the right balance where it fits. When doing integration with OEMs, do we open it up for more people to write software for these. So that's where security comes in and we get into a situation more like others using the component model. The EU is introducing new legislation about cyber resiliency. Looking at the fact that people sell devices and never security updates for them. They are considering mandating supporting IoT devices for their lifetime. It might include keeping them patched and secure. That conversation is still going on about that. What does it mean for using OSS, but still actively discussing. NIST in the US is also thinking about this. Relevant to the healthcare industry and others.

CW: (presenting: Integration: industrial IoT technical challenges)

XW: Thank you for inviting me. Currently how to support zero copy data sharing across modules, in an ability often used in like a sensor processing flow in some interoperability? We have such a requirement and Sony wants such capability and more. We’ve done some more study on that. Currency available standard proposal. Memory control looks most close to this requirement. It seems it has not been updated for two years. I actually just found it in the list of topics today and I’m happy to see that. We figure out few options before we want to support. The first one is to host global memory and access it through a runtime api. Very significant overhead. GC. global heap object. we can’t do(?) that. especially for embedded env, gc will increase footprint and performance overhead. C/C++ can’t generate GC. we look other tool for options this ones use global memory reference and so ref can be passed through modules that we need to introduce some opcodes for data exchange between memory ref and ?? stack. true for standard process. also we may use second linear memory for sharing between modules we need to be able to pass the data address. that can be shared across modules. address can be presented with a memory index + offset. And we can

TT: merging memory: would the multi memory proposal we discussed yesterday be a way to use that?

XW: I didn’t joint meeting today so I didn’t know

TT: We voted for the multi-memory proposal.

XW: We need additional things on top of the multi memory. Memory index is hard-coded in the opcode. If we want to share data addresses across modules we need to pass the address in memory index and offset. For shared memory space, we will require a unified index space. E.g. 100~200 can be shared in all modules. something like that. That means we still need some additional work on top of that.

TL: Question about the requirement. Igalia folks have done work in LLVM / Clang to add C/C++ extensions for tables. In C code you can declare or import tables and write C/C++ code for table.get/set. This exactly the same strategy as in LLVM and clang can be used to support declaring import/export in second memories. We have Clang builtins that lower to additional memories and instructions. The weird part is it wouldn’t be normal pointers; they are builtin functions to do load/stores and memcpy to other memories. Is it sufficient for you or do you need DMA regions?

XW: that could certainly help with the problem. We could have code to use that kind of capability directly

TL: yeah happy to talk more offline

XW: we just figure out runtime workload

CW: thanks, that's a good indication of the directions we’re thinking about

CWatt: You mentioned that Siemens acquired a company just to keep the toolchain running. Could Siemens resource more of this work?

BT: Could you buy Google?

CW: good question on what's the resourcing available. We talked with other industrial IOT companies. Discussed that we’re in similar situations where wasm looks very attractive. But we seem to be still on the fence in pre-production, i.e. no products shipping yet. So our contributions are still limited. Individually we’d love to be more involved but resources are still a bit limited this year. Working internally to get more commitment and hopefully we can step it up in the future.

TT: We are evaluating as of now. Some critical points. What can wecan dig differently? Wrap up our contribution? Versioning? Compatibility? What should that evolve to? Trying to find out whether we can contribute. We welcome the community. We have potentially trillions of market size. What can you make business out of open source? All has to be very settled. Every action that might undermine determinism and execution performance is a concern e.g., relaxed SIMD is interesting, we really need a profile. If you have a machine that has a problem then you produce waste and no one will buy the machine. We are watching it closely and trying to make the community aware of what it means when it changes drastically in ways not useful to our use case.

BT: Did you succeed in running wasm in the real time operating systems?

TT: Yes

Wasm compilation hints (Emanuel Ziegler)

EZ presenting slides

Urgency: which functions are needed first? Hotness: which tier is most appropriate: we don’t have to wait to tier up Functions executed in groups: could tier them up together or split modules

CW: How much could you already win by collecting info the first time you see a program in the cache?

EZ: That's an option, we are looking at that. E.g. with eager compilation we stored that in the cache. The problem is that on the web you don’t have as many hits as you want. There are updates, or evictions. In theory it works well, and if you use a site regularly it works but often it looks like the first execution.

CW: Great, thank you.

EZ: (presenting)

CB: (presenting: Prototype implementation in V8)

BT: So that doesn’t include cross compilation?

CB: It does. Eager compilation takes time, but this was executed on a workstation with lots of cores and compiled in parallel. Lazy compilation only happens on the main thread.

CW: One of the motivations to move to lazy compilation is to collect type info in GC-heavy programs. Is this using wasm GC?

CB: This is only linear memory. Next benchmark on

CW: For wasm mvp, it would make sense to do no lazy compilation

CB: it depends on how many functions are needed too. If we need all or most of them, then compiling eagerly makes more sense, but if not, then lazy compilation is better. In this case we use about ⅓ of functions

CW: For start up with lazy liftoff + PGO is slow because process PGO compilation?

CB: this includes compilation. So the startup in default config doesn’t compile anything

CW: PGO have some hints to compile

CB: so we’re already compiling some functions with liftoff and some with turbofan. So it's slower than always using liftoff

CW: That is 0.000….

CW: Have you measured the overhead of purely processing PGO annotations?

CB: no, but the processing is very simple, just a few bits per function

CW: Naively the same format with branch hinting. It might be hard to keep track of byte offsets.

CB: Currently it's really just the most basic format I could think of. It’s just because it’s a prototype

CW: I’m interested in different formats for PGO affecting processing speeds.

CB: probably but I’d assume that the format wouldn’t make a huge difference. But yeah we should make a format that’s cheap to process

EZ: (presenting: next steps)

RH: SpiderMonkey would be interested in this. Especially speculating inlining about potential call targets. Should you even try profiling that? it’s unpredictable, in which case it is maybe a waste of time. In that case ???

EZ: yeah we can figure out details about what makes sense. We maybe don’t want all this info, but it still could be useful. And not every engine has to value all the hints, but it’s more value to the producers if thye know that someone would be interested.

KW: On the producer side we want to have something like this. We need more kinds of hints. This part of code would be run only once

YI: One more kind of producer: just in time compiler at runtimes. I’d really like this info to have a real use case . x86 dynamic calculus modules. (we did notice the switch to lazy compilation, it was bad for us!) We are using undocumented compilation hints in v8 already . for us for example try to tune our engine to work well with v8 but not the case for other engines. standard way of saying intent we have all the info. loop, branch. We know what branch is hot. We’d love to be able to say that and we are very interested. possibly a way to help benchmarking. We have a tool that works that is easy to integrate with rototype.

BT: cool work. What's the stability of these hints? you want the format to encapsulate facts. not selecting the tier because it changes over time. ??

EZ: yeah and also not just “is this hot or not” but how hot is it, you might draw the line in different places depending on resources

JM: I was similarly concerned about that; how stable this is. If we collect profiles in Chrome and run in Firefox, how stable is that over time? But overall this is very exciting.

KW: One particular helpful hint might go on memories re: how to bounds-check and how hot it is. Should bounce check explicitly? Or MMU strategy? Should store base address in a register? We have to choose or guess somehow, hints would be nice.

RH: PGO collection, desirable to info output from one collector is not heavily biased towards what it consumes. Objective criteria of cold/medium/hot. Engines have different senses of what’s hot.

EZ: it sounds like there’s interest based on the feedback from the room. So I guess the next step is to create a repo, explainer, and continue the discussion.

RH: What’s unclear is, is this a different format from the code annotation or branch hints, or is this compatible? Is this going to be another proposal?

EZ: Good question.

RH: I haven’t followed the proposals that closely.

CW: We tried to make branch hinting format a standard. I’m interested if that format can be used.

EZ: yeah that was a question about whether we should have one section that covers it all, or separate sections for each kind of hint.

DG: We are at time. Agreed on the next steps to take it forward

Update on JS String Builtins (Ryan Hunt)

RH presenting slides PC: what does it mean for this to be polyfillable

RH: in this example the compile-time parts you can import as builtins. If you want to replace it with a polyfill you could replace it with an instance-time import with the implementation. So it is polyfillable

PC: It should set a function instead of builtin?

RH: if you want to compile-time import a JS function you’d get a link error. So you could fix it by moving from a compile-time import to an instance-time import

IR: you can just use source based imports

RH: ill talk about that on a later slide

TL: Compile time import thing only affects web engines. Do we not add any notion of compile time imports in the spec?

RH: I believe it could be layered in the JS APi spec. It might be a small thing that compile-time imports are eager.. The core spec might need to know e.g. how do I type check some imports but not all of them

TL: Semantically you can pretend your compile time imports ??

RH: yeah in the JS API you could take those imports and associate them with the module

CW: It is formalizable in terms of pre-imports. Might not be exposed to the user but could be internally. This is not a general concept; this is special. way to formalize it.

BT: You're importing the whole module and methods in it. Could you import individual functions one by one?

RH: in this case it’s just equals, it could be individual methods

RH: you could use a nested object, there could be other ways to show it in JS

RH: (presenting)

RH: A would get evaluated first, then you defer compilation of B, and then when you provide the instance for C you would do the specialization

CW: The point is, without some way to defer compilation, try to compile a b c before even ??

RH: If you don’t defer the compilation in the ESM pipeline until A has developed its exports then you can’t assume what kind of export it is, builtin or JS.

CW: With the natural model of Esm, you done compilation before ????

RH: yes. Not sure about all the details but I think so. It is in the realm of implementation technique

AK: see integration as in the future. And compile-time imports are nearer, but I don’t think this works. ??. after compilation of the whole module graph. how you find out what the values are.

RH: agree that these are further out but trying not to paint ourselves into a corner especially if this is easy.

AK: Given my experience, I’d be surprised if this works. The evaluation happens way later. Anything else you have to evaluate to find out what the ??? are.

RH: The evaluation is for sure the last stage. I’m thinking not of semantic compilation step but machine code. So if A is guaranteed to be evaluated before B, you can defer the actual compilation

AK: how would you be guaranteed that the evaluation order depends on ?? hard to get the guarantee.

RH: Cycles do make it harder

AK: Yeah, we agree there’s lots of dragons here.

CW: My concern is that this means the compilation mode of ESM integration is not as flexible as Wasm compilation. It is a weird mismatch.

RH: I would agree that's the root of the problem, ESM has very specific ways that the process works, and some ideas don’t fit well. What to do about that is an open question.

RH: (presenting source-phase imports)

TL: This is a JS side reserved namespace. In wasm we need to import the correct namespace, so we use the correct name in your wasm imports. but you can also use the same name without using this mechanism. This is carving out some preserved namespace that can't be used for anything else. Is ther no web compatibility issue?

RH: That's the hope. In the JS API today it’s not reserved, so it would be a breaking change. So that's’ the idea behind opting in, and you could allow polyfilling. ESM is newer so we could say we always have that

CW: maybe even the host provides two different kinds of js string and js string fast ????

RH: would that be a different name?

CW: you can imagine on js side two reserved set of module names

RH: so in this example when you do compile you would have 2 different names, but it's the same on the wasm side

CW: you choose on js side which one you want to give. Going back to the previous concern, previously we talked about strings. I want to choose strings depending on time complexity and this would be the mechanism to allow it. Not that I want to do that.

RH: I don’t think this prevents that. The philosophical thing is trying to provide them as they are to the wasm app as they are in the browser

AK: About polyfilling. I agree this is a straightforward way to do that, except the performance. It totally punts the idea of polyfilling can be fast. We are importing functions somewhere.

RH: One thing to understand is what's the use case for polyfilling on the web. My understanding is that the use case is I want to run outside the browser that doesn't have these. So in those cases you could do something in the toolchain.

AK: I want to broaden the discussion back to stringref. One objection to stringref was “I don’t want to do that. I can provide that in the toolchain.” ??? Very close to implementing stringref everywhere.

RH: Whether we go builtin modules or compile time imports, they have the same issue. With polyfilling outside the web it depends on the amount of effort you want to provide, how much you value your off web port. If you care most about the web, you could use a naive polyfill outside the web browser. But as you go up in effort you'd want to just emit inline wasm code that does the operations rather than use the JS string interface. So you’d have 2 modes, one with native wasm GC and one using the web interface.

TL: I could imagine a world where the toolchain is emitting two modules: Main module + imports for js string and namespace. Only module you use. another module that particular lang impl + string behind js interface. They ship both modules. at some point in the engine they ?? together.

RH: That seems a valid implementation. What I'm trying to get at is that the JS string interface isn’t trying to be the one everyone uses on all platforms. It's possible but if you're going outside the web you'll want to recompile anyway, and also being able to use your own GC string is going to be better than trying to use the JS string interface

CW: use your own GC string: you talk about other non-web builtins?

RH: If you wanted utf8 strings, you'd just use array of i8 inline in your own code just like other language primitives

CW: I feel if that’s a good solution, wouldn't it be less pressure on the web, ??

RH: The boundary problem is the big thing, when your language has similar strings to browsers and you want to use web APIs there is a significant cost to the difference. Outside the web using GC strings seems more feasible

AW: It might be useful to continue discussion on lowering of stringrefs. It might be useful to have examples.

RH: The key thing I wanted was to talk about the builtin modules approach instead of compile time imports, that's been the most controversial thing. So making progress there seems like something we want to decide

CW: I see this approach as very sensible. I’m happy to see it.

AK: I’d like to get the temperature of the room about the idea, making up names of modules ??? I want to see if anybody thinks this is weird. I’m trying to get some feedback in case it raises alarm bells.

RH: as mentioned, web APIs are heavily guarded so maybe there will be something from outside this group. But the thing that makes this sensible is that we focus on just the adaptation problem between the wasm API and how JS would consume it. So there are questions about how to name it but I hope that this mostly lives in toolchains where people won’t have too many naming concerns

JM: I’m super curious and I don’t know the answer. Do we have the actual ability to standardize that? Can our group do that or do we have to defer it to TC39?

RH: I think for ESM integration, that one does live in both worlds, so you have a decision of, can you do an import of @wasm from a JS module, in that case you're doing amore general form of builtin modules which TC39 has discussed and not agreed on. You can also maybe only allow these imports in wasm modules, and we have more direct control over that. It’s reasonable to scope this to just JS primitives, ie things that don’t provide capabilities

TS: I think I am skeptical of the future of where toolchains compile different things to different targets and in reality this is more likely to mean that outside web hosts will eventually feel intense pressure to implement js strings. I don’t really have a better alternative

TS: Wasm strings are not a better alternative. I think it might just be ok? JS strings are not the most amazing string ever invented. But it’s not the end of the world. I think it’s nice ???

RH: there’s at least a chance we could avoid it by telling toolchains to implement the string type you want off the web. If you go with the webassembly string upfront, you're committed to that

TL: as a counterpoint, for c/c++/rust we have separate triples. Emscripten/WASI triples. So there is precedent for having two different compilations for two different targets.

TS: nobody likes that.

AR: there’s a reason why the stringref proposal is problematic, it doesn’t meet the requirements of all languages so they wouldn’t have the option to use it. So this is similar, if JS strings don’t meet those requirements either, they also couldn’t use this. So that also lowers the risk of everyone depending on JS strings

TS: Now we risk having multiple strings that people have to implement. The web has a lot of weight and smaller ecosystems can get pulled along. I’m not saying that's necessarily teh worst outcome but I do think I just want to say I think it is unrealistic to expect ?? outcome.

CW: from the iot point of view, zero interest in strings.

JK: Iot would use no GC at all, which includes no managed strings

KW: Would make the point that this seems nice in the sense that even if every wasm module wants to import this. When we say everyone has to implement, it makes a big difference between every runtime and every host. A webassembly runtime has to implement the semantics of wasm, e.g. memory.grow. But a runtime can say that there will be imports of what the spec calls hostcode, and it's not the same as the runtime. Even if every host e.g. wasi has to implement, that’s still better than if it's every runtime.

CW: if I want to set up a cloud computing company that runs wasm, grab wasmtime, c-embedded library ??

AK: yeah ideally it's wasm2c plus the embedded library but either way it's better as a library

BT: ??

RH: ok to bring this up. This was voted and discussed before that this was the direction that the CG was interested in going. stringref vs imported. If people are interested in reopening that, that’s fine with me. But I don’t want to spend the cg time on that. Any objections to switching from compile time imports to the builtin modules model

Spritely's use of GC as a target for Scheme compilation (Andy Wingo)

AW presenting slides

TL: when wasm-opt runs on binaries it will removes the non-nullable bit

RH: I see string-ref. Is that a Guile thing?

AW: yes scheme standard

RH: You said strings are mutable too?

AW: yes, except for literals, but there's no predicate to know. We have a subtype of string, mutable string, then you can ref.test it. Same fields but different type. You can just subtype string, and use the same fields. It’s less about proving things and more about representation

CW: if the string is mutable, ??

AW: the string type is a readable string type, and the mutable one is a read/write string type.

CW: read-write string type has additional string field

AR: Conrad is asking how to distinguish them. you can’t make one subtype of the other without adding any field.

AW: ???? I am willing to do this to my users

AR: this is a good example for why stringref doesn’t generalize well

AW: I disagree with you but we’ll get to that later

On stringref:

TL: Why isn’t it fast? Just function calls?

AW: yeah there's a call per codepoint

TL: I’m referring to calls that go to other wasm modules that don't talk directly to each other. They go through JS

AW: this is a host provided function, we don’t compile directly to the web

TL: when you’re running on the web these functions exist so you can’t optimize them ahead of time

AW: ???

RT: an issue is that hosts cant polyfill stringref using wasm. So what you're doing here is essentially what you'd expect the host to do in wasm. But hosts wouldn’t be able to do that because the downcasting behavior for stringref can't clash with other ref types

AW: Not sure I understand the downcasting point

RT: take the types you implement for stringref. For the proposal when you downcast a stringref you have to make sure it’s distinct from all other types. So if someone casts toa struct of stringref, and someone else casts to a struct of array_i8 then if there's another array of i8 they would be the same.

AW: That’s why we perform this transaction. We’re willing to make those tradeoffs.

RT: just wanted to point out that its a problem that wasm hosts can’t polyfill stringref

AW: I think Wasm hosts should emit stringref. But I don’t want to argue about that now, I'll just mention few more things

AW: (presenting)

SL: you use delimited continuations, for what?

AW: primitive for EH and green threads. They are exposed to the users of the Guile language. Some people could use coroutines.

SL: primarily. They’re not using them in their full generality

AW: mostly they use the fibers library

SL: Do you compile exceptions to exceptions?

AW: No, we are compiling EH to continuations. Currently exceptions don’t compose with delimited control. It would limit stack switching. We would have a couple others, e.g., ability to swap out a whole set of parameters.

CW: i brought up yesterday the idea of shared continuations, where you suspend on one thread and resume on another

AW: By default we are stealing green threads, scheduler. We could be one thread only and that's useful for many cases.

CW: But it would be desirable to facilitate that.

AW: yes

BT: How does performance compare to native?

AW: We can make it work. Calls are more expensive. Loops are faster than native. Loops are faster because CPS can keep loops. Calls are pessimization. 4x slower or so.

AW: Also, THANK YOU WASM GROUP! it's awesome that all the extensions we needed landed right when they did :) felt like a risky bet depending on that at the start of the Hoot project and we are SO GRATEFUL that GC, tail calls, etc all landed

WebAssembly Benchmarking Task Force

BT presenting slides

DG: jetstream benchmarks?

BT: those are mainly microbenchmarks

BT: (presenting)

DG: this fits in the framework of a subgroup - charter, deliverables etc

RH: speedometer 3? benchmarking has pitfalls - Mozilla position is there needs to be consensus on measuring real-world performance - non-representative things get removed - please do this - Spidermonkey sees 5 year old Wasm binaries all the time - not great - living process is a big deal

MB : As a researcher I would like to be involved in the process

RH: speedometer 3 relevant

BT: Is there much wasm connection in speedometer 3?

RH: not much right now - no bandwidth. If the Wasm benchmarking subgroup made an official org, Moz could attend and feedback, but not much bandwidth for active contribution

NF (chat): microbenchmarks have their place, but not in shared benchmark suites that will inevitably be used to compare between engines. within such a benchmark suite, we should really only have real world programs to avoid the overfitting you mentioned earlier.

BT: you’d be against microbenchmarks?

NF: in any shared suite, yes

BT: depends on purpose - microbenchmark can be used to confirm presence of optimisations we rely on - one microbench terrible - many in a suite can have a purpose

NF: no control over how these are interpreted - no nuance - results only reliable if they are not read as nuanced

BT: microbenchmarks shouldn’t be used for bragging

JM: I share concerns about microbenchmarks - compared to speedometer 3, we can’t do toolchain tests. Your design space could include toolchains and browser vendors to check real user experience - exciting.

CWoods: we’d also like to be involved - political reality of microbenches complicated - we want to understand Wasm performance profile and engineering best effort - microbenches useful for that - not comparing between runtimes, but finding squeaky wheels. We found: random memory accesses and bounds checking can be expensive - graphs, vtables.

If you end up in the space where you end up in a space like C++ where some things are horribly slow that would be better (rougth note)

BT: thanks

DG: at time - follow up on setting up subgroup

DSL for specification: Next steps (Andreas Rossberg, Sukyoung Ryu, Conrad Watt)

AR presenting slides

KW: could you synthesise the reference interpreter?

AR: we synthesised a prose interpreter - in principle yes - to me, not highest priority - it’s the first thing you write

KW: synthesise mechanisation?

CW: YES

CW: You could also synthesize some proofs in coq

KW: Could this make all the formal stuff more manageable

AR: (presenting)

TL: what is it written in, how maintainable

AR: In OCaml, (laughts) because it’s the language for this sort of stuff. I can’t say yet how maintainable it is, it is hard to know right now. Important goal.

TL: How do we share the burden?

AR: It should simplify the authoring, but also reduce the maintenance. Tweaking of layout and semantics parts can be done by different people.

BT: Is there a spec for the specDSL?

AR: I presented SpecTec at ICFP, people asking whether they could use that for their toys. But that’s very specialised for Wasm. We don’t try to be general. Other tools that are generals don’t work.

CW: We don’t want users, we don’t want to maintain it for anybody else

HA: Do we still have to write something else than the spec document?

AR: We still have to write the explainers and the structure of the document

HA: Is that currently usable right away?

AR: We have full support for Wasm 2.0 minus SIMD but the tool is not completely ready

: What do you think would be the timeline

AR: We should start only for the latex part, I would have liked to use that for Wasm 3, but it is not clear that we would be ready in time. But we can do that incrementally. Different parts don’t have the same risks. Latex is probably the lower risk part.

Are there any objections? This is the phase where there should be unanimous consent.

(Nobody say anything)

?: How do we know that what is written is sensible ?

AR: We can check the output. This would allow lots of consistency checks that we can’t do right now with our tooling and latex.

CW: We don’t want to add coq or isabelle in the tools that the CG has to maintain

TL: It is specialised for Wasm. Can this cope up with next evolutions

AR: Wasm3 should be the litmus test for that. It didn’t need extensions: seems good

Wasm_of_ocaml: compiling OCaml bytecode to WasmGC (Jérôme Vouillon)

JV presenting slides

TL: About the endianness mismatch. Linear memory is little endian

JV: And typed array have platform endiannes

JV: (presenting)

AR: great stuff, I love it. The numbers are including wasm-opt I suppose.

JV: Yes

AR: Did you try without

JV: No

RT: You said that cast are 5%. Is that 5% of the 7x slowdown ?

JV: This is the difference between running some files with and without chrome option to disable tests

RT: Does that mean that relative to native ⅓ of the native time is spent doing tests ?

Post-MVP GC discussion (Andreas Rossberg)

AR presenting slides

AK: Determinism makes sense, I don’t think its good to sneak it in, take it through a longer discussion - it’s easy to not support GC. It’s complicated enough to go through the process

AR: Whenever it’s going to be a part of the spec, we want to make sure the profiles spec is there

RH: Spidermonkey perspective, we don’t see anything wrong, we expect it to see a significant amount of work, stack switching will also be a lot of work, but we will most likely prioritize stack switching first

AR: The two also interact in nasty ways.

AK: V8 is very interested in this and because of our work on shared structs in JS, we'll be in a position to experiment with this in the next year. We're also talking to partners who might be interested in experimenting with this, since they'll have to rearchitect their apps to take advantage of it.

JM: Architecture is very real, would be nice to know how good this is for the fullness of time, is this a feature that is desired? Are new languages coming up with newer concurrency model? Another question - does this pessimize wasm applications that donb’t use threads? Does this necessitate the design of a garbage collector that performs worse on single-threaded applications?

HP: I can say something brief, the current implementation isn’t penalizing the main thread, we’re happy to share our story - we’re not sure if we’re at the good place yet, but we have projects in place that are working through it

AR: I expect this direction to be inevitable. The question is now how hard we want to push forward on this. The next question is who would want to pick this up. As a proposal it’s relatively simple. You’ll have to a number of discussions with engine vendors.

TL: Everything we talked about yesterday, we would also solve for this effort - salami slicing - how do we uncouple stuff?

AR: We should do it a part of the threading proposal

CW: We could legitimately call this share everything proposal

PC: Should there be a profile?

AR: You’ll have a no-GC, no-threads profile - if you’ve excluded one you’ve excluded the feature. Or if you need one you might need the other too

CW: Just so I totally understand, did you win anything from being able to import the literal GC types you can import today or is this more relevant for post-MVP extensions?

AR: Gives you a way of paramerarizing over the type you’re operating on, to the module its only a reference type, so you’re not tied to what the thing is. the string implementation is a special case example

CW: But would you ever try to import a less precise struct type by someone else or is that too much granularity

AR: Like a supertype? I don’t have a good use case for that. Maybe that exists in some systems but honestly I don’t know.

CW: That’s all I was hoping to hear

AR: Not sure if that adds any significant complexity. It’s just subtype checking and you can restrict the syntax on one side of that check or not, other than that I don’t think it has one real implication on implementations.

FM: You can’t compile an offset to a structure.. Maybe too specific

AR: What I meant is there is no implication for engines to allow this but disallowing that might be a nice example of excluding some things, knowing you have a common header for structs that define a different module without having to know the extent of all of them. That’s a good example. Might be worth just doing it, but Post-Post-MVP.

TL: There’s one thorny but trivial problem, the type section comes before the import section

AR: Yes, I should have that on the next slide. There is also one minor thing, we want to allow type definitions with abstract heap types because someone might want to include i31 as their implementation for something.

RT: For now when you cast to an imported type, so you can’t precompile the type during instantiation

AR: Will get back to that problem as well. You are right. We have to think about casts as well in that context.

TL: Of course if you allow interleaving sections, that won't help the case where the import section has to come in the middle of a recursion group.

AR: That won’t work anyway if you have mutual recursion, you can’t import them independently anyway. That’s one restriction about isorecursive types that I mentioned before, you have to import them together

TL: Are these so similar that every function that takes a type import is exactly the same thing?

AR: that’s the invariant I would want, a generic function is equivalent to a little module with an import. It can access it’s surroundings so that it has a closure of course, other than that, that’s the property I want. Efficient way that doesn’t require instantiation for each call.

BT: I would like to see type parameters decoupled from type imports

AR: No need, as long as we keep the constraints separate. At least need to be designed together

BT: Seems like more engine work

AR: that’s the point: right now this is a pure validation time feature. Needs nothing in the runtime and I think that’s an important goal to achieve. That’s why I want to keep it separate from value type instantiation.

FM: Before we go into that we should have a proper requirement or use case for it, which group of users are we unblocking?

AR: I think basically almost every language that has some form of generics except Java generics because they are an afterthought they are compiled away. Almost every other language that has generics has cases where if you don’t have that, you have to do this upcast/downcast dance. OCaml is one an example, C# is another.

TL: Do the ocaml folks in the room have a sense of if they’ll use this?

PC: Given that we’ve seen max 10% in the test, we may not do it first

JK: Type related use case that stood out is would like to pass it back to the host and I don’t have to so far is importing opaque types from the host. Strings is one example but not the only. Would be good not to have a soup of externref because once you consume such an externref you need to type check it so if you don’t have something like Arrays and StringBuffers inside of Wasm core, and we have good reasons for some of these, it would be good to say I have a string from the host here and I don’t have to do a type check. Means we also need a type check function because the engine needs to do a type check at the boundary to amke sure it matches the object being passed around.

AR: Which gets back to the question of moving back from exported types, another way to phrase this imported/exported rtts..

CW: I'm a little surprised that you're expecting that we can map source level generics to this, given that we weren't expecting source types to map directly to Wasm types.

AR: They might have to do pass more than just an RTT. IT’s not sufficient, but it is a building block

CR: It’s a good start but I need to think more.

RT: For something like ocaml to use this, because it needs to downcast at some type. Every polymorphic function will also be gicen the rtt for it, you will then have to construct the rtt on the fly, and then you have to do the type construction dynamically, is this worth it? <TODO: RT to fix>

AR: The whole point is not to pass an RTT everywhere. Basically when you compile something like OCaml with a type repr you have eqref anyway. And only the places where you consume a value you need a cast but at that point you usually know the type you are casting to. In addition this allows a polymorphic call has a more concrete type, you might also get out a more concrete type when it gets back to you.

RT: I can’t construct a pair value of alpha alpha, without knowing the rtt for tag (?)

AR: That is correct. The other feature we need is a way of constructing/allocating values without RTT. So if you never want to cast them, they don’t need to carry RTT. A good question hwo much of your code would fall into the intersection of things where you never need RTT but it’s worth investigating whether it gives some benefit in circumstances.

ZB: Both features look like we would want to use them in Kotlin, more request - how about having import/export of unsigned numbers, could be used to provide better APIs and to go abc and forth from the host.

AR: What do you mean importing unsigned numbers?

ZB: Allowing using u8 in import/export section

AR: Not just about imports/exports, we don’t have small integers. Once we have them you can import/export them as an immutable global but it is not something we have included.

ZB: Another thing about typed parameters is about covariant and invariant things and different bounds for typed parameters

AR: That’s a well-known problem. For that we could do variance and polarities as they are sometimes called. plausible but not entirely straightforward and another added complexity. There is a point of diminishing returns but we have to figure out where that is, so for polarities we have to figure out where that is but nothing technically preventing that.

BT: Scala has a long complicated history of type parameters, their experiments of reified ??

AR: maybe that’s why i'm bringing it up, worth investigating, I don’t have an answer. My gut is it is.

: Just wanted to add what Ben keeps saying, I’m skeptical of type parameters at all because of the type varieties there are across the languages.

AR: most languages don't allow you to specify variance much, scala does, lets not talk about Java, doesn’t matter anyway because type erasure. Some modern OOO languages have it, Ocaml doesn’t count

SL: ocaml does

AK: Whether we should do work here depends on source languages that can give us feedback. We shouldn’t sopend time without having folks singed up to do that.

AR: They have to be able to experiment with it, chicken and egg problem

AK: I think we should have people who say yes right now im hearing language implementers say I don’t know if I would try this because I have other stuff or its not a big deal. To answer the question about prioritization.

AR: There’s a semantic difference for variance, if some languages use an unsound thing, they’re on their own

FM: So far this is really not post-MVP GC, but post-MVP types. What about extending the range of GC languages that we might want to support - Go, do we want to support finalizers?

AR: I have a slide on finalizers yes. But yes this is mostly about types, but they are the complex part about GC mostly. If you look at the GC proposal mostly it’s trivial and most of the complexity is the types.

TL: There seems to be two broad paths you could take. .. This approach or you could add vtables to the language

EZ: Also save memory

TL: CW added you can add type parameters super interesting… vTables could also save memory if you do other stuff with it.

AR: IF you do it right, I think you should be able to get as good. But one thing I don’t have is the descriptor here. There is a way os fixing this, a paper 20 years ago introduced this notion of a self type quantifier. More type theory context but if you translate it into Wasm it might be all the thing you need to do is write this.

TL: If you’re talking about the paper I think you are referring to, it built on F-Bounded Polymorphism.

RT: That paper, noone’s able to work for JAva or anything like that, its insufficiently expressive for a lot of common cases

AR: Sure it will always be expressible for many cases but it’s about how far can we get with so little.

RT: The paper that you have on the slide, it couldn’t handle it properly, specially optimizing compilers, the type system is too complicated. No optimizing compiler was able to make it work

AR: Because why?

AR: That’s a fair point, anything we add to the type system means more qork and deeper understanding for tools to deal with and in general that seemslike an inevitable tradeoff or conflict. You have to make your choice. Either accept paying a certain cost or you make the type system more complex. I don’t know how to resolve this. Is it worth while or too much to go there.

BT: Higher level point: We should motivate this with language needs

AR: This one is a concrete need. All the languages compiling to it already.

BT: and will have to decide how to prioritize, you mentioned a memory overhead as well, making the memory efficiency of objects will be important.

AR: I thnk that’s totally doable.

AK: Combining what Ben and Thomas said, its not about having self types that have casts, but there’s a problem to be solved. The question is what problem are we solving, and not solution are we offering.

AR: Self Types you can read in two ways. It’s solving typing of self parameters

AK: That’s the right way to approach each of these things.

AR: Fair.

FM: The java string type is actually an example of this.

AR: Right. Also in C when you do data structures in C, a common pattern to have an array at the end. Definitely not weird.

TL: I don’t know if you’re familiar with the get Element pointer instruction in LLVM IR

AR: I’m not

TL: It’s kind of like a struct.get, array.get but it takes as many indices as it needs to traverse into this nested thing, so you don't need to take references

AR: Also not something you necessarily want over time, benefits for the complexity aren’t clear

CW: I remember early conversations about interior pointer support is this the same thing?

AR: But if engines implement fat pointers, they would be penalized, they’d have to optimize them into interiroir pointers. I doubt they would do that because interior pointers are painful. I have a slide saying I don’t know what we want to do here.

CW: JS has weak references and a finalization registry. Do we want to do that or do they have the right idea?

AR: Every language has at least one or several semantics for this kind of thing, they are mutually incompatible with each other.

AW: WIll be advantageous to source languages. But none of them were on the list of OCaml, Scheme, Kotlin. If we are going to prioritize, we have to pick what wins.

Closure (Day 2)