diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 5543f04ea83..9d0a96af6a0 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -48,7 +48,6 @@ #include #include #include -#include namespace JS { @@ -823,14 +822,13 @@ Value ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& global_o static void print_indent(int indent) { - for (int i = 0; i < indent * 2; ++i) - putchar(' '); + out("{}", String::repeated(' ', indent * 2)); } void ASTNode::dump(int indent) const { print_indent(indent); - printf("%s\n", class_name()); + outln("{}", class_name()); } void ScopeNode::dump(int indent) const @@ -838,13 +836,13 @@ void ScopeNode::dump(int indent) const ASTNode::dump(indent); if (!m_variables.is_empty()) { print_indent(indent + 1); - printf("(Variables)\n"); + outln("(Variables)"); for (auto& variable : m_variables) variable.dump(indent + 2); } if (!m_children.is_empty()) { print_indent(indent + 1); - printf("(Children)\n"); + outln("(Children)"); for (auto& child : children()) child.dump(indent + 2); } @@ -923,10 +921,10 @@ void BinaryExpression::dump(int indent) const } print_indent(indent); - printf("%s\n", class_name()); + outln("{}", class_name()); m_lhs->dump(indent + 1); print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); m_rhs->dump(indent + 1); } @@ -946,10 +944,10 @@ void LogicalExpression::dump(int indent) const } print_indent(indent); - printf("%s\n", class_name()); + outln("{}", class_name()); m_lhs->dump(indent + 1); print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); m_rhs->dump(indent + 1); } @@ -981,16 +979,19 @@ void UnaryExpression::dump(int indent) const } print_indent(indent); - printf("%s\n", class_name()); + outln("{}", class_name()); print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); m_lhs->dump(indent + 1); } void CallExpression::dump(int indent) const { print_indent(indent); - printf("CallExpression %s\n", is_new_expression() ? "[new]" : ""); + if (is_new_expression()) + outln("CallExpression [new]"); + else + outln("CallExpression"); m_callee->dump(indent + 1); for (auto& argument : m_arguments) argument.value->dump(indent + 1); @@ -1005,21 +1006,20 @@ void ClassDeclaration::dump(int indent) const void ClassExpression::dump(int indent) const { print_indent(indent); - ASSERT(m_name.characters()); - printf("ClassExpression: \"%s\"\n", m_name.characters()); + outln("ClassExpression: \"{}\"", m_name); print_indent(indent); - printf("(Constructor)\n"); + outln("(Constructor)"); m_constructor->dump(indent + 1); if (!m_super_class.is_null()) { print_indent(indent); - printf("(Super Class)\n"); + outln("(Super Class)"); m_super_class->dump(indent + 1); } print_indent(indent); - printf("(Methods)\n"); + outln("(Methods)"); for (auto& method : m_methods) method.dump(indent + 1); } @@ -1029,7 +1029,7 @@ void ClassMethod::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("(Key)\n"); + outln("(Key)"); m_key->dump(indent + 1); const char* kind_string = nullptr; @@ -1045,78 +1045,78 @@ void ClassMethod::dump(int indent) const break; } print_indent(indent); - printf("Kind: %s\n", kind_string); + outln("Kind: {}", kind_string); print_indent(indent); - printf("Static: %s\n", m_is_static ? "true" : "false"); + outln("Static: {}", m_is_static); print_indent(indent); - printf("(Function)\n"); + outln("(Function)"); m_function->dump(indent + 1); } void StringLiteral::dump(int indent) const { print_indent(indent); - printf("StringLiteral \"%s\"\n", m_value.characters()); + outln("StringLiteral \"{}\"", m_value); } void SuperExpression::dump(int indent) const { print_indent(indent); - printf("super\n"); + outln("super"); } void NumericLiteral::dump(int indent) const { print_indent(indent); - printf("NumericLiteral %g\n", m_value); + outln("NumericLiteral {}", m_value); } void BigIntLiteral::dump(int indent) const { print_indent(indent); - printf("BigIntLiteral %s\n", m_value.characters()); + outln("BigIntLiteral {}", m_value); } void BooleanLiteral::dump(int indent) const { print_indent(indent); - printf("BooleanLiteral %s\n", m_value ? "true" : "false"); + outln("BooleanLiteral {}", m_value); } void NullLiteral::dump(int indent) const { print_indent(indent); - printf("null\n"); + outln("null"); } void FunctionNode::dump(int indent, const char* class_name) const { print_indent(indent); - printf("%s '%s'\n", class_name, name().characters()); + outln("{} '{}'", class_name, name()); if (!m_parameters.is_empty()) { print_indent(indent + 1); - printf("(Parameters)\n"); + outln("(Parameters)\n"); for (auto& parameter : m_parameters) { print_indent(indent + 2); if (parameter.is_rest) - printf("..."); - printf("%s\n", parameter.name.characters()); + out("..."); + outln("{}", parameter.name); if (parameter.default_value) parameter.default_value->dump(indent + 3); } } if (!m_variables.is_empty()) { print_indent(indent + 1); - printf("(Variables)\n"); + outln("(Variables)"); for (auto& variable : m_variables) variable.dump(indent + 2); } print_indent(indent + 1); - printf("(Body)\n"); + outln("(Body)"); body().dump(indent + 2); } @@ -1142,12 +1142,12 @@ void IfStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("If\n"); + outln("If"); predicate().dump(indent + 1); consequent().dump(indent + 1); if (alternate()) { print_indent(indent); - printf("Else\n"); + outln("Else"); alternate()->dump(indent + 1); } } @@ -1157,7 +1157,7 @@ void WhileStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("While\n"); + outln("While"); test().dump(indent + 1); body().dump(indent + 1); } @@ -1167,10 +1167,10 @@ void WithStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent + 1); - printf("Object\n"); + outln("Object"); object().dump(indent + 2); print_indent(indent + 1); - printf("Body\n"); + outln("Body"); body().dump(indent + 2); } @@ -1179,7 +1179,7 @@ void DoWhileStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("DoWhile\n"); + outln("DoWhile"); test().dump(indent + 1); body().dump(indent + 1); } @@ -1189,7 +1189,7 @@ void ForStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("For\n"); + outln("For"); if (init()) init()->dump(indent + 1); if (test()) @@ -1204,7 +1204,7 @@ void ForInStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("ForIn\n"); + outln("ForIn"); lhs().dump(indent + 1); rhs().dump(indent + 1); body().dump(indent + 1); @@ -1215,7 +1215,7 @@ void ForOfStatement::dump(int indent) const ASTNode::dump(indent); print_indent(indent); - printf("ForOf\n"); + outln("ForOf"); lhs().dump(indent + 1); rhs().dump(indent + 1); body().dump(indent + 1); @@ -1234,7 +1234,7 @@ Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object) void Identifier::dump(int indent) const { print_indent(indent); - printf("Identifier \"%s\"\n", m_string.characters()); + outln("Identifier \"{}\"", m_string); } void SpreadExpression::dump(int indent) const @@ -1465,7 +1465,7 @@ void AssignmentExpression::dump(int indent) const ASTNode::dump(indent); print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); m_lhs->dump(indent + 1); m_rhs->dump(indent + 1); } @@ -1485,12 +1485,12 @@ void UpdateExpression::dump(int indent) const ASTNode::dump(indent); if (m_prefixed) { print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); } m_argument->dump(indent + 1); if (!m_prefixed) { print_indent(indent + 1); - printf("%s\n", op_string); + outln("{}", op_string); } } @@ -1532,7 +1532,7 @@ void VariableDeclaration::dump(int indent) const ASTNode::dump(indent); print_indent(indent + 1); - printf("%s\n", declaration_kind_string); + outln("{}", declaration_kind_string); for (auto& declarator : m_declarations) declarator.dump(indent + 1); @@ -1645,7 +1645,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o void MemberExpression::dump(int indent) const { print_indent(indent); - printf("%s (computed=%s)\n", class_name(), is_computed() ? "true" : "false"); + outln("%{}(computed={})", class_name(), is_computed()); m_object->dump(indent + 1); m_property->dump(indent + 1); } @@ -1698,7 +1698,7 @@ void MetaProperty::dump(int indent) const else ASSERT_NOT_REACHED(); print_indent(indent); - printf("%s %s\n", class_name(), name.characters()); + outln("{} {}", class_name(), name); } Value MetaProperty::execute(Interpreter& interpreter, GlobalObject&) const @@ -1738,7 +1738,7 @@ Value NullLiteral::execute(Interpreter&, GlobalObject&) const void RegExpLiteral::dump(int indent) const { print_indent(indent); - printf("%s (/%s/%s)\n", class_name(), content().characters(), flags().characters()); + outln("{} (/{}/{})", class_name(), content(), flags()); } Value RegExpLiteral::execute(Interpreter&, GlobalObject& global_object) const @@ -1754,7 +1754,7 @@ void ArrayExpression::dump(int indent) const element->dump(indent + 1); } else { print_indent(indent + 1); - printf("\n"); + outln(""); } } } @@ -1812,10 +1812,10 @@ void TaggedTemplateLiteral::dump(int indent) const { ASTNode::dump(indent); print_indent(indent + 1); - printf("(Tag)\n"); + outln("(Tag)"); m_tag->dump(indent + 2); print_indent(indent + 1); - printf("(Template Literal)\n"); + outln("(Template Literal)"); m_template_literal->dump(indent + 2); } @@ -1862,18 +1862,18 @@ void TryStatement::dump(int indent) const { ASTNode::dump(indent); print_indent(indent); - printf("(Block)\n"); + outln("(Block)"); block().dump(indent + 1); if (handler()) { print_indent(indent); - printf("(Handler)\n"); + outln("(Handler)"); handler()->dump(indent + 1); } if (finalizer()) { print_indent(indent); - printf("(Finalizer)\n"); + outln("(Finalizer)"); finalizer()->dump(indent + 1); } } @@ -1881,10 +1881,10 @@ void TryStatement::dump(int indent) const void CatchClause::dump(int indent) const { print_indent(indent); - printf("CatchClause"); - if (!m_parameter.is_null()) - printf(" (%s)", m_parameter.characters()); - printf("\n"); + if (m_parameter.is_null()) + outln("CatchClause"); + else + outln("CatchClause ({})", m_parameter); body().dump(indent + 1); } @@ -2011,13 +2011,13 @@ void SwitchCase::dump(int indent) const ASTNode::dump(indent); print_indent(indent + 1); if (m_test) { - printf("(Test)\n"); + outln("(Test)"); m_test->dump(indent + 2); } else { - printf("(Default)\n"); + outln("(Default)"); } print_indent(indent + 1); - printf("(Consequent)\n"); + outln("(Consequent)"); for (auto& statement : m_consequent) statement.dump(indent + 2); } @@ -2042,13 +2042,13 @@ void ConditionalExpression::dump(int indent) const { ASTNode::dump(indent); print_indent(indent + 1); - printf("(Test)\n"); + outln("(Test)"); m_test->dump(indent + 2); print_indent(indent + 1); - printf("(Consequent)\n"); + outln("(Consequent)"); m_consequent->dump(indent + 2); print_indent(indent + 1); - printf("(Alternate)\n"); + outln("(Alternate)"); m_alternate->dump(indent + 2); } diff --git a/Libraries/LibJS/CMakeLists.txt b/Libraries/LibJS/CMakeLists.txt index 55edf67311c..5d149be98e8 100644 --- a/Libraries/LibJS/CMakeLists.txt +++ b/Libraries/LibJS/CMakeLists.txt @@ -55,7 +55,6 @@ set(SOURCES Runtime/Object.cpp Runtime/ObjectPrototype.cpp Runtime/PrimitiveString.cpp - Runtime/PropertyAttributes.cpp Runtime/ProxyConstructor.cpp Runtime/ProxyObject.cpp Runtime/Reference.cpp diff --git a/Libraries/LibJS/Heap/Heap.cpp b/Libraries/LibJS/Heap/Heap.cpp index c42e9b38f73..099daf4185e 100644 --- a/Libraries/LibJS/Heap/Heap.cpp +++ b/Libraries/LibJS/Heap/Heap.cpp @@ -118,10 +118,9 @@ void Heap::gather_roots(HashTable& roots) } #ifdef HEAP_DEBUG - dbg() << "gather_roots:"; - for (auto* root : roots) { - dbg() << " + " << root; - } + dbgln("gather_roots:"); + for (auto* root : roots) + dbgln(" + {}", root); #endif } @@ -130,7 +129,7 @@ void Heap::gather_conservative_roots(HashTable& roots) FlatPtr dummy; #ifdef HEAP_DEBUG - dbg() << "gather_conservative_roots:"; + dbgln("gather_conservative_roots:"); #endif jmp_buf buf; @@ -161,19 +160,19 @@ void Heap::gather_conservative_roots(HashTable& roots) if (!possible_pointer) continue; #ifdef HEAP_DEBUG - dbg() << " ? " << (const void*)possible_pointer; + dbgln(" ? {}", (const void*)possible_pointer); #endif auto* possible_heap_block = HeapBlock::from_cell(reinterpret_cast(possible_pointer)); if (all_live_heap_blocks.contains(possible_heap_block)) { if (auto* cell = possible_heap_block->cell_from_possible_pointer(possible_pointer)) { if (cell->is_live()) { #ifdef HEAP_DEBUG - dbg() << " ?-> " << (const void*)cell; + dbgln(" ?-> {}", (const void*)cell); #endif roots.set(cell); } else { #ifdef HEAP_DEBUG - dbg() << " #-> " << (const void*)cell; + dbgln(" #-> {}", (const void*)cell); #endif } } @@ -190,7 +189,7 @@ public: if (cell->is_marked()) return; #ifdef HEAP_DEBUG - dbg() << " ! " << cell; + dbgln(" ! {}", cell); #endif cell->set_marked(true); cell->visit_edges(*this); @@ -200,7 +199,7 @@ public: void Heap::mark_live_cells(const HashTable& roots) { #ifdef HEAP_DEBUG - dbg() << "mark_live_cells:"; + dbgln("mark_live_cells:"); #endif MarkingVisitor visitor; for (auto* root : roots) @@ -210,7 +209,7 @@ void Heap::mark_live_cells(const HashTable& roots) void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measurement_timer) { #ifdef HEAP_DEBUG - dbg() << "sweep_dead_cells:"; + dbgln("sweep_dead_cells:"); #endif Vector empty_blocks; Vector full_blocks_that_became_usable; @@ -227,7 +226,7 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure if (cell->is_live()) { if (!cell->is_marked()) { #ifdef HEAP_DEBUG - dbg() << " ~ " << cell; + dbgln(" ~ {}", cell); #endif block.deallocate(cell); ++collected_cells; @@ -249,21 +248,21 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure for (auto* block : empty_blocks) { #ifdef HEAP_DEBUG - dbg() << " - HeapBlock empty @ " << block << ": cell_size=" << block->cell_size(); + dbgln(" - HeapBlock empty @ {}: cell_size={}", block, block->cell_size()); #endif allocator_for_size(block->cell_size()).block_did_become_empty({}, *block); } for (auto* block : full_blocks_that_became_usable) { #ifdef HEAP_DEBUG - dbg() << " - HeapBlock usable again @ " << block << ": cell_size=" << block->cell_size(); + dbgln(" - HeapBlock usable again @ {}: cell_size={}", block, block->cell_size()); #endif allocator_for_size(block->cell_size()).block_did_become_usable({}, *block); } #ifdef HEAP_DEBUG for_each_block([&](auto& block) { - dbg() << " > Live HeapBlock @ " << &block << ": cell_size=" << block.cell_size(); + dbgln(" > Live HeapBlock @ {}: cell_size={}", &block, block.cell_size()); return IterationDecision::Continue; }); #endif @@ -271,7 +270,6 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure int time_spent = measurement_timer.elapsed(); if (print_report) { - size_t live_block_count = 0; for_each_block([&](auto&) { ++live_block_count; diff --git a/Libraries/LibJS/Lexer.cpp b/Libraries/LibJS/Lexer.cpp index 74af67b9ea3..047c5437e9d 100644 --- a/Libraries/LibJS/Lexer.cpp +++ b/Libraries/LibJS/Lexer.cpp @@ -181,7 +181,7 @@ void Lexer::consume() type = "LINE SEPARATOR"; else type = "PARAGRAPH SEPARATOR"; - dbg() << "Found a line terminator: " << type; + dbgln("Found a line terminator: {}", type); #endif // This is a three-char line terminator, we need to increase m_position some more. // We might reach EOF and need to check again. @@ -201,9 +201,9 @@ void Lexer::consume() m_line_number++; m_line_column = 1; #ifdef LEXER_DEBUG - dbg() << "Incremented line number, now at: line " << m_line_number << ", column 1"; + dbgln("Incremented line number, now at: line {}, column 1", m_line_number); } else { - dbg() << "Previous was CR, this is LF - not incrementing line number again."; + dbgln("Previous was CR, this is LF - not incrementing line number again."); #endif } } else { @@ -638,12 +638,12 @@ Token Lexer::next() value_start_column_number); #ifdef LEXER_DEBUG - dbg() << "------------------------------"; - dbg() << "Token: " << m_current_token.name(); - dbg() << "Trivia: _" << m_current_token.trivia() << "_"; - dbg() << "Value: _" << m_current_token.value() << "_"; - dbg() << "Line: " << m_current_token.line_number() << ", Column: " << m_current_token.line_column(); - dbg() << "------------------------------"; + dbgln("------------------------------"); + dbgln("Token: {}", m_current_token.name()); + dbgln("Trivia: _{}_", m_current_token.trivia()); + dbgln("Value: _{}_", m_current_token.value()); + dbgln("Line: {}, Column: {}", m_current_token.line_number(), m_current_token.line_column()); + dbgln("------------------------------"); #endif return m_current_token; diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 457e1890112..ca7b8abe9af 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -93,7 +93,7 @@ public: { int p = m_token_precedence[static_cast(token)]; if (p == 0) { - fprintf(stderr, "Internal Error: No precedence for operator %s\n", Token::name(token)); + warnln("Internal Error: No precedence for operator {}", Token::name(token)); ASSERT_NOT_REACHED(); return -1; } diff --git a/Libraries/LibJS/Runtime/Cell.cpp b/Libraries/LibJS/Runtime/Cell.cpp index 342085264fc..22a9979a35a 100644 --- a/Libraries/LibJS/Runtime/Cell.cpp +++ b/Libraries/LibJS/Runtime/Cell.cpp @@ -24,7 +24,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include @@ -56,11 +55,4 @@ VM& Cell::vm() const return heap().vm(); } -const LogStream& operator<<(const LogStream& stream, const Cell* cell) -{ - if (!cell) - return stream << "Cell{nullptr}"; - return stream << cell->class_name() << '{' << static_cast(cell) << '}'; -} - } diff --git a/Libraries/LibJS/Runtime/Cell.h b/Libraries/LibJS/Runtime/Cell.h index 97f555a7640..825887f24e7 100644 --- a/Libraries/LibJS/Runtime/Cell.h +++ b/Libraries/LibJS/Runtime/Cell.h @@ -26,8 +26,10 @@ #pragma once +#include #include #include +#include #include namespace JS { @@ -70,6 +72,19 @@ private: bool m_live { true }; }; -const LogStream& operator<<(const LogStream&, const Cell*); +} + +namespace AK { + +template<> +struct Formatter : Formatter { + void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Cell* cell) + { + if (!cell) + Formatter::format(params, builder, "Cell{nullptr}"); + else + Formatter::format(params, builder, String::formatted("{}{{{}}}", cell->class_name(), static_cast(cell))); + } +}; } diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index edba9ff2ff6..a51d353973e 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -25,7 +25,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include @@ -179,7 +178,7 @@ void GlobalObject::visit_edges(Visitor& visitor) JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc) { - dbg() << "Forced garbage collection requested!"; + dbgln("Forced garbage collection requested!"); vm.heap().collect_garbage(); return js_undefined(); } diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index e9631f76216..012ea4a0c20 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -198,11 +198,11 @@ Value Object::get_own_properties(const Object& this_object, PropertyKind kind, b if (kind == PropertyKind::Key) { properties_array->define_property(i, js_string(vm(), String::number(i))); } else if (kind == PropertyKind::Value) { - properties_array->define_property(i, js_string(vm(), String::format("%c", str[i]))); + properties_array->define_property(i, js_string(vm(), String::formatted("{:c}", str[i]))); } else { auto* entry_array = Array::create(global_object()); entry_array->define_property(0, js_string(vm(), String::number(i))); - entry_array->define_property(1, js_string(vm(), String::format("%c", str[i]))); + entry_array->define_property(1, js_string(vm(), String::formatted("{:c}", str[i]))); properties_array->define_property(i, entry_array); } if (vm().exception()) @@ -400,9 +400,7 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object& } #ifdef OBJECT_DEBUG - dbg() << "Defining new property " << property_name.to_display_string() << " with accessor descriptor { attributes=" << attributes << ", " - << "getter=" << getter.to_string_without_side_effects() << ", " - << "setter=" << setter.to_string_without_side_effects() << "}"; + dbgln("Defining new property {} with accessor descriptor {{ attributes={}, getter={}, setter={} }}", property_name.to_display_string(), attributes, getter, setter); #endif return define_property(property_name, Accessor::create(vm, getter_function, setter_function), attributes, throw_exceptions); @@ -422,8 +420,7 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object& return {}; #ifdef OBJECT_DEBUG - dbg() << "Defining new property " << property_name.to_display_string() << " with data descriptor { attributes=" << attributes - << ", value=" << (value.is_empty() ? "" : value.to_string_without_side_effects()) << " }"; + dbgln("Defining new property {} with data descriptor {{ attributes={}, value={} }}", property_name.to_display_string(), attributes, value); #endif return define_property(property_name, value, attributes, throw_exceptions); @@ -503,7 +500,7 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert if (!is_extensible() && new_property) { #ifdef OBJECT_DEBUG - dbg() << "Disallow define_property of non-extensible object"; + dbgln("Disallow define_property of non-extensible object"); #endif if (throw_exceptions && vm().in_strict_mode()) vm().throw_exception(global_object(), ErrorType::NonExtensibleDefine, property_name.to_display_string()); @@ -532,7 +529,7 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert if (!new_property && mode == PutOwnPropertyMode::DefineProperty && !metadata.value().attributes.is_configurable() && attributes != metadata.value().attributes) { #ifdef OBJECT_DEBUG - dbg() << "Disallow reconfig of non-configurable property"; + dbgln("Disallow reconfig of non-configurable property"); #endif if (throw_exceptions) vm().throw_exception(global_object(), ErrorType::DescChangeNonConfigurable, property_name.to_display_string()); @@ -548,14 +545,14 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert metadata = shape().lookup(property_name); #ifdef OBJECT_DEBUG - dbg() << "Reconfigured property " << property_name.to_display_string() << ", new shape says offset is " << metadata.value().offset << " and my storage capacity is " << m_storage.size(); + dbgln("Reconfigured property {}, new shape says offset is {} and my storage capacity is {}", property_name.to_display_string(), metadata.value().offset, m_storage.size()); #endif } auto value_here = m_storage[metadata.value().offset]; if (!new_property && mode == PutOwnPropertyMode::Put && !value_here.is_accessor() && !metadata.value().attributes.is_writable()) { #ifdef OBJECT_DEBUG - dbg() << "Disallow write to non-writable property"; + dbgln("Disallow write to non-writable property"); #endif return false; } @@ -580,7 +577,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index, if (!is_extensible() && new_property) { #ifdef OBJECT_DEBUG - dbg() << "Disallow define_property of non-extensible object"; + dbgln("Disallow define_property of non-extensible object"); #endif if (throw_exceptions && vm().in_strict_mode()) vm().throw_exception(global_object(), ErrorType::NonExtensibleDefine, property_index); @@ -599,7 +596,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index, if (!new_property && mode == PutOwnPropertyMode::DefineProperty && !existing_attributes.is_configurable() && attributes != existing_attributes) { #ifdef OBJECT_DEBUG - dbg() << "Disallow reconfig of non-configurable property"; + dbgln("Disallow reconfig of non-configurable property"); #endif if (throw_exceptions) vm().throw_exception(global_object(), ErrorType::DescChangeNonConfigurable, property_index); @@ -609,7 +606,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index, auto value_here = new_property ? Value() : existing_property.value().value; if (!new_property && mode == PutOwnPropertyMode::Put && !value_here.is_accessor() && !existing_attributes.is_writable()) { #ifdef OBJECT_DEBUG - dbg() << "Disallow write to non-writable property"; + dbgln("Disallow write to non-writable property"); #endif return false; } diff --git a/Libraries/LibJS/Runtime/PropertyAttributes.cpp b/Libraries/LibJS/Runtime/PropertyAttributes.cpp deleted file mode 100644 index 689c1b16531..00000000000 --- a/Libraries/LibJS/Runtime/PropertyAttributes.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020, Matthew Olsson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -namespace JS { - -const LogStream& operator<<(const LogStream& stream, const PropertyAttributes& attributes) -{ - return stream << attributes.bits(); -} - -} diff --git a/Libraries/LibJS/Runtime/PropertyAttributes.h b/Libraries/LibJS/Runtime/PropertyAttributes.h index d2fbe50ad78..44a33439472 100644 --- a/Libraries/LibJS/Runtime/PropertyAttributes.h +++ b/Libraries/LibJS/Runtime/PropertyAttributes.h @@ -26,7 +26,7 @@ #pragma once -#include +#include #include namespace JS { @@ -87,8 +87,18 @@ private: u8 m_bits; }; -const LogStream& operator<<(const LogStream& stream, const PropertyAttributes& attributes); - const PropertyAttributes default_attributes = Attribute::Configurable | Attribute::Writable | Attribute::Enumerable; } + +namespace AK { + +template<> +struct Formatter : Formatter { + void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::PropertyAttributes& attributes) + { + Formatter::format(params, builder, attributes.bits()); + } +}; + +} diff --git a/Libraries/LibJS/Runtime/Reference.h b/Libraries/LibJS/Runtime/Reference.h index 149bb31082c..c81d9644407 100644 --- a/Libraries/LibJS/Runtime/Reference.h +++ b/Libraries/LibJS/Runtime/Reference.h @@ -98,6 +98,4 @@ private: bool m_global_variable { false }; }; -const LogStream& operator<<(const LogStream&, const Value&); - } diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp index 75a966e1b21..29fad69f4b0 100644 --- a/Libraries/LibJS/Runtime/VM.cpp +++ b/Libraries/LibJS/Runtime/VM.cpp @@ -47,7 +47,7 @@ VM::VM() { m_empty_string = m_heap.allocate_without_global_object(String::empty()); for (size_t i = 0; i < 128; ++i) { - m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object(String::format("%c", i)); + m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object(String::formatted("{:c}", i)); } m_scope_object_shape = m_heap.allocate_without_global_object(Shape::ShapeWithoutGlobalObjectTag::Tag); diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index eb00a5116e9..4822aae8e55 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -118,7 +118,8 @@ String Value::to_string_without_side_effects() const return is_negative_infinity() ? "-Infinity" : "Infinity"; if (is_integer()) return String::number(as_i32()); - return String::format("%.4f", m_value.as_double); + // FIXME: This should be more sophisticated: don't cut off decimals, don't include trailing zeros + return String::formatted("{:.4}", m_value.as_double); case Type::String: return m_value.as_string->string(); case Type::Symbol: @@ -162,7 +163,8 @@ String Value::to_string(GlobalObject& global_object, bool legacy_null_to_empty_s return is_negative_infinity() ? "-Infinity" : "Infinity"; if (is_integer()) return String::number(as_i32()); - return String::format("%.4f", m_value.as_double); + // FIXME: This should be more sophisticated: don't cut off decimals, don't include trailing zeros + return String::formatted("{:.4}", m_value.as_double); case Type::String: return m_value.as_string->string(); case Type::Symbol: @@ -237,7 +239,7 @@ Object* Value::to_object(GlobalObject& global_object) const case Type::Object: return &const_cast(as_object()); default: - dbg() << "Dying because I can't to_object() on " << *this; + dbgln("Dying because I can't to_object() on {}", *this); ASSERT_NOT_REACHED(); } } @@ -822,11 +824,6 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) } } -const LogStream& operator<<(const LogStream& stream, const Value& value) -{ - return stream << (value.is_empty() ? "" : value.to_string_without_side_effects()); -} - bool same_value(Value lhs, Value rhs) { if (lhs.type() != rhs.type()) diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 6ad54f12d0f..1b0b9213263 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -27,8 +27,9 @@ #pragma once #include +#include #include -#include +#include #include #include #include @@ -337,6 +338,16 @@ bool same_value_non_numeric(Value lhs, Value rhs); TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs); size_t length_of_array_like(GlobalObject&, Value); -const LogStream& operator<<(const LogStream&, const Value&); +} + +namespace AK { + +template<> +struct Formatter : Formatter { + void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Value& value) + { + Formatter::format(params, builder, value.is_empty() ? "" : value.to_string_without_side_effects()); + } +}; }