LCOV - code coverage report
Current view: top level - test/unittests/compiler - js-call-reducer-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 291 300 97.0 %
Date: 2019-02-19 Functions: 58 84 69.0 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cctype>
       6             : 
       7             : #include "src/compiler/compilation-dependencies.h"
       8             : #include "src/compiler/js-call-reducer.h"
       9             : #include "src/compiler/js-graph.h"
      10             : #include "src/compiler/simplified-operator.h"
      11             : #include "src/feedback-vector.h"
      12             : #include "src/heap/factory.h"
      13             : #include "src/isolate.h"
      14             : #include "test/unittests/compiler/graph-unittest.h"
      15             : #include "test/unittests/compiler/node-test-utils.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace compiler {
      20             : 
      21             : class JSCallReducerTest : public TypedGraphTest {
      22             :  public:
      23          24 :   JSCallReducerTest()
      24          48 :       : TypedGraphTest(3), javascript_(zone()), deps_(isolate(), zone()) {
      25          24 :     broker()->SerializeStandardObjects();
      26          24 :   }
      27          48 :   ~JSCallReducerTest() override = default;
      28             : 
      29             :  protected:
      30          50 :   Reduction Reduce(Node* node) {
      31          50 :     MachineOperatorBuilder machine(zone());
      32          50 :     SimplifiedOperatorBuilder simplified(zone());
      33             :     JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
      34         100 :                     &machine);
      35             :     // TODO(titzer): mock the GraphReducer here for better unit testing.
      36          50 :     GraphReducer graph_reducer(zone(), graph());
      37             : 
      38             :     JSCallReducer reducer(&graph_reducer, &jsgraph, broker(),
      39          50 :                           JSCallReducer::kNoFlags, &deps_);
      40         100 :     return reducer.Reduce(node);
      41             :   }
      42             : 
      43             :   JSOperatorBuilder* javascript() { return &javascript_; }
      44             : 
      45           2 :   Node* GlobalFunction(const char* name) {
      46             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      47             :         Object::GetProperty(
      48             :             isolate(), isolate()->global_object(),
      49           6 :             isolate()->factory()->NewStringFromAsciiChecked(name))
      50           4 :             .ToHandleChecked());
      51           2 :     return HeapConstant(f);
      52             :   }
      53             : 
      54          37 :   Node* MathFunction(const std::string& name) {
      55             :     Handle<Object> m =
      56             :         JSObject::GetProperty(
      57             :             isolate(), isolate()->global_object(),
      58         111 :             isolate()->factory()->NewStringFromAsciiChecked("Math"))
      59          74 :             .ToHandleChecked();
      60             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      61             :         Object::GetProperty(
      62             :             isolate(), m,
      63          74 :             isolate()->factory()->NewStringFromAsciiChecked(name.c_str()))
      64          74 :             .ToHandleChecked());
      65          37 :     return HeapConstant(f);
      66             :   }
      67             : 
      68           2 :   Node* StringFunction(const char* name) {
      69             :     Handle<Object> m =
      70             :         JSObject::GetProperty(
      71             :             isolate(), isolate()->global_object(),
      72           6 :             isolate()->factory()->NewStringFromAsciiChecked("String"))
      73           4 :             .ToHandleChecked();
      74             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      75             :         Object::GetProperty(
      76           4 :             isolate(), m, isolate()->factory()->NewStringFromAsciiChecked(name))
      77           4 :             .ToHandleChecked());
      78           2 :     return HeapConstant(f);
      79             :   }
      80             : 
      81           5 :   Node* NumberFunction(const char* name) {
      82             :     Handle<Object> m =
      83             :         JSObject::GetProperty(
      84             :             isolate(), isolate()->global_object(),
      85          15 :             isolate()->factory()->NewStringFromAsciiChecked("Number"))
      86          10 :             .ToHandleChecked();
      87             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      88             :         Object::GetProperty(
      89          10 :             isolate(), m, isolate()->factory()->NewStringFromAsciiChecked(name))
      90          10 :             .ToHandleChecked());
      91           5 :     return HeapConstant(f);
      92             :   }
      93             : 
      94          29 :   std::string op_name_for(const char* fnc) {
      95          29 :     std::string string_fnc(fnc);
      96          29 :     char initial = std::toupper(fnc[0]);
      97          87 :     return std::string("Number") + initial +
      98         116 :            string_fnc.substr(1, std::string::npos);
      99             :   }
     100             : 
     101          43 :   const Operator* Call(int arity) {
     102          43 :     FeedbackVectorSpec spec(zone());
     103             :     spec.AddCallICSlot();
     104          43 :     Handle<FeedbackMetadata> metadata = FeedbackMetadata::New(isolate(), &spec);
     105             :     Handle<SharedFunctionInfo> shared =
     106             :         isolate()->factory()->NewSharedFunctionInfoForBuiltin(
     107          43 :             isolate()->factory()->empty_string(), Builtins::kIllegal);
     108             :     // Set the raw feedback metadata to circumvent checks that we are not
     109             :     // overwriting existing metadata.
     110          86 :     shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
     111          43 :     Handle<FeedbackVector> vector = FeedbackVector::New(isolate(), shared);
     112             :     VectorSlotPair feedback(vector, FeedbackSlot(0), UNINITIALIZED);
     113             :     return javascript()->Call(arity, CallFrequency(), feedback,
     114             :                               ConvertReceiverMode::kAny,
     115          43 :                               SpeculationMode::kAllowSpeculation);
     116             :   }
     117             : 
     118             :  private:
     119             :   JSOperatorBuilder javascript_;
     120             :   CompilationDependencies deps_;
     121             : };
     122             : 
     123       15189 : TEST_F(JSCallReducerTest, PromiseConstructorNoArgs) {
     124             :   Node* promise =
     125           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     126           1 :   Node* effect = graph()->start();
     127             :   Node* control = graph()->start();
     128           1 :   Node* context = UndefinedConstant();
     129           1 :   Node* frame_state = graph()->start();
     130             : 
     131             :   Node* construct =
     132             :       graph()->NewNode(javascript()->Construct(2), promise, promise, context,
     133           3 :                        frame_state, effect, control);
     134             : 
     135           1 :   Reduction r = Reduce(construct);
     136             : 
     137           3 :   ASSERT_FALSE(r.Changed());
     138             : }
     139             : 
     140       15189 : TEST_F(JSCallReducerTest, PromiseConstructorSubclass) {
     141             :   Node* promise =
     142           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     143             :   Node* new_target =
     144           2 :       HeapConstant(handle(native_context()->array_function(), isolate()));
     145           1 :   Node* effect = graph()->start();
     146             :   Node* control = graph()->start();
     147           1 :   Node* context = UndefinedConstant();
     148           1 :   Node* frame_state = graph()->start();
     149             : 
     150           1 :   Node* executor = UndefinedConstant();
     151             :   Node* construct =
     152             :       graph()->NewNode(javascript()->Construct(3), promise, executor,
     153           3 :                        new_target, context, frame_state, effect, control);
     154             : 
     155           1 :   Reduction r = Reduce(construct);
     156             : 
     157           3 :   ASSERT_FALSE(r.Changed());
     158             : }
     159             : 
     160       15189 : TEST_F(JSCallReducerTest, PromiseConstructorBasic) {
     161             :   Node* promise =
     162           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     163           1 :   Node* effect = graph()->start();
     164             :   Node* control = graph()->start();
     165           1 :   Node* context = UndefinedConstant();
     166           1 :   Node* frame_state = graph()->start();
     167             : 
     168           1 :   Node* executor = UndefinedConstant();
     169             :   Node* construct =
     170             :       graph()->NewNode(javascript()->Construct(3), promise, executor, promise,
     171           3 :                        context, frame_state, effect, control);
     172             : 
     173           1 :   Reduction r = Reduce(construct);
     174             : 
     175           1 :   if (FLAG_experimental_inline_promise_constructor) {
     176           1 :     ASSERT_TRUE(r.Changed());
     177             :   } else {
     178           0 :     ASSERT_FALSE(r.Changed());
     179             :   }
     180             : }
     181             : 
     182             : // Exactly the same as PromiseConstructorBasic which expects a reduction,
     183             : // except that we invalidate the protector cell.
     184       15189 : TEST_F(JSCallReducerTest, PromiseConstructorWithHook) {
     185             :   Node* promise =
     186           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     187           1 :   Node* effect = graph()->start();
     188             :   Node* control = graph()->start();
     189           1 :   Node* context = UndefinedConstant();
     190           1 :   Node* frame_state = graph()->start();
     191             : 
     192           1 :   Node* executor = UndefinedConstant();
     193             :   Node* construct =
     194             :       graph()->NewNode(javascript()->Construct(3), promise, executor, promise,
     195           3 :                        context, frame_state, effect, control);
     196             : 
     197           1 :   isolate()->InvalidatePromiseHookProtector();
     198             : 
     199           1 :   Reduction r = Reduce(construct);
     200             : 
     201           3 :   ASSERT_FALSE(r.Changed());
     202             : }
     203             : 
     204             : // -----------------------------------------------------------------------------
     205             : // Math unaries
     206             : 
     207             : namespace {
     208             : 
     209             : const char* kMathUnaries[] = {
     210             :     "abs",  "acos",  "acosh", "asin", "asinh", "atan",  "cbrt",
     211             :     "ceil", "cos",   "cosh",  "exp",  "expm1", "floor", "fround",
     212             :     "log",  "log1p", "log10", "log2", "round", "sign",  "sin",
     213             :     "sinh", "sqrt",  "tan",   "tanh", "trunc"};
     214             : 
     215             : }  // namespace
     216             : 
     217       15189 : TEST_F(JSCallReducerTest, MathUnaryWithNumber) {
     218         157 :   TRACED_FOREACH(const char*, fnc, kMathUnaries) {
     219          26 :     Node* effect = graph()->start();
     220             :     Node* control = graph()->start();
     221          26 :     Node* context = UndefinedConstant();
     222          26 :     Node* frame_state = graph()->start();
     223          52 :     Node* jsfunction = MathFunction(fnc);
     224          26 :     Node* p0 = Parameter(Type::Any(), 0);
     225             :     Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     226          26 :                                   context, frame_state, effect, control);
     227          26 :     Reduction r = Reduce(call);
     228          27 :     ASSERT_TRUE(r.Changed());
     229         156 :     EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     230           0 :                 op_name_for(fnc));
     231          26 :   }
     232             : }
     233             : 
     234             : // -----------------------------------------------------------------------------
     235             : // Math binaries
     236             : 
     237             : namespace {
     238             : 
     239             : const char* kMathBinaries[] = {"atan2", "pow"};
     240             : 
     241             : }  // namespace
     242             : 
     243       15189 : TEST_F(JSCallReducerTest, MathBinaryWithNumber) {
     244          13 :   TRACED_FOREACH(const char*, fnc, kMathBinaries) {
     245           4 :     Node* jsfunction = MathFunction(fnc);
     246             : 
     247           2 :     Node* effect = graph()->start();
     248             :     Node* control = graph()->start();
     249           2 :     Node* context = UndefinedConstant();
     250           2 :     Node* frame_state = graph()->start();
     251           2 :     Node* p0 = Parameter(Type::Any(), 0);
     252           2 :     Node* p1 = Parameter(Type::Any(), 0);
     253             :     Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     254           2 :                                   p1, context, frame_state, effect, control);
     255           2 :     Reduction r = Reduce(call);
     256             : 
     257           3 :     ASSERT_TRUE(r.Changed());
     258          12 :     EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     259           0 :                 op_name_for(fnc));
     260           2 :   }
     261             : }
     262             : 
     263             : // -----------------------------------------------------------------------------
     264             : // Math.clz32
     265             : 
     266       15189 : TEST_F(JSCallReducerTest, MathClz32WithUnsigned32) {
     267           2 :   Node* jsfunction = MathFunction("clz32");
     268           1 :   Node* effect = graph()->start();
     269             :   Node* control = graph()->start();
     270           1 :   Node* context = UndefinedConstant();
     271           1 :   Node* frame_state = graph()->start();
     272             : 
     273           1 :   Node* p0 = Parameter(Type::Unsigned32(), 0);
     274             :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     275           1 :                                 context, frame_state, effect, control);
     276           1 :   Reduction r = Reduce(call);
     277             : 
     278           2 :   ASSERT_TRUE(r.Changed());
     279           7 :   EXPECT_THAT(r.replacement(),
     280           0 :               IsNumberClz32(IsNumberToUint32(IsSpeculativeToNumber(p0))));
     281             : }
     282             : 
     283       15189 : TEST_F(JSCallReducerTest, MathClz32WithUnsigned32NoArg) {
     284           2 :   Node* jsfunction = MathFunction("clz32");
     285           1 :   Node* effect = graph()->start();
     286             :   Node* control = graph()->start();
     287           1 :   Node* context = UndefinedConstant();
     288           1 :   Node* frame_state = graph()->start();
     289             : 
     290             :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     291           1 :                                 context, frame_state, effect, control);
     292           1 :   Reduction r = Reduce(call);
     293             : 
     294           2 :   ASSERT_TRUE(r.Changed());
     295           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(32));
     296             : }
     297             : 
     298             : // -----------------------------------------------------------------------------
     299             : // Math.imul
     300             : 
     301       15189 : TEST_F(JSCallReducerTest, MathImulWithUnsigned32) {
     302           2 :   Node* jsfunction = MathFunction("imul");
     303             : 
     304           1 :   Node* effect = graph()->start();
     305             :   Node* control = graph()->start();
     306           1 :   Node* context = UndefinedConstant();
     307           1 :   Node* frame_state = graph()->start();
     308           1 :   Node* p0 = Parameter(Type::Unsigned32(), 0);
     309           1 :   Node* p1 = Parameter(Type::Unsigned32(), 1);
     310             :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     311           1 :                                 p1, context, frame_state, effect, control);
     312           1 :   Reduction r = Reduce(call);
     313             : 
     314           2 :   ASSERT_TRUE(r.Changed());
     315           6 :   EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     316           0 :               op_name_for("imul"));
     317             : }
     318             : 
     319             : // -----------------------------------------------------------------------------
     320             : // Math.min
     321             : 
     322       15189 : TEST_F(JSCallReducerTest, MathMinWithNoArguments) {
     323           2 :   Node* jsfunction = MathFunction("min");
     324           1 :   Node* effect = graph()->start();
     325             :   Node* control = graph()->start();
     326           1 :   Node* context = UndefinedConstant();
     327           1 :   Node* frame_state = graph()->start();
     328             :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     329           1 :                                 context, frame_state, effect, control);
     330           1 :   Reduction r = Reduce(call);
     331             : 
     332           2 :   ASSERT_TRUE(r.Changed());
     333           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(V8_INFINITY));
     334             : }
     335             : 
     336       15189 : TEST_F(JSCallReducerTest, MathMinWithNumber) {
     337           2 :   Node* jsfunction = MathFunction("min");
     338           1 :   Node* effect = graph()->start();
     339             :   Node* control = graph()->start();
     340           1 :   Node* context = UndefinedConstant();
     341           1 :   Node* frame_state = graph()->start();
     342           1 :   Node* p0 = Parameter(Type::Any(), 0);
     343             :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     344           1 :                                 context, frame_state, effect, control);
     345           1 :   Reduction r = Reduce(call);
     346             : 
     347           2 :   ASSERT_TRUE(r.Changed());
     348           5 :   EXPECT_THAT(r.replacement(), IsSpeculativeToNumber(p0));
     349             : }
     350             : 
     351       15189 : TEST_F(JSCallReducerTest, MathMinWithTwoArguments) {
     352           2 :   Node* jsfunction = MathFunction("min");
     353           1 :   Node* effect = graph()->start();
     354             :   Node* control = graph()->start();
     355           1 :   Node* context = UndefinedConstant();
     356           1 :   Node* frame_state = graph()->start();
     357           1 :   Node* p0 = Parameter(Type::Any(), 0);
     358           1 :   Node* p1 = Parameter(Type::Any(), 1);
     359             :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     360           1 :                                 p1, context, frame_state, effect, control);
     361           1 :   Reduction r = Reduce(call);
     362             : 
     363           2 :   ASSERT_TRUE(r.Changed());
     364           8 :   EXPECT_THAT(r.replacement(), IsNumberMin(IsSpeculativeToNumber(p0),
     365           0 :                                            IsSpeculativeToNumber(p1)));
     366             : }
     367             : 
     368             : // -----------------------------------------------------------------------------
     369             : // Math.max
     370             : 
     371       15189 : TEST_F(JSCallReducerTest, MathMaxWithNoArguments) {
     372           2 :   Node* jsfunction = MathFunction("max");
     373             : 
     374           1 :   Node* effect = graph()->start();
     375             :   Node* control = graph()->start();
     376           1 :   Node* context = UndefinedConstant();
     377           1 :   Node* frame_state = graph()->start();
     378             :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     379           1 :                                 context, frame_state, effect, control);
     380           1 :   Reduction r = Reduce(call);
     381             : 
     382           2 :   ASSERT_TRUE(r.Changed());
     383           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
     384             : }
     385             : 
     386       15189 : TEST_F(JSCallReducerTest, MathMaxWithNumber) {
     387           2 :   Node* jsfunction = MathFunction("max");
     388           1 :   Node* effect = graph()->start();
     389             :   Node* control = graph()->start();
     390           1 :   Node* context = UndefinedConstant();
     391           1 :   Node* frame_state = graph()->start();
     392           1 :   Node* p0 = Parameter(Type::Any(), 0);
     393             :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     394           1 :                                 context, frame_state, effect, control);
     395           1 :   Reduction r = Reduce(call);
     396             : 
     397           2 :   ASSERT_TRUE(r.Changed());
     398           5 :   EXPECT_THAT(r.replacement(), IsSpeculativeToNumber(p0));
     399             : }
     400             : 
     401       15189 : TEST_F(JSCallReducerTest, MathMaxWithTwoArguments) {
     402           2 :   Node* jsfunction = MathFunction("max");
     403             : 
     404           1 :   Node* effect = graph()->start();
     405             :   Node* control = graph()->start();
     406           1 :   Node* context = UndefinedConstant();
     407           1 :   Node* frame_state = graph()->start();
     408           1 :   Node* p0 = Parameter(Type::Any(), 0);
     409           1 :   Node* p1 = Parameter(Type::Any(), 1);
     410             :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     411           1 :                                 p1, context, frame_state, effect, control);
     412           1 :   Reduction r = Reduce(call);
     413             : 
     414           2 :   ASSERT_TRUE(r.Changed());
     415           8 :   EXPECT_THAT(r.replacement(), IsNumberMax(IsSpeculativeToNumber(p0),
     416           0 :                                            IsSpeculativeToNumber(p1)));
     417             : }
     418             : 
     419             : // -----------------------------------------------------------------------------
     420             : // String.fromCharCode
     421             : 
     422       15189 : TEST_F(JSCallReducerTest, StringFromSingleCharCodeWithNumber) {
     423           1 :   Node* function = StringFunction("fromCharCode");
     424             : 
     425           1 :   Node* effect = graph()->start();
     426             :   Node* control = graph()->start();
     427           1 :   Node* context = UndefinedConstant();
     428           1 :   Node* frame_state = graph()->start();
     429           1 :   Node* p0 = Parameter(Type::Any(), 0);
     430             :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     431           1 :                                 context, frame_state, effect, control);
     432           1 :   Reduction r = Reduce(call);
     433             : 
     434           2 :   ASSERT_TRUE(r.Changed());
     435           6 :   EXPECT_THAT(r.replacement(),
     436           0 :               IsStringFromSingleCharCode(IsSpeculativeToNumber(p0)));
     437             : }
     438             : 
     439       15189 : TEST_F(JSCallReducerTest, StringFromSingleCharCodeWithPlainPrimitive) {
     440           1 :   Node* function = StringFunction("fromCharCode");
     441             : 
     442           1 :   Node* effect = graph()->start();
     443             :   Node* control = graph()->start();
     444           1 :   Node* context = UndefinedConstant();
     445           1 :   Node* frame_state = graph()->start();
     446           1 :   Node* p0 = Parameter(Type::PlainPrimitive(), 0);
     447             :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     448           1 :                                 context, frame_state, effect, control);
     449           1 :   Reduction r = Reduce(call);
     450             : 
     451           2 :   ASSERT_TRUE(r.Changed());
     452           6 :   EXPECT_THAT(r.replacement(),
     453           0 :               IsStringFromSingleCharCode(IsSpeculativeToNumber(p0)));
     454             : }
     455             : 
     456             : // -----------------------------------------------------------------------------
     457             : // Number.isFinite
     458             : 
     459       15189 : TEST_F(JSCallReducerTest, NumberIsFinite) {
     460           1 :   Node* function = NumberFunction("isFinite");
     461             : 
     462           1 :   Node* effect = graph()->start();
     463             :   Node* control = graph()->start();
     464           1 :   Node* context = UndefinedConstant();
     465           1 :   Node* frame_state = graph()->start();
     466           1 :   Node* p0 = Parameter(Type::Any(), 0);
     467             :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     468           1 :                                 context, frame_state, effect, control);
     469           1 :   Reduction r = Reduce(call);
     470             : 
     471           2 :   ASSERT_TRUE(r.Changed());
     472           5 :   EXPECT_THAT(r.replacement(), IsObjectIsFiniteNumber(p0));
     473             : }
     474             : 
     475             : // -----------------------------------------------------------------------------
     476             : // Number.isInteger
     477             : 
     478       15189 : TEST_F(JSCallReducerTest, NumberIsIntegerWithNumber) {
     479           1 :   Node* function = NumberFunction("isInteger");
     480             : 
     481           1 :   Node* effect = graph()->start();
     482             :   Node* control = graph()->start();
     483           1 :   Node* context = UndefinedConstant();
     484           1 :   Node* frame_state = graph()->start();
     485           1 :   Node* p0 = Parameter(Type::Any(), 0);
     486             :   Node* call =
     487             :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     488           3 :                        context, frame_state, effect, control);
     489           1 :   Reduction r = Reduce(call);
     490             : 
     491           2 :   ASSERT_TRUE(r.Changed());
     492           5 :   EXPECT_THAT(r.replacement(), IsObjectIsInteger(p0));
     493             : }
     494             : 
     495             : // -----------------------------------------------------------------------------
     496             : // Number.isNaN
     497             : 
     498       15189 : TEST_F(JSCallReducerTest, NumberIsNaNWithNumber) {
     499           1 :   Node* function = NumberFunction("isNaN");
     500             : 
     501           1 :   Node* effect = graph()->start();
     502             :   Node* control = graph()->start();
     503           1 :   Node* context = UndefinedConstant();
     504           1 :   Node* frame_state = graph()->start();
     505           1 :   Node* p0 = Parameter(Type::Any(), 0);
     506             :   Node* call =
     507             :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     508           3 :                        context, frame_state, effect, control);
     509           1 :   Reduction r = Reduce(call);
     510             : 
     511           2 :   ASSERT_TRUE(r.Changed());
     512           5 :   EXPECT_THAT(r.replacement(), IsObjectIsNaN(p0));
     513             : }
     514             : 
     515             : // -----------------------------------------------------------------------------
     516             : // Number.isSafeInteger
     517             : 
     518       15189 : TEST_F(JSCallReducerTest, NumberIsSafeIntegerWithIntegral32) {
     519           1 :   Node* function = NumberFunction("isSafeInteger");
     520             : 
     521           1 :   Node* effect = graph()->start();
     522             :   Node* control = graph()->start();
     523           1 :   Node* context = UndefinedConstant();
     524           1 :   Node* frame_state = graph()->start();
     525           1 :   Node* p0 = Parameter(Type::Any(), 0);
     526             :   Node* call =
     527             :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     528           3 :                        context, frame_state, effect, control);
     529           1 :   Reduction r = Reduce(call);
     530             : 
     531           2 :   ASSERT_TRUE(r.Changed());
     532           5 :   EXPECT_THAT(r.replacement(), IsObjectIsSafeInteger(p0));
     533             : }
     534             : 
     535             : // -----------------------------------------------------------------------------
     536             : // isFinite
     537             : 
     538       15189 : TEST_F(JSCallReducerTest, GlobalIsFiniteWithNumber) {
     539           1 :   Node* function = GlobalFunction("isFinite");
     540             : 
     541           1 :   Node* effect = graph()->start();
     542             :   Node* control = graph()->start();
     543           1 :   Node* context = UndefinedConstant();
     544           1 :   Node* frame_state = graph()->start();
     545           1 :   Node* p0 = Parameter(Type::Any(), 0);
     546             :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     547           1 :                                 context, frame_state, effect, control);
     548           1 :   Reduction r = Reduce(call);
     549             : 
     550           2 :   ASSERT_TRUE(r.Changed());
     551           6 :   EXPECT_THAT(r.replacement(), IsNumberIsFinite(IsSpeculativeToNumber(p0)));
     552             : }
     553             : 
     554             : // -----------------------------------------------------------------------------
     555             : // isNaN
     556             : 
     557       15189 : TEST_F(JSCallReducerTest, GlobalIsNaN) {
     558           1 :   Node* function = GlobalFunction("isNaN");
     559             : 
     560           1 :   Node* effect = graph()->start();
     561             :   Node* control = graph()->start();
     562           1 :   Node* context = UndefinedConstant();
     563           1 :   Node* frame_state = graph()->start();
     564           1 :   Node* p0 = Parameter(Type::Any(), 0);
     565             :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     566           1 :                                 context, frame_state, effect, control);
     567           1 :   Reduction r = Reduce(call);
     568             : 
     569           2 :   ASSERT_TRUE(r.Changed());
     570           6 :   EXPECT_THAT(r.replacement(), IsNumberIsNaN(IsSpeculativeToNumber(p0)));
     571             : }
     572             : 
     573             : // -----------------------------------------------------------------------------
     574             : // Number.parseInt
     575             : 
     576       15189 : TEST_F(JSCallReducerTest, NumberParseInt) {
     577           1 :   Node* function = NumberFunction("parseInt");
     578             : 
     579           1 :   Node* effect = graph()->start();
     580             :   Node* control = graph()->start();
     581           1 :   Node* context = UndefinedConstant();
     582           1 :   Node* frame_state = graph()->start();
     583           1 :   Node* p0 = Parameter(Type::Any(), 0);
     584           1 :   Node* p1 = Parameter(Type::Any(), 1);
     585             :   Node* call = graph()->NewNode(Call(4), function, UndefinedConstant(), p0, p1,
     586           1 :                                 context, frame_state, effect, control);
     587           1 :   Reduction r = Reduce(call);
     588             : 
     589           2 :   ASSERT_TRUE(r.Changed());
     590           6 :   EXPECT_THAT(r.replacement(), IsJSParseInt(p0, p1));
     591             : }
     592             : 
     593             : }  // namespace compiler
     594             : }  // namespace internal
     595        9111 : }  // namespace v8

Generated by: LCOV version 1.10