Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: implements almost all of the i32 operations #100

Merged
merged 12 commits into from
Jan 19, 2018

Conversation

ColinEberhardt
Copy link
Collaborator

@ColinEberhardt ColinEberhardt commented Jan 17, 2018

progress towards #97

  • i32.add
  • i32.sub
  • i32.mul
  • i32.div_u
  • i32.div_s - needs to throw 'integer overflow' exception
  • i32.or
  • i32.xor
  • i32.and
  • i32.rem_u
  • i32.rem_s
  • i32.shl
  • i32.shr_u
  • i32.shr_s
  • i32.rotl
  • i32.rotr
  • i32.clz
  • i32.ctz
  • i32.popcnt
  • i32.eq
  • i32.eqz
  • i32.ine
  • i32.ilt_u
  • i32.ilt_s
  • i32.igt_u
  • i32.igt_s
  • i32.ile_u
  • i32.ile_s
  • i32.ige_u
  • i32.ige_s

fixes #87

I'm basically running through all of our integer operations with a goal of getting them fully spec compliant and closing off #97

I've taken the official webassembly test suite and used a few regexes to convert it into chai / mocha test. Once #76 is implemented, these tests can be deleted.

Regarding this specific change, i32 is now a class that implements our NumberInterface interface, allowing implementation of some of the specific features we need to match WebAssembly integer maths. With this PR we now support signed / unsigned division, multiplication uses Long to ensure we don't exceed JS numeric precision, and various runtime exceptions are being thrown (as per spec)

@ColinEberhardt
Copy link
Collaborator Author

updated to add:

  • i32.and
  • i32.rem_u
  • i32.rem_s

@ColinEberhardt
Copy link
Collaborator Author

updated to add:

  • i32.shl
  • i32.shr_u
  • i32.shr_s

@ColinEberhardt
Copy link
Collaborator Author

  • rotl
  • rotr

@@ -79,52 +79,52 @@ it("should conform to the wasm test suite", () => {
equals(m.exports.div_u(11, 5), 2);
equals(m.exports.div_u(17, 7), 2);

// throws(() => m.exports.rem_s(1, 0), "$4");
Copy link
Owner

Choose a reason for hiding this comment

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

Could we remove it instead of commenting it?


export function createValueFromAST(value: number): StackLocal {
value = (value | 0) % Math.pow(2, bits);
export class i32 implements Number<i32> {
Copy link
Owner

Choose a reason for hiding this comment

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

You probably need to rebase, I had to rename the interface.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah - good spot, I've turned Flow back on again, and fixed the issues this PR introduced :-)

@xtuc
Copy link
Owner

xtuc commented Jan 17, 2018

Looks nice! I will review it in detail on my desktop tommorow.

@ColinEberhardt
Copy link
Collaborator Author

ColinEberhardt commented Jan 17, 2018

  • clz
  • ctz

NOTE: these are simple, worst case O(31), implementations. In future, it might be worth using a more optimal algorithm http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear

@ColinEberhardt ColinEberhardt changed the title fix: fixed various i32 operations feat: implements almost all of the i32 operations Jan 18, 2018
@@ -69,6 +70,92 @@ export class BaseNumber implements NumberInterface<BaseNumber> {
return new BaseNumber(-this._value);
}

/*eslint-disable no-unused-vars*/
Copy link
Owner

Choose a reason for hiding this comment

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

Just FYI I commented the operand somewhere in a PR, like:

rem_s(/*operand: BaseNumber*/): BaseNumber {
    throw new RuntimeError("Unsupported operation");
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, good point - for some reason I thought doing that would result in Flow errors, but it does not :-)

return createValue(c.popcnt());

case "eqz":
return createValue(c.eqz());
Copy link
Owner

Choose a reason for hiding this comment

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

By the way, why is the value called c? value sounds more explicit to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good point - I'll change that.

}

isTrue(): boolean {
return this._value == 1;
Copy link
Owner

Choose a reason for hiding this comment

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

We can use triple equal here. I'm not sure about this tbh, numeric types are not booleans, either the name is misleading or we could inline the === 1 in the callers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

=== 👍

This reflects the specification which details a boolean interpretation for integers:

https://webassembly.github.io/spec/core/exec/numerics.html#boolean-interpretation

I'll add this as a comment.

(i32.ge_u)
)
(export "ge_u" (func $ge_u))
)
Copy link
Owner

@xtuc xtuc Jan 19, 2018

Choose a reason for hiding this comment

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

I really like that, the spec is way more testable this way, but way less maintainable.

We can commit that we after we include the spec tests we should remove it, ok? If so I can create an issue to track it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll add an issue to track

Copy link
Owner

@xtuc xtuc left a comment

Choose a reason for hiding this comment

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

Otherwise, lgtm! 👍

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

Successfully merging this pull request may close these issues.

incorrect implementation of i32.div_s
2 participants