Skip to content

[wasm2c] Add support for i32 arithmetic and basic variables - #8957

Open
lexi-nadia wants to merge 1 commit into
WebAssembly:mainfrom
lexi-nadia:wasm2c-i32
Open

[wasm2c] Add support for i32 arithmetic and basic variables#8957
lexi-nadia wants to merge 1 commit into
WebAssembly:mainfrom
lexi-nadia:wasm2c-i32

Conversation

@lexi-nadia

Copy link
Copy Markdown
Collaborator

This change adds the bare minimum support needed to make the i32.wast spec test suite pass.

This change adds the bare minimum support needed to make the i32.wast spec test suite pass.
@lexi-nadia
lexi-nadia requested a review from a team as a code owner July 30, 2026 22:39
@lexi-nadia
lexi-nadia requested review from tlively and removed request for a team July 30, 2026 22:39
isFirst = false;
} else if (c == '_') {
if (isFirst) {
result += "0x5F";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wouldn't this create an identifier starting with a number? That's not valid, right? I see that this is only used to mangle some suffix of the final name. It would be good to add a comment about that.

Comment on lines +107 to +111
std::vector<std::string> modulePrefixes;
std::unordered_map<Name, std::string> moduleNameToPrefix;
std::unordered_map<std::string, std::unordered_set<std::string>>
moduleExports;
std::string lastModulePrefix;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It would be good to have some comments on what these hold. In particular it would be good to point out that we may be translating multiple modules at once for spec tests that contain multiple modules.

// Verify export exists
auto expIt = moduleExports.find(activePrefix);
if (expIt == moduleExports.end() ||
!expIt->second.count(invoke->name.toString())) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
!expIt->second.count(invoke->name.toString())) {
!expIt->second.contains(invoke->name.toString())) {

exports.insert(exp->name.toString());
}
}
moduleExports[prefix] = exports;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
moduleExports[prefix] = exports;
moduleExports[prefix] = std::move(exports);


// Verify export exists
auto expIt = moduleExports.find(activePrefix);
if (expIt == moduleExports.end() ||

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like we could do something like const auto& exports = moduleExports.at(activePrefix); because we already verified that the module name is good and therefore activePrefix must exist and have an entry in moduleExports.

: c(c), func(func), moduleName(moduleName) {}

void push() {
stackDepth++;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We generally prefer pre-increment operators (although this was not historically the case).

Suggested change
stackDepth++;
++stackDepth;

Comment on lines +114 to +118
if (func->isParam(curr->index)) {
name = "var_p" + std::to_string(curr->index);
} else {
name = "var_l" + std::to_string(curr->index - func->getNumParams());
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any particular reason not to unify the names and just use var_<i> for both?

Comment on lines +352 to +353
if (exportedFunctions.count(func->name)) {
std::string exportedName = mangleName(exportedFunctions[func->name]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can avoid the double lookup here and similar places.

Comment on lines +420 to +422
std::string exportedName = mangleName(exportedFunctions[func->name]);
c << resType << " w2c_" << moduleName << "_" << exportedName << "("
<< paramsDecl << ") {" << endl;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It would be nice to pull out helper functions for all the different kinds of names that need to be assembled.

Comment on lines +438 to +441
StackIR* stackIR = moduleStackIR.getStackIROrNull(func.get());
if (!stackIR) {
Fatal() << "Failed to generate Stack IR for function " << func->name;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since we just need to visit each instruction in order, it would be simpler to use a PostWalker than StackIR. Unless there's another reason to use StackIR that I'm forgetting?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants