11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-gen.h" 61cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h" 71cb0ef41Sopenharmony_ci#include "src/codegen/code-stub-assembler.h" 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cinamespace v8 { 101cb0ef41Sopenharmony_cinamespace internal { 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci// ES #sec-isfinite-number 131cb0ef41Sopenharmony_ciTF_BUILTIN(GlobalIsFinite, CodeStubAssembler) { 141cb0ef41Sopenharmony_ci auto context = Parameter<Context>(Descriptor::kContext); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci Label return_true(this), return_false(this); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci // We might need to loop once for ToNumber conversion. 191cb0ef41Sopenharmony_ci TVARIABLE(Object, var_num); 201cb0ef41Sopenharmony_ci Label loop(this, &var_num); 211cb0ef41Sopenharmony_ci var_num = Parameter<Object>(Descriptor::kNumber); 221cb0ef41Sopenharmony_ci Goto(&loop); 231cb0ef41Sopenharmony_ci BIND(&loop); 241cb0ef41Sopenharmony_ci { 251cb0ef41Sopenharmony_ci TNode<Object> num = var_num.value(); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci // Check if {num} is a Smi or a HeapObject. 281cb0ef41Sopenharmony_ci GotoIf(TaggedIsSmi(num), &return_true); 291cb0ef41Sopenharmony_ci TNode<HeapObject> num_heap_object = CAST(num); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci // Check if {num_heap_object} is a HeapNumber. 321cb0ef41Sopenharmony_ci Label if_numisheapnumber(this), 331cb0ef41Sopenharmony_ci if_numisnotheapnumber(this, Label::kDeferred); 341cb0ef41Sopenharmony_ci Branch(IsHeapNumber(num_heap_object), &if_numisheapnumber, 351cb0ef41Sopenharmony_ci &if_numisnotheapnumber); 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci BIND(&if_numisheapnumber); 381cb0ef41Sopenharmony_ci { 391cb0ef41Sopenharmony_ci // Check if {num_heap_object} contains a finite, non-NaN value. 401cb0ef41Sopenharmony_ci TNode<Float64T> num_value = LoadHeapNumberValue(num_heap_object); 411cb0ef41Sopenharmony_ci BranchIfFloat64IsNaN(Float64Sub(num_value, num_value), &return_false, 421cb0ef41Sopenharmony_ci &return_true); 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci BIND(&if_numisnotheapnumber); 461cb0ef41Sopenharmony_ci { 471cb0ef41Sopenharmony_ci // Need to convert {num_heap_object} to a Number first. 481cb0ef41Sopenharmony_ci var_num = 491cb0ef41Sopenharmony_ci CallBuiltin(Builtin::kNonNumberToNumber, context, num_heap_object); 501cb0ef41Sopenharmony_ci Goto(&loop); 511cb0ef41Sopenharmony_ci } 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci BIND(&return_true); 551cb0ef41Sopenharmony_ci Return(TrueConstant()); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci BIND(&return_false); 581cb0ef41Sopenharmony_ci Return(FalseConstant()); 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci// ES6 #sec-isnan-number 621cb0ef41Sopenharmony_ciTF_BUILTIN(GlobalIsNaN, CodeStubAssembler) { 631cb0ef41Sopenharmony_ci auto context = Parameter<Context>(Descriptor::kContext); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci Label return_true(this), return_false(this); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // We might need to loop once for ToNumber conversion. 681cb0ef41Sopenharmony_ci TVARIABLE(Object, var_num); 691cb0ef41Sopenharmony_ci Label loop(this, &var_num); 701cb0ef41Sopenharmony_ci var_num = Parameter<Object>(Descriptor::kNumber); 711cb0ef41Sopenharmony_ci Goto(&loop); 721cb0ef41Sopenharmony_ci BIND(&loop); 731cb0ef41Sopenharmony_ci { 741cb0ef41Sopenharmony_ci TNode<Object> num = var_num.value(); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // Check if {num} is a Smi or a HeapObject. 771cb0ef41Sopenharmony_ci GotoIf(TaggedIsSmi(num), &return_false); 781cb0ef41Sopenharmony_ci TNode<HeapObject> num_heap_object = CAST(num); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci // Check if {num_heap_object} is a HeapNumber. 811cb0ef41Sopenharmony_ci Label if_numisheapnumber(this), 821cb0ef41Sopenharmony_ci if_numisnotheapnumber(this, Label::kDeferred); 831cb0ef41Sopenharmony_ci Branch(IsHeapNumber(num_heap_object), &if_numisheapnumber, 841cb0ef41Sopenharmony_ci &if_numisnotheapnumber); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci BIND(&if_numisheapnumber); 871cb0ef41Sopenharmony_ci { 881cb0ef41Sopenharmony_ci // Check if {num_heap_object} contains a NaN. 891cb0ef41Sopenharmony_ci TNode<Float64T> num_value = LoadHeapNumberValue(num_heap_object); 901cb0ef41Sopenharmony_ci BranchIfFloat64IsNaN(num_value, &return_true, &return_false); 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci BIND(&if_numisnotheapnumber); 941cb0ef41Sopenharmony_ci { 951cb0ef41Sopenharmony_ci // Need to convert {num_heap_object} to a Number first. 961cb0ef41Sopenharmony_ci var_num = 971cb0ef41Sopenharmony_ci CallBuiltin(Builtin::kNonNumberToNumber, context, num_heap_object); 981cb0ef41Sopenharmony_ci Goto(&loop); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci BIND(&return_true); 1031cb0ef41Sopenharmony_ci Return(TrueConstant()); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci BIND(&return_false); 1061cb0ef41Sopenharmony_ci Return(FalseConstant()); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci} // namespace internal 1101cb0ef41Sopenharmony_ci} // namespace v8 111