| Index: src/asmjs/asm-js.cc
|
| diff --git a/src/asmjs/asm-js.cc b/src/asmjs/asm-js.cc
|
| index eb3d017f857fce4503eafe29cbbdda3dedfe55c8..182ee151fa27e0ad783cb5df5b005a4e13553190 100644
|
| --- a/src/asmjs/asm-js.cc
|
| +++ b/src/asmjs/asm-js.cc
|
| @@ -53,8 +53,28 @@ i::MaybeHandle<i::FixedArray> CompileModule(
|
| return compiled_module;
|
| }
|
|
|
| +Handle<i::Object> StdlibMathMember(i::Isolate* isolate,
|
| + Handle<JSReceiver> stdlib,
|
| + Handle<Name> name) {
|
| + Handle<i::Name> math_name(
|
| + isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Math")));
|
| + MaybeHandle<i::Object> maybe_math = i::Object::GetProperty(stdlib, math_name);
|
| + if (maybe_math.is_null()) {
|
| + return Handle<i::Object>();
|
| + }
|
| + Handle<i::Object> math = maybe_math.ToHandleChecked();
|
| + if (!math->IsJSReceiver()) {
|
| + return Handle<i::Object>();
|
| + }
|
| + MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(math, name);
|
| + if (maybe_value.is_null()) {
|
| + return Handle<i::Object>();
|
| + }
|
| + return maybe_value.ToHandleChecked();
|
| +}
|
| +
|
| bool IsStdlibMemberValid(i::Isolate* isolate, Handle<JSReceiver> stdlib,
|
| - i::Handle<i::Object> member_id) {
|
| + Handle<i::Object> member_id) {
|
| int32_t member_kind;
|
| if (!member_id->ToInt32(&member_kind)) {
|
| UNREACHABLE();
|
| @@ -62,56 +82,81 @@ bool IsStdlibMemberValid(i::Isolate* isolate, Handle<JSReceiver> stdlib,
|
| switch (member_kind) {
|
| case wasm::AsmTyper::StandardMember::kNone:
|
| case wasm::AsmTyper::StandardMember::kModule:
|
| - case wasm::AsmTyper::StandardMember::kStdlib: {
|
| + case wasm::AsmTyper::StandardMember::kStdlib:
|
| + case wasm::AsmTyper::StandardMember::kHeap:
|
| + case wasm::AsmTyper::StandardMember::kFFI: {
|
| // Nothing to check for these.
|
| return true;
|
| }
|
| - case wasm::AsmTyper::StandardMember::kNaN: {
|
| - i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
|
| - STATIC_CHAR_VECTOR("NaN")));
|
| - i::MaybeHandle<i::Object> maybe_value =
|
| - i::Object::GetProperty(stdlib, name);
|
| + case wasm::AsmTyper::StandardMember::kInfinity: {
|
| + Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
|
| + STATIC_CHAR_VECTOR("Infinity")));
|
| + MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name);
|
| if (maybe_value.is_null()) {
|
| return false;
|
| }
|
| - i::Handle<i::Object> value = maybe_value.ToHandleChecked();
|
| - if (!value->IsNaN()) {
|
| + Handle<i::Object> value = maybe_value.ToHandleChecked();
|
| + return value->IsNumber() && std::isinf(value->Number());
|
| + }
|
| + case wasm::AsmTyper::StandardMember::kNaN: {
|
| + Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
|
| + STATIC_CHAR_VECTOR("NaN")));
|
| + MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name);
|
| + if (maybe_value.is_null()) {
|
| return false;
|
| }
|
| - return true;
|
| + Handle<i::Object> value = maybe_value.ToHandleChecked();
|
| + return value->IsNaN();
|
| }
|
| - case wasm::AsmTyper::StandardMember::kHeap:
|
| - case wasm::AsmTyper::StandardMember::kFFI:
|
| - case wasm::AsmTyper::StandardMember::kInfinity:
|
| - case wasm::AsmTyper::StandardMember::kMathAcos:
|
| - case wasm::AsmTyper::StandardMember::kMathAsin:
|
| - case wasm::AsmTyper::StandardMember::kMathAtan:
|
| - case wasm::AsmTyper::StandardMember::kMathCos:
|
| - case wasm::AsmTyper::StandardMember::kMathSin:
|
| - case wasm::AsmTyper::StandardMember::kMathTan:
|
| - case wasm::AsmTyper::StandardMember::kMathExp:
|
| - case wasm::AsmTyper::StandardMember::kMathLog:
|
| - case wasm::AsmTyper::StandardMember::kMathCeil:
|
| - case wasm::AsmTyper::StandardMember::kMathFloor:
|
| - case wasm::AsmTyper::StandardMember::kMathSqrt:
|
| - case wasm::AsmTyper::StandardMember::kMathAbs:
|
| - case wasm::AsmTyper::StandardMember::kMathClz32:
|
| - case wasm::AsmTyper::StandardMember::kMathMin:
|
| - case wasm::AsmTyper::StandardMember::kMathMax:
|
| - case wasm::AsmTyper::StandardMember::kMathAtan2:
|
| - case wasm::AsmTyper::StandardMember::kMathPow:
|
| - case wasm::AsmTyper::StandardMember::kMathImul:
|
| - case wasm::AsmTyper::StandardMember::kMathFround:
|
| - case wasm::AsmTyper::StandardMember::kMathE:
|
| - case wasm::AsmTyper::StandardMember::kMathLN10:
|
| - case wasm::AsmTyper::StandardMember::kMathLN2:
|
| - case wasm::AsmTyper::StandardMember::kMathLOG2E:
|
| - case wasm::AsmTyper::StandardMember::kMathLOG10E:
|
| - case wasm::AsmTyper::StandardMember::kMathPI:
|
| - case wasm::AsmTyper::StandardMember::kMathSQRT1_2:
|
| - case wasm::AsmTyper::StandardMember::kMathSQRT2:
|
| - // TODO(bradnelson) Actually check these.
|
| - return true;
|
| +#define STDLIB_MATH_FUNC(CamelName, fname) \
|
| + case wasm::AsmTyper::StandardMember::k##CamelName: { \
|
| + Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \
|
| + STATIC_CHAR_VECTOR(#fname))); \
|
| + Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \
|
| + if (value.is_null() || !value->IsJSFunction()) { \
|
| + return false; \
|
| + } \
|
| + Handle<i::JSFunction> func(i::JSFunction::cast(*value)); \
|
| + return func->shared()->code() == \
|
| + isolate->builtins()->builtin(Builtins::k##CamelName); \
|
| + }
|
| + STDLIB_MATH_FUNC(MathAcos, acos)
|
| + STDLIB_MATH_FUNC(MathAsin, asin)
|
| + STDLIB_MATH_FUNC(MathAtan, atan)
|
| + STDLIB_MATH_FUNC(MathCos, cos)
|
| + STDLIB_MATH_FUNC(MathSin, sin)
|
| + STDLIB_MATH_FUNC(MathTan, tan)
|
| + STDLIB_MATH_FUNC(MathExp, exp)
|
| + STDLIB_MATH_FUNC(MathLog, log)
|
| + STDLIB_MATH_FUNC(MathCeil, ceil)
|
| + STDLIB_MATH_FUNC(MathFloor, floor)
|
| + STDLIB_MATH_FUNC(MathSqrt, sqrt)
|
| + STDLIB_MATH_FUNC(MathAbs, abs)
|
| + STDLIB_MATH_FUNC(MathClz32, clz32)
|
| + STDLIB_MATH_FUNC(MathMin, min)
|
| + STDLIB_MATH_FUNC(MathMax, max)
|
| + STDLIB_MATH_FUNC(MathAtan2, atan2)
|
| + STDLIB_MATH_FUNC(MathPow, pow)
|
| + STDLIB_MATH_FUNC(MathImul, imul)
|
| + STDLIB_MATH_FUNC(MathFround, fround)
|
| +#undef STDLIB_MATH_FUNC
|
| +#define STDLIB_MATH_CONST(cname, const_value) \
|
| + case wasm::AsmTyper::StandardMember::kMath##cname: { \
|
| + i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \
|
| + STATIC_CHAR_VECTOR(#cname))); \
|
| + i::Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \
|
| + return !value.is_null() && value->IsNumber() && \
|
| + value->Number() == const_value; \
|
| + }
|
| + STDLIB_MATH_CONST(E, 2.718281828459045)
|
| + STDLIB_MATH_CONST(LN10, 2.302585092994046)
|
| + STDLIB_MATH_CONST(LN2, 0.6931471805599453)
|
| + STDLIB_MATH_CONST(LOG2E, 1.4426950408889634)
|
| + STDLIB_MATH_CONST(LOG10E, 0.4342944819032518)
|
| + STDLIB_MATH_CONST(PI, 3.141592653589793)
|
| + STDLIB_MATH_CONST(SQRT1_2, 0.7071067811865476)
|
| + STDLIB_MATH_CONST(SQRT2, 1.4142135623730951)
|
| +#undef STDLIB_MATH_CONST
|
| default: { UNREACHABLE(); }
|
| }
|
| return false;
|
|
|