LibJS: Use new format functions everywhere

This changes the remaining uses of the following functions across LibJS:

- String::format() => String::formatted()
- dbg() => dbgln()
- printf() => out(), outln()
- fprintf() => warnln()

I also removed the relevant 'LogStream& operator<<' overloads as they're
not needed anymore.
This commit is contained in:
Linus Groh 2020-12-06 16:55:19 +00:00 committed by Andreas Kling
parent 2313e58393
commit 5eb1f752ab
Notes: sideshowbarker 2024-07-19 01:01:14 +09:00
15 changed files with 151 additions and 171 deletions

View File

@ -48,7 +48,6 @@
#include <LibJS/Runtime/Shape.h>
#include <LibJS/Runtime/StringObject.h>
#include <LibJS/Runtime/WithScope.h>
#include <stdio.h>
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("<empty>\n");
outln("<empty>");
}
}
}
@ -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);
}

View File

@ -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

View File

@ -118,10 +118,9 @@ void Heap::gather_roots(HashTable<Cell*>& 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<Cell*>& 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<Cell*>& 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<const Cell*>(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<Cell*>& 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<Cell*>& 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<HeapBlock*, 32> empty_blocks;
Vector<HeapBlock*, 32> 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;

View File

@ -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;

View File

@ -93,7 +93,7 @@ public:
{
int p = m_token_precedence[static_cast<size_t>(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;
}

View File

@ -24,7 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/LogStream.h>
#include <LibJS/Heap/Heap.h>
#include <LibJS/Heap/HeapBlock.h>
#include <LibJS/Runtime/Cell.h>
@ -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<const void*>(cell) << '}';
}
}

View File

@ -26,8 +26,10 @@
#pragma once
#include <AK/Format.h>
#include <AK/Forward.h>
#include <AK/Noncopyable.h>
#include <AK/String.h>
#include <LibJS/Forward.h>
namespace JS {
@ -70,6 +72,19 @@ private:
bool m_live { true };
};
const LogStream& operator<<(const LogStream&, const Cell*);
}
namespace AK {
template<>
struct Formatter<JS::Cell> : Formatter<StringView> {
void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Cell* cell)
{
if (!cell)
Formatter<StringView>::format(params, builder, "Cell{nullptr}");
else
Formatter<StringView>::format(params, builder, String::formatted("{}{{{}}}", cell->class_name(), static_cast<const void*>(cell)));
}
};
}

View File

@ -25,7 +25,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/LogStream.h>
#include <AK/Utf8View.h>
#include <LibJS/Console.h>
#include <LibJS/Heap/DeferGC.h>
@ -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();
}

View File

@ -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() ? "<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<TypeError>(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<TypeError>(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<TypeError>(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<TypeError>(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;
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
* 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 <LibJS/Runtime/PropertyAttributes.h>
namespace JS {
const LogStream& operator<<(const LogStream& stream, const PropertyAttributes& attributes)
{
return stream << attributes.bits();
}
}

View File

@ -26,7 +26,7 @@
#pragma once
#include <AK/LogStream.h>
#include <AK/Format.h>
#include <AK/Types.h>
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<JS::PropertyAttributes> : Formatter<u8> {
void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::PropertyAttributes& attributes)
{
Formatter<u8>::format(params, builder, attributes.bits());
}
};
}

View File

@ -98,6 +98,4 @@ private:
bool m_global_variable { false };
};
const LogStream& operator<<(const LogStream&, const Value&);
}

View File

@ -47,7 +47,7 @@ VM::VM()
{
m_empty_string = m_heap.allocate_without_global_object<PrimitiveString>(String::empty());
for (size_t i = 0; i < 128; ++i) {
m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object<PrimitiveString>(String::format("%c", i));
m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object<PrimitiveString>(String::formatted("{:c}", i));
}
m_scope_object_shape = m_heap.allocate_without_global_object<Shape>(Shape::ShapeWithoutGlobalObjectTag::Tag);

View File

@ -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<Object&>(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() ? "<empty>" : value.to_string_without_side_effects());
}
bool same_value(Value lhs, Value rhs)
{
if (lhs.type() != rhs.type())

View File

@ -27,8 +27,9 @@
#pragma once
#include <AK/Assertions.h>
#include <AK/Format.h>
#include <AK/Forward.h>
#include <AK/LogStream.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <LibJS/Forward.h>
#include <math.h>
@ -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<JS::Value> : Formatter<StringView> {
void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Value& value)
{
Formatter<StringView>::format(params, builder, value.is_empty() ? "<empty>" : value.to_string_without_side_effects());
}
};
}