5 #include "src/ast/ast.h" 10 #include "src/ast/prettyprinter.h" 11 #include "src/ast/scopes.h" 12 #include "src/base/hashmap.h" 13 #include "src/builtins/builtins-constructor.h" 14 #include "src/builtins/builtins.h" 15 #include "src/code-stubs.h" 16 #include "src/contexts.h" 17 #include "src/conversions-inl.h" 18 #include "src/double.h" 19 #include "src/elements.h" 20 #include "src/objects-inl.h" 21 #include "src/objects/literal-objects-inl.h" 22 #include "src/objects/literal-objects.h" 23 #include "src/objects/map.h" 24 #include "src/property-details.h" 25 #include "src/property.h" 26 #include "src/string-stream.h" 36 static const char* NameForNativeContextIntrinsicIndex(
uint32_t idx) {
38 #define NATIVE_CONTEXT_FIELDS_IDX(NAME, Type, name) \ 42 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELDS_IDX)
43 #undef NATIVE_CONTEXT_FIELDS_IDX 49 return "UnknownIntrinsicIndex";
52 void AstNode::Print() { Print(Isolate::Current()); }
54 void AstNode::Print(Isolate* isolate) {
55 AllowHandleDereference allow_deref;
56 AstPrinter::PrintOut(isolate,
this);
62 #define RETURN_NODE(Node) \ 64 return static_cast<Node*>(this); 66 IterationStatement* AstNode::AsIterationStatement() {
67 switch (node_type()) {
68 ITERATION_NODE_LIST(RETURN_NODE);
74 BreakableStatement* AstNode::AsBreakableStatement() {
75 switch (node_type()) {
76 BREAKABLE_NODE_LIST(RETURN_NODE);
77 ITERATION_NODE_LIST(RETURN_NODE);
83 MaterializedLiteral* AstNode::AsMaterializedLiteral() {
84 switch (node_type()) {
85 LITERAL_NODE_LIST(RETURN_NODE);
93 bool Expression::IsSmiLiteral()
const {
94 return IsLiteral() && AsLiteral()->type() == Literal::kSmi;
97 bool Expression::IsNumberLiteral()
const {
98 return IsLiteral() && AsLiteral()->IsNumber();
101 bool Expression::IsStringLiteral()
const {
102 return IsLiteral() && AsLiteral()->type() == Literal::kString;
105 bool Expression::IsPropertyName()
const {
106 return IsLiteral() && AsLiteral()->IsPropertyName();
109 bool Expression::IsNullLiteral()
const {
110 return IsLiteral() && AsLiteral()->type() == Literal::kNull;
113 bool Expression::IsTheHoleLiteral()
const {
114 return IsLiteral() && AsLiteral()->type() == Literal::kTheHole;
117 bool Expression::IsCompileTimeValue() {
118 if (IsLiteral())
return true;
119 MaterializedLiteral* literal = AsMaterializedLiteral();
120 if (literal ==
nullptr)
return false;
121 return literal->IsSimple();
124 bool Expression::IsUndefinedLiteral()
const {
125 if (IsLiteral() && AsLiteral()->type() == Literal::kUndefined)
return true;
127 const VariableProxy* var_proxy = AsVariableProxy();
128 if (var_proxy ==
nullptr)
return false;
129 Variable* var = var_proxy->var();
132 return var !=
nullptr && var->IsUnallocated() &&
133 var_proxy->raw_name()->IsOneByteEqualTo(
"undefined");
136 bool Expression::ToBooleanIsTrue()
const {
137 return IsLiteral() && AsLiteral()->ToBooleanIsTrue();
140 bool Expression::ToBooleanIsFalse()
const {
141 return IsLiteral() && AsLiteral()->ToBooleanIsFalse();
144 bool Expression::IsValidReferenceExpression()
const {
145 return IsProperty() ||
146 (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression());
149 bool Expression::IsAnonymousFunctionDefinition()
const {
150 return (IsFunctionLiteral() &&
151 AsFunctionLiteral()->IsAnonymousFunctionDefinition()) ||
153 AsClassLiteral()->IsAnonymousFunctionDefinition());
156 bool Expression::IsConciseMethodDefinition()
const {
157 return IsFunctionLiteral() && IsConciseMethod(AsFunctionLiteral()->kind());
160 bool Expression::IsAccessorFunctionDefinition()
const {
161 return IsFunctionLiteral() && IsAccessorFunction(AsFunctionLiteral()->kind());
164 bool Statement::IsJump()
const {
165 switch (node_type()) {
166 #define JUMP_NODE_LIST(V) \ 168 V(ExpressionStatement) \ 169 V(ContinueStatement) \ 173 #define GENERATE_CASE(Node) \ 175 return static_cast<const Node*>(this)->IsJump(); 176 JUMP_NODE_LIST(GENERATE_CASE)
178 #undef JUMP_NODE_LIST 184 VariableProxy::VariableProxy(Variable* var,
int start_position)
185 : Expression(start_position, kVariableProxy),
186 raw_name_(var->raw_name()),
187 next_unresolved_(nullptr) {
188 bit_field_ |= IsThisField::encode(var->is_this()) |
189 IsAssignedField::encode(
false) |
190 IsResolvedField::encode(
false) |
191 HoleCheckModeField::encode(HoleCheckMode::kElided);
195 VariableProxy::VariableProxy(
const VariableProxy* copy_from)
196 : Expression(copy_from->position(), kVariableProxy),
197 next_unresolved_(nullptr) {
198 bit_field_ = copy_from->bit_field_;
199 DCHECK(!copy_from->is_resolved());
200 raw_name_ = copy_from->raw_name_;
203 void VariableProxy::BindTo(Variable* var) {
204 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
208 if (is_assigned()) var->set_maybe_assigned();
211 Assignment::Assignment(NodeType node_type, Token::Value op, Expression* target,
212 Expression* value,
int pos)
213 : Expression(pos, node_type), target_(target), value_(value) {
214 bit_field_ |= TokenField::encode(op);
217 void FunctionLiteral::set_inferred_name(Handle<String> inferred_name) {
218 DCHECK(!inferred_name.is_null());
219 inferred_name_ = inferred_name;
220 DCHECK(raw_inferred_name_ ==
nullptr || raw_inferred_name_->IsEmpty());
221 raw_inferred_name_ =
nullptr;
222 scope()->set_has_inferred_function_name(
true);
225 void FunctionLiteral::set_raw_inferred_name(
226 const AstConsString* raw_inferred_name) {
227 DCHECK_NOT_NULL(raw_inferred_name);
228 raw_inferred_name_ = raw_inferred_name;
229 DCHECK(inferred_name_.is_null());
230 inferred_name_ = Handle<String>();
231 scope()->set_has_inferred_function_name(
true);
234 bool FunctionLiteral::ShouldEagerCompile()
const {
235 return scope()->ShouldEagerCompile();
238 void FunctionLiteral::SetShouldEagerCompile() {
239 scope()->set_should_eager_compile();
242 bool FunctionLiteral::AllowsLazyCompilation() {
243 return scope()->AllowsLazyCompilation();
246 Handle<String> FunctionLiteral::name(Isolate* isolate)
const {
247 return raw_name_ ? raw_name_->string() : isolate->factory()->empty_string();
250 int FunctionLiteral::start_position()
const {
251 return scope()->start_position();
255 int FunctionLiteral::end_position()
const {
256 return scope()->end_position();
260 LanguageMode FunctionLiteral::language_mode()
const {
261 return scope()->language_mode();
264 FunctionKind FunctionLiteral::kind()
const {
return scope()->function_kind(); }
266 bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
267 if (expr ==
nullptr || !expr->IsFunctionLiteral())
return false;
268 DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope());
269 return expr->AsFunctionLiteral()->scope()->NeedsHomeObject();
272 std::unique_ptr<char[]> FunctionLiteral::GetDebugName()
const {
273 const AstConsString* cons_string;
274 if (raw_name_ !=
nullptr && !raw_name_->IsEmpty()) {
275 cons_string = raw_name_;
276 }
else if (raw_inferred_name_ !=
nullptr && !raw_inferred_name_->IsEmpty()) {
277 cons_string = raw_inferred_name_;
278 }
else if (!inferred_name_.is_null()) {
279 AllowHandleDereference allow_deref;
280 return inferred_name_->ToCString();
282 char* empty_str =
new char[1];
284 return std::unique_ptr<char[]>(empty_str);
288 std::vector<char> result_vec;
289 std::forward_list<const AstRawString*> strings = cons_string->ToRawStrings();
290 for (
const AstRawString*
string : strings) {
291 if (!string->is_one_byte())
break;
292 for (
int i = 0;
i <
string->length();
i++) {
293 result_vec.push_back(string->raw_data()[
i]);
296 std::unique_ptr<char[]> result(
new char[result_vec.size() + 1]);
297 memcpy(result.get(), result_vec.data(), result_vec.size());
298 result[result_vec.size()] =
'\0';
302 ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
303 Kind kind,
bool is_computed_name)
304 : LiteralProperty(key, value, is_computed_name),
308 ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
309 Expression* key, Expression* value,
310 bool is_computed_name)
311 : LiteralProperty(key, value, is_computed_name), emit_store_(true) {
312 if (!is_computed_name && key->AsLiteral()->IsString() &&
313 key->AsLiteral()->AsRawString() == ast_value_factory->proto_string()) {
315 }
else if (value_->AsMaterializedLiteral() !=
nullptr) {
316 kind_ = MATERIALIZED_LITERAL;
317 }
else if (value_->IsLiteral()) {
324 bool LiteralProperty::NeedsSetFunctionName()
const {
325 return is_computed_name() && (value_->IsAnonymousFunctionDefinition() ||
326 value_->IsConciseMethodDefinition() ||
327 value_->IsAccessorFunctionDefinition());
330 ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value,
331 Kind kind,
bool is_static,
332 bool is_computed_name,
334 : LiteralProperty(key, value, is_computed_name),
336 is_static_(is_static),
337 is_private_(is_private),
338 private_or_computed_name_var_(nullptr) {}
340 bool ObjectLiteral::Property::IsCompileTimeValue()
const {
341 return kind_ == CONSTANT ||
342 (kind_ == MATERIALIZED_LITERAL && value_->IsCompileTimeValue());
346 void ObjectLiteral::Property::set_emit_store(
bool emit_store) {
347 emit_store_ = emit_store;
350 bool ObjectLiteral::Property::emit_store()
const {
return emit_store_; }
352 void ObjectLiteral::CalculateEmitStore(Zone* zone) {
353 const auto GETTER = ObjectLiteral::Property::GETTER;
354 const auto SETTER = ObjectLiteral::Property::SETTER;
356 ZoneAllocationPolicy allocator(zone);
358 CustomMatcherZoneHashMap table(
359 Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, allocator);
360 for (
int i = properties()->length() - 1;
i >= 0;
i--) {
361 ObjectLiteral::Property*
property = properties()->at(
i);
362 if (property->is_computed_name())
continue;
363 if (property->IsPrototype())
continue;
364 Literal* literal =
property->key()->AsLiteral();
365 DCHECK(!literal->IsNullLiteral());
368 ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator);
369 if (entry->value ==
nullptr) {
370 entry->value = property;
387 static_cast<ObjectLiteral::Property*
>(entry->value)->kind();
388 bool complementary_accessors =
389 (
property->kind() == GETTER && later_kind == SETTER) ||
390 (property->kind() == SETTER && later_kind == GETTER);
391 if (!complementary_accessors) {
392 property->set_emit_store(
false);
393 if (later_kind == GETTER || later_kind == SETTER) {
394 entry->value = property;
401 void ObjectLiteral::InitFlagsForPendingNullPrototype(
int i) {
403 for (;
i < properties()->length();
i++) {
404 if (properties()->at(
i)->IsNullPrototype()) {
405 set_has_null_protoype(
true);
411 int ObjectLiteral::InitDepthAndFlags() {
412 if (is_initialized())
return depth();
413 bool is_simple =
true;
414 bool has_seen_prototype =
false;
415 bool needs_initial_allocation_site =
false;
420 for (
int i = 0;
i < properties()->length();
i++) {
421 ObjectLiteral::Property*
property = properties()->at(
i);
422 if (property->IsPrototype()) {
423 has_seen_prototype =
true;
426 if (property->IsNullPrototype()) {
427 set_has_null_protoype(
true);
430 DCHECK(!has_null_prototype());
434 if (nof_properties == boilerplate_properties_) {
435 DCHECK(property->is_computed_name());
437 if (!has_seen_prototype) InitFlagsForPendingNullPrototype(
i);
440 DCHECK(!property->is_computed_name());
442 MaterializedLiteral* literal =
property->value()->AsMaterializedLiteral();
443 if (literal !=
nullptr) {
444 int subliteral_depth = literal->InitDepthAndFlags() + 1;
445 if (subliteral_depth > depth_acc) depth_acc = subliteral_depth;
446 needs_initial_allocation_site |= literal->NeedsInitialAllocationSite();
449 Literal* key =
property->key()->AsLiteral();
450 Expression* value =
property->value();
452 bool is_compile_time_value = value->IsCompileTimeValue();
453 is_simple = is_simple && is_compile_time_value;
460 if (key->AsArrayIndex(&element_index)) {
461 max_element_index = Max(element_index, max_element_index);
464 DCHECK(key->IsPropertyName());
470 set_depth(depth_acc);
471 set_is_simple(is_simple);
472 set_needs_initial_allocation_site(needs_initial_allocation_site);
473 set_has_elements(elements > 0);
474 set_fast_elements((max_element_index <= 32) ||
475 ((2 * elements) >= max_element_index));
479 void ObjectLiteral::BuildBoilerplateDescription(Isolate* isolate) {
480 if (!boilerplate_description_.is_null())
return;
483 bool has_seen_proto =
false;
484 for (
int i = 0;
i < properties()->length();
i++) {
485 ObjectLiteral::Property*
property = properties()->at(
i);
486 if (property->IsPrototype()) {
487 has_seen_proto =
true;
490 if (property->is_computed_name()) {
494 Literal* key =
property->key()->AsLiteral();
496 if (!key->IsPropertyName()) {
501 Handle<ObjectBoilerplateDescription> boilerplate_description =
502 isolate->factory()->NewObjectBoilerplateDescription(
503 boilerplate_properties_, properties()->length(), index_keys,
507 for (
int i = 0;
i < properties()->length();
i++) {
508 ObjectLiteral::Property*
property = properties()->at(
i);
509 if (property->IsPrototype())
continue;
511 if (static_cast<uint32_t>(position) == boilerplate_properties_) {
512 DCHECK(property->is_computed_name());
515 DCHECK(!property->is_computed_name());
517 MaterializedLiteral* m_literal =
property->value()->AsMaterializedLiteral();
518 if (m_literal !=
nullptr) {
519 m_literal->BuildConstants(isolate);
525 Literal* key_literal =
property->key()->AsLiteral();
528 key_literal->AsArrayIndex(&element_index)
529 ? isolate->factory()->NewNumberFromUint(element_index)
530 : Handle<Object>::cast(key_literal->AsRawPropertyName()->string());
532 Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
535 boilerplate_description->set_key_value(position++, *key, *value);
538 boilerplate_description->set_flags(EncodeLiteralType());
540 boilerplate_description_ = boilerplate_description;
543 bool ObjectLiteral::IsFastCloningSupported()
const {
547 return fast_elements() && is_shallow() &&
548 properties_count() <=
549 ConstructorBuiltins::kMaximumClonedShallowObjectProperties;
552 int ArrayLiteral::InitDepthAndFlags() {
553 if (is_initialized())
return depth();
555 int constants_length =
556 first_spread_index_ >= 0 ? first_spread_index_ : values()->length();
559 bool is_simple = first_spread_index_ < 0;
562 for (; array_index < constants_length; array_index++) {
563 Expression* element = values()->at(array_index);
564 MaterializedLiteral* literal = element->AsMaterializedLiteral();
565 if (literal !=
nullptr) {
566 int subliteral_depth = literal->InitDepthAndFlags() + 1;
567 if (subliteral_depth > depth_acc) depth_acc = subliteral_depth;
570 if (!element->IsCompileTimeValue()) {
575 set_depth(depth_acc);
576 set_is_simple(is_simple);
579 set_needs_initial_allocation_site(
true);
583 void ArrayLiteral::BuildBoilerplateDescription(Isolate* isolate) {
584 if (!boilerplate_description_.is_null())
return;
586 int constants_length =
587 first_spread_index_ >= 0 ? first_spread_index_ : values()->length();
588 ElementsKind kind = FIRST_FAST_ELEMENTS_KIND;
589 Handle<FixedArray> fixed_array =
590 isolate->factory()->NewFixedArrayWithHoles(constants_length);
593 bool is_holey =
false;
595 for (; array_index < constants_length; array_index++) {
596 Expression* element = values()->at(array_index);
597 DCHECK(!element->IsSpread());
598 MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
599 if (m_literal !=
nullptr) {
600 m_literal->BuildConstants(isolate);
604 HandleScope scope(isolate);
605 Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate);
606 if (boilerplate_value->IsTheHole(isolate)) {
611 if (boilerplate_value->IsUninitialized(isolate)) {
612 boilerplate_value = handle(Smi::kZero, isolate);
615 kind = GetMoreGeneralElementsKind(kind,
616 boilerplate_value->OptimalElementsKind());
617 fixed_array->set(array_index, *boilerplate_value);
620 if (is_holey) kind = GetHoleyElementsKind(kind);
624 if (is_simple() && depth() == 1 && array_index > 0 &&
625 IsSmiOrObjectElementsKind(kind)) {
626 fixed_array->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
629 Handle<FixedArrayBase> elements = fixed_array;
630 if (IsDoubleElementsKind(kind)) {
631 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
632 elements = isolate->factory()->NewFixedDoubleArray(constants_length);
634 ElementsKind from_kind = TERMINAL_FAST_ELEMENTS_KIND;
635 accessor->CopyElements(isolate, fixed_array, from_kind, elements,
639 boilerplate_description_ =
640 isolate->factory()->NewArrayBoilerplateDescription(kind, elements);
643 bool ArrayLiteral::IsFastCloningSupported()
const {
644 return depth() <= 1 &&
646 ConstructorBuiltins::kMaximumClonedShallowArrayElements;
649 bool MaterializedLiteral::IsSimple()
const {
650 if (IsArrayLiteral())
return AsArrayLiteral()->is_simple();
651 if (IsObjectLiteral())
return AsObjectLiteral()->is_simple();
652 DCHECK(IsRegExpLiteral());
656 Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
658 if (expression->IsLiteral()) {
659 return expression->AsLiteral()->BuildValue(isolate);
661 if (expression->IsCompileTimeValue()) {
662 if (expression->IsObjectLiteral()) {
663 ObjectLiteral* object_literal = expression->AsObjectLiteral();
664 DCHECK(object_literal->is_simple());
665 return object_literal->boilerplate_description();
667 DCHECK(expression->IsArrayLiteral());
668 ArrayLiteral* array_literal = expression->AsArrayLiteral();
669 DCHECK(array_literal->is_simple());
670 return array_literal->boilerplate_description();
673 return isolate->factory()->uninitialized_value();
676 int MaterializedLiteral::InitDepthAndFlags() {
677 if (IsArrayLiteral())
return AsArrayLiteral()->InitDepthAndFlags();
678 if (IsObjectLiteral())
return AsObjectLiteral()->InitDepthAndFlags();
679 DCHECK(IsRegExpLiteral());
683 bool MaterializedLiteral::NeedsInitialAllocationSite() {
684 if (IsArrayLiteral()) {
685 return AsArrayLiteral()->needs_initial_allocation_site();
687 if (IsObjectLiteral()) {
688 return AsObjectLiteral()->needs_initial_allocation_site();
690 DCHECK(IsRegExpLiteral());
694 void MaterializedLiteral::BuildConstants(Isolate* isolate) {
695 if (IsArrayLiteral()) {
696 AsArrayLiteral()->BuildBoilerplateDescription(isolate);
699 if (IsObjectLiteral()) {
700 AsObjectLiteral()->BuildBoilerplateDescription(isolate);
703 DCHECK(IsRegExpLiteral());
706 Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription(
708 Handle<FixedArray> raw_strings =
709 isolate->factory()->NewFixedArray(this->raw_strings()->length(), TENURED);
710 bool raw_and_cooked_match =
true;
711 for (
int i = 0;
i < raw_strings->length(); ++
i) {
712 if (this->cooked_strings()->at(
i) ==
nullptr ||
713 *this->raw_strings()->at(
i)->string() !=
714 *this->cooked_strings()->at(
i)->string()) {
715 raw_and_cooked_match =
false;
717 raw_strings->set(
i, *this->raw_strings()->at(
i)->
string());
719 Handle<FixedArray> cooked_strings = raw_strings;
720 if (!raw_and_cooked_match) {
721 cooked_strings = isolate->factory()->NewFixedArray(
722 this->cooked_strings()->length(), TENURED);
723 for (
int i = 0;
i < cooked_strings->length(); ++
i) {
724 if (this->cooked_strings()->at(
i) !=
nullptr) {
725 cooked_strings->set(
i, *this->cooked_strings()->at(
i)->
string());
727 cooked_strings->set(
i, ReadOnlyRoots(isolate).undefined_value());
731 return isolate->factory()->NewTemplateObjectDescription(raw_strings,
735 static bool IsCommutativeOperationWithSmiLiteral(Token::Value op) {
737 return op == Token::MUL || op == Token::BIT_AND || op == Token::BIT_OR ||
738 op == Token::BIT_XOR;
742 static bool MatchSmiLiteralOperation(Expression* left, Expression* right,
743 Expression** expr, Smi* literal) {
744 if (right->IsSmiLiteral()) {
746 *literal = right->AsLiteral()->AsSmiLiteral();
752 bool BinaryOperation::IsSmiLiteralOperation(Expression** subexpr,
754 return MatchSmiLiteralOperation(left_, right_, subexpr, literal) ||
755 (IsCommutativeOperationWithSmiLiteral(op()) &&
756 MatchSmiLiteralOperation(right_, left_, subexpr, literal));
759 static bool IsTypeof(Expression* expr) {
760 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
761 return maybe_unary !=
nullptr && maybe_unary->op() == Token::TYPEOF;
765 static bool MatchLiteralCompareTypeof(Expression* left, Token::Value op,
766 Expression* right, Expression** expr,
768 if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
769 *expr = left->AsUnaryOperation()->expression();
770 *literal = right->AsLiteral();
776 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
778 return MatchLiteralCompareTypeof(left_, op(), right_, expr, literal) ||
779 MatchLiteralCompareTypeof(right_, op(), left_, expr, literal);
783 static bool IsVoidOfLiteral(Expression* expr) {
784 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
785 return maybe_unary !=
nullptr && maybe_unary->op() == Token::VOID &&
786 maybe_unary->expression()->IsLiteral();
792 static bool MatchLiteralCompareUndefined(Expression* left,
796 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
800 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) {
807 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
808 return MatchLiteralCompareUndefined(left_, op(), right_, expr) ||
809 MatchLiteralCompareUndefined(right_, op(), left_, expr);
813 static bool MatchLiteralCompareNull(Expression* left,
817 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
824 bool CompareOperation::IsLiteralCompareNull(Expression** expr) {
825 return MatchLiteralCompareNull(left_, op(), right_, expr) ||
826 MatchLiteralCompareNull(right_, op(), left_, expr);
829 Call::CallType Call::GetCallType()
const {
830 VariableProxy* proxy = expression()->AsVariableProxy();
831 if (proxy !=
nullptr) {
832 if (proxy->var()->IsUnallocated()) {
834 }
else if (proxy->var()->IsLookupSlot()) {
837 return proxy->var()->mode() == VariableMode::kDynamic ? WITH_CALL
842 if (expression()->IsSuperCallReference())
return SUPER_CALL;
844 Property*
property = expression()->AsProperty();
845 if (property !=
nullptr) {
846 bool is_super =
property->IsSuperAccess();
847 if (property->key()->IsPropertyName()) {
848 return is_super ? NAMED_SUPER_PROPERTY_CALL : NAMED_PROPERTY_CALL;
850 return is_super ? KEYED_SUPER_PROPERTY_CALL : KEYED_PROPERTY_CALL;
854 if (expression()->IsResolvedProperty()) {
855 return RESOLVED_PROPERTY_CALL;
861 CaseClause::CaseClause(Zone* zone, Expression* label,
862 const ScopedPtrList<Statement>& statements)
863 : label_(label), statements_(0, nullptr) {
864 statements.CopyTo(&statements_, zone);
867 bool Literal::IsPropertyName()
const {
868 if (type() != kString)
return false;
870 return !string_->AsArrayIndex(&index);
873 bool Literal::ToUint32(
uint32_t* value)
const {
876 return string_->AsArrayIndex(value);
878 if (smi_ < 0)
return false;
879 *value =
static_cast<uint32_t>(smi_);
882 return DoubleToUint32IfEqualToSelf(AsNumber(), value);
888 bool Literal::AsArrayIndex(
uint32_t* value)
const {
889 return ToUint32(value) && *value != kMaxUInt32;
892 Handle<Object> Literal::BuildValue(Isolate* isolate)
const {
895 return handle(Smi::FromInt(smi_), isolate);
897 return isolate->factory()->NewNumber(number_, TENURED);
899 return string_->string();
901 return isolate->factory()->home_object_symbol();
903 return isolate->factory()->ToBoolean(boolean_);
905 return isolate->factory()->null_value();
907 return isolate->factory()->undefined_value();
909 return isolate->factory()->the_hole_value();
913 return BigIntLiteral(isolate, bigint_.c_str()).ToHandleChecked();
918 bool Literal::ToBooleanIsTrue()
const {
923 return DoubleToBoolean(number_);
925 return !string_->IsEmpty();
932 const char* bigint_str = bigint_.c_str();
933 size_t length = strlen(bigint_str);
934 DCHECK_GT(length, 0);
935 if (length == 1 && bigint_str[0] ==
'0')
return false;
938 for (
size_t i = (bigint_str[0] ==
'0') ? 2 : 0;
i < length; ++
i) {
939 if (bigint_str[
i] !=
'0')
return true;
952 return IsString() ? AsRawString()->Hash()
953 : ComputeLongHash(double_to_uint64(AsNumber()));
958 bool Literal::Match(
void* a,
void* b) {
959 Literal* x =
static_cast<Literal*
>(a);
960 Literal* y =
static_cast<Literal*
>(b);
961 return (x->IsString() && y->IsString() &&
962 x->AsRawString() == y->AsRawString()) ||
963 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
966 Literal* AstNodeFactory::NewNumberLiteral(
double number,
int pos) {
968 if (DoubleToSmiInteger(number, &int_value)) {
969 return NewSmiLiteral(int_value, pos);
971 return new (zone_) Literal(number, pos);
974 const char* CallRuntime::debug_name() {
976 return is_jsruntime() ? NameForNativeContextIntrinsicIndex(context_index_)
979 return is_jsruntime() ?
"(context function)" : function_->name;
983 #define RETURN_LABELS(NodeType) \ 985 return static_cast<const NodeType*>(this)->labels(); 987 ZonePtrList<const AstRawString>* BreakableStatement::labels()
const {
988 switch (node_type()) {
989 BREAKABLE_NODE_LIST(RETURN_LABELS)
990 ITERATION_NODE_LIST(RETURN_LABELS)