Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 34 additions & 21 deletions src/debug_utils-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,42 @@ std::string ToBaseString(const T& value) {
return ToStringHelper::BaseConvert<BASE_BITS>(value);
}

inline std::string SPrintFImpl(const char* format) {
const char* p = strchr(format, '%');
if (p == nullptr) [[unlikely]]
return format;
CHECK_EQ(p[1], '%'); // Only '%%' allowed when there are no arguments.
inline std::string SPrintFImpl(std::string_view format) {
auto offset = format.find('%');
if (offset == std::string_view::npos) return std::string(format);
CHECK_LT(offset + 1, format.size());
CHECK_EQ(format[offset + 1],
'%'); // Only '%%' allowed when there are no arguments.

return std::string(format, p + 1) + SPrintFImpl(p + 2);
return std::string(format.substr(0, offset + 1)) +
SPrintFImpl(format.substr(offset + 2));
}

template <typename Arg, typename... Args>
std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
const char* format, Arg&& arg, Args&&... args) {
const char* p = strchr(format, '%');
CHECK_NOT_NULL(p); // If you hit this, you passed in too many arguments.
std::string ret(format, p);
std::string_view format,
Arg&& arg,
Args&&... args) {
auto offset = format.find('%');
CHECK_NE(offset, std::string_view::npos); // If you hit this, you passed in
// too many arguments.
std::string ret(format.substr(0, offset));
// Ignore long / size_t modifiers
while (strchr("lz", *++p) != nullptr) {}
switch (*p) {
while (++offset < format.size() &&
(format[offset] == 'l' || format[offset] == 'z')) {
}
switch (offset == format.size() ? '\0' : format[offset]) {
case '%': {
return ret + '%' + SPrintFImpl(p + 1,
std::forward<Arg>(arg),
std::forward<Args>(args)...);
return ret + '%' +
SPrintFImpl(format.substr(offset + 1),
std::forward<Arg>(arg),
std::forward<Args>(args)...);
}
default: {
return ret + '%' + SPrintFImpl(p,
std::forward<Arg>(arg),
std::forward<Args>(args)...);
return ret + '%' +
SPrintFImpl(format.substr(offset),
std::forward<Arg>(arg),
std::forward<Args>(args)...);
}
case 'd':
case 'i':
Expand Down Expand Up @@ -120,17 +129,21 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
break;
}
}
return ret + SPrintFImpl(p + 1, std::forward<Args>(args)...);
return ret +
SPrintFImpl(format.substr(offset + 1), std::forward<Args>(args)...);
}

template <typename... Args>
std::string COLD_NOINLINE SPrintF( // NOLINT(runtime/string)
const char* format, Args&&... args) {
std::string_view format,
Args&&... args) {
return SPrintFImpl(format, std::forward<Args>(args)...);
}

template <typename... Args>
void COLD_NOINLINE FPrintF(FILE* file, const char* format, Args&&... args) {
void COLD_NOINLINE FPrintF(FILE* file,
std::string_view format,
Args&&... args) {
FWrite(file, SPrintF(format, std::forward<Args>(args)...));
}

Expand Down
4 changes: 2 additions & 2 deletions src/debug_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ inline std::string ToString(const T& value);
// - Supports %p and %s. %d, %i and %u are aliases for %s.
// - Accepts any class that has a ToString() method for stringification.
template <typename... Args>
inline std::string SPrintF(const char* format, Args&&... args);
inline std::string SPrintF(std::string_view format, Args&&... args);
template <typename... Args>
inline void FPrintF(FILE* file, const char* format, Args&&... args);
inline void FPrintF(FILE* file, std::string_view format, Args&&... args);
void NODE_EXTERN_PRIVATE FWrite(FILE* file, const std::string& str);

// Listing the AsyncWrap provider types first enables us to cast directly
Expand Down
17 changes: 8 additions & 9 deletions src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details);
#define V(code, type) \
template <typename... Args> \
inline v8::Local<v8::Object> code( \
v8::Isolate* isolate, const char* format, Args&&... args) { \
v8::Isolate* isolate, std::string_view format, Args&&... args) { \
std::string message; \
if (sizeof...(Args) == 0) { \
message = format; \
Expand All @@ -165,17 +165,18 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details);
} \
template <typename... Args> \
inline void THROW_##code( \
v8::Isolate* isolate, const char* format, Args&&... args) { \
v8::Isolate* isolate, std::string_view format, Args&&... args) { \
isolate->ThrowException( \
code(isolate, format, std::forward<Args>(args)...)); \
} \
template <typename... Args> \
inline void THROW_##code( \
Environment* env, const char* format, Args&&... args) { \
Environment* env, std::string_view format, Args&&... args) { \
THROW_##code(env->isolate(), format, std::forward<Args>(args)...); \
} \
template <typename... Args> \
inline void THROW_##code(Realm* realm, const char* format, Args&&... args) { \
inline void THROW_##code( \
Realm* realm, std::string_view format, Args&&... args) { \
THROW_##code(realm->isolate(), format, std::forward<Args>(args)...); \
}
ERRORS_WITH_CODE(V)
Expand Down Expand Up @@ -258,10 +259,8 @@ PREDEFINED_ERROR_MESSAGES(V)
// Errors with predefined non-static messages
inline void THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(Environment* env,
int64_t timeout) {
std::ostringstream message;
message << "Script execution timed out after ";
message << timeout << "ms";
THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, message.str().c_str());
THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(
env, "Script execution timed out after %dms", timeout);
}

inline void THROW_ERR_REQUIRE_ASYNC_MODULE(
Expand All @@ -283,7 +282,7 @@ inline void THROW_ERR_REQUIRE_ASYNC_MODULE(
message += "\n Requiring ";
message += +utf8.out();
}
THROW_ERR_REQUIRE_ASYNC_MODULE(env, message.c_str());
THROW_ERR_REQUIRE_ASYNC_MODULE(env, message);
}

inline v8::Local<v8::Object> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
Expand Down
Loading