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

Fix of ToUInt32 (ecma_number_to_uint32) and ToInt32 (ecma_number_to_int32) conversion routines #226

Merged
merged 2 commits into from
Jun 23, 2015

Conversation

ruben-ayrapetyan
Copy link
Contributor

Related issue: #160

@ruben-ayrapetyan ruben-ayrapetyan added bug Undesired behaviour critical Raises security concerns ecma core Related to core ECMA functionality labels Jun 22, 2015
@ruben-ayrapetyan ruben-ayrapetyan added this to the Core ECMA features milestone Jun 22, 2015
@egavrin
Copy link
Contributor

egavrin commented Jun 22, 2015

Good to me.

@ruben-ayrapetyan ruben-ayrapetyan assigned galpeter and unassigned egavrin Jun 22, 2015
const ecma_number_t num_2_pow_32 = (float) uint64_2_pow_32;

ecma_number_t num_in_uint32_range = ecma_number_calc_remainder (abs_num,
num_2_pow_32);
Copy link
Member

Choose a reason for hiding this comment

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

Personally I think this is a costly operation, and would add a fast path which simply checks that abs_num < num_2_pow_32.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@galpeter galpeter assigned zherczeg and unassigned galpeter Jun 23, 2015
// Check that the value can be represented with uint32_t
JERRY_ASSERT (ret < (1ull << 32));

return (uint32_t) ret;
Copy link
Member

Choose a reason for hiding this comment

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

uint64 computation on 32 bit machines is also costly, and I think it is not necessary here. We could achive the same result with:

uint32_t uint32_num = (uint32_t) num_in_uint32_range;
if (sign)
{
uint32_num = -uint32_num;
}
return uint32_num;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@egavrin
Copy link
Contributor

egavrin commented Jun 23, 2015

Vera checks failed.

@ruben-ayrapetyan
Copy link
Contributor Author

Pull request is updated.

@ruben-ayrapetyan
Copy link
Contributor Author

@zherczeg, @egavrin, pull request is fixed according to your notes. Please, review.

@egavrin
Copy link
Contributor

egavrin commented Jun 23, 2015

Good to me.

{
return 0;
ret = (int32_t) (uint32_num - int64_2_pow_32);
Copy link
Member

Choose a reason for hiding this comment

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

I am not fully sure, but isn't the is the same as the original uint32_num? You substract 32 0s, and only keep the lower 32 bit. Should be the same as ret = (int32_t) uint32_num; If this is true, we could remove the whole check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably, it is true for most cases, but according to C++ standard (4.7. Integral conversions):
"If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined."

From other view point, for cases, where it is true, optimizer should remove unnecessary operations. I'll check this on armv7-hf and x86_32 targets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If noinline attribute is put on both functions, g++ 4.8.2 produces the following code for ecma_number_to_int32 (-Os optimization level):

  • x86:
0804fdab <_Z20ecma_number_to_int32d>:
 804fdab:       55                      push   %ebp
 804fdac:       89 e5                   mov    %esp,%ebp
 804fdae:       5d                      pop    %ebp
 804fdaf:       e9 47 ff ff ff          jmp    804fcfb <_Z21ecma_number_to_uint32d>
  • armv7-hf:
0000d0c0 <_Z20ecma_number_to_int32d>:
    d0c0:       e7c1            b.n     d046 <_Z21ecma_number_to_uint32d>

So, all conversion operations in ecma_number_to_int32, are removed for the targets, and the function, actually, just returns the value, received from ecma_number_to_uint32.

@zherczeg
Copy link
Member

Looks much better, +1 from me.

@egavrin
Copy link
Contributor

egavrin commented Jun 23, 2015

make push

…sponding to item 6 (actual remainder calculation, without handling of NaN. Infinity and zero values), as ecma_number_calc_remainder.

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan [email protected]
…nt32) conversion routines.

Related issue: #160

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan [email protected]
@ruben-ayrapetyan ruben-ayrapetyan merged commit 913519d into master Jun 23, 2015
@ruben-ayrapetyan ruben-ayrapetyan deleted the Ruben-fix-issue-160 branch June 23, 2015 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Undesired behaviour critical Raises security concerns ecma core Related to core ECMA functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants