Skip to content

Instantly share code, notes, and snippets.

@timakin
Last active August 29, 2015 14:15
Show Gist options
  • Save timakin/691d5aa46088287c9927 to your computer and use it in GitHub Desktop.
Save timakin/691d5aa46088287c9927 to your computer and use it in GitHub Desktop.
JavaScriptのMathクラスの実装をV8エンジンソースから読み解く╭( ・ㅂ・)و ̑̑ ref: http://qiita.com/timakin/items/2b0436c60e43e78894a2
var $floor = MathFloor;
function MathFloor(x) {
x = TO_NUMBER_INLINE(x);
// It's more common to call this with a positive number that's out
// of range than negative numbers; check the upper bound first.
if (x < 0x80000000 && x > 0) {
// Numbers in the range [0, 2^31) can be floored by converting
// them to an unsigned 32-bit value using the shift operator.
// We avoid doing so for -0, because the result of Math.floor(-0)
// has to be -0, which wouldn't be the case with the shift.
return TO_UINT32(x);
} else {
return %MathFloorRT(x);
}
}
macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : NonNumberToNumber(arg));
RUNTIME_FUNCTION(Runtime_MathFloorRT) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
isolate->counters()->math_floor()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
return *isolate->factory()->NewNumber(Floor(x));
}
#define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
RUNTIME_ASSERT(args[index]->IsNumber()); \
double name = args.number_at(index);
double number_at(int index) {
return (*this)[index]->Number();
}
double number_at(int index) {
return (*this)[index]->Number();
}
macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : NonNumberToNumber(arg));
var $floor = MathFloor;
function MathFloor(x) {
x = TO_NUMBER_INLINE(x);
// It's more common to call this with a positive number that's out
// of range than negative numbers; check the upper bound first.
if (x < 0x80000000 && x > 0) {
// Numbers in the range [0, 2^31) can be floored by converting
// them to an unsigned 32-bit value using the shift operator.
// We avoid doing so for -0, because the result of Math.floor(-0)
// has to be -0, which wouldn't be the case with the shift.
return TO_UINT32(x);
} else {
return %MathFloorRT(x);
}
}
RUNTIME_FUNCTION(Runtime_MathFloorRT) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
isolate->counters()->math_floor()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
return *isolate->factory()->NewNumber(Floor(x));
}
#define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
RUNTIME_ASSERT(args[index]->IsNumber()); \
double name = args.number_at(index);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment