mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm] Create a common base class for TextBuffer/ZoneTextBuffer.
Generally, methods that take a *TextBuffer pointer do not care how the internal buffer is allocated, and so they could be used for either if both were subclasses of a base class that contained the printing methods. This CL makes that base class, and now TextBuffer and ZoneTextBuffer now share the exact same set of methods for printing to the internal buffer. Since the base class is in platform, this does mean dropping the overload of AddString for Dart String objects that was part of ZoneTextBuffer. Instead, this CL just adds an intermediate call to ToCString() for the small number of callers that used the overload, keeping the printing interface the same for both. In addition, one use of TextBuffer that then re-allocated the buffer contents into the zone manually has been replaced with a ZoneTextBuffer instead. Change-Id: I438a085e7e20d55d93987fd7f36afd636f95955f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/157741 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
parent
e51623f81a
commit
fa03ee7782
|
@ -608,7 +608,7 @@ static void WriteLoadingUnitManifest(File* manifest_file,
|
|||
line.Printf("{ \"id\": %" Pd ", \"path\": \"", id);
|
||||
line.AddEscapedString(path);
|
||||
line.Printf("\" }");
|
||||
if (!manifest_file->Print("%s\n", line.buf())) {
|
||||
if (!manifest_file->Print("%s\n", line.buffer())) {
|
||||
PrintErrAndExit("Error: Unable to write file: %s\n\n",
|
||||
loading_unit_manifest_filename);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class NamespaceImpl {
|
|||
// Normalize it.
|
||||
char result[PATH_MAX];
|
||||
const intptr_t result_len =
|
||||
File::CleanUnixPath(tbuf.buf(), result, PATH_MAX);
|
||||
File::CleanUnixPath(tbuf.buffer(), result, PATH_MAX);
|
||||
if (result_len < 0) {
|
||||
errno = ENAMETOOLONG;
|
||||
return false;
|
||||
|
|
|
@ -81,7 +81,7 @@ bool NamespaceImpl::SetCwd(Namespace* namespc, const char* new_path) {
|
|||
// Normalize it.
|
||||
char result[PATH_MAX];
|
||||
const intptr_t result_len =
|
||||
File::CleanUnixPath(tbuf.buf(), result, PATH_MAX);
|
||||
File::CleanUnixPath(tbuf.buffer(), result, PATH_MAX);
|
||||
if (result_len < 0) {
|
||||
errno = ENAMETOOLONG;
|
||||
return false;
|
||||
|
|
|
@ -61,7 +61,7 @@ class NamespaceImpl {
|
|||
// Normalize it.
|
||||
char result[PATH_MAX];
|
||||
const intptr_t result_len =
|
||||
File::CleanUnixPath(tbuf.buf(), result, PATH_MAX);
|
||||
File::CleanUnixPath(tbuf.buffer(), result, PATH_MAX);
|
||||
if (result_len < 0) {
|
||||
errno = ENAMETOOLONG;
|
||||
return false;
|
||||
|
|
|
@ -245,7 +245,8 @@ CObject* SSLFilter::ProcessFilterRequest(const CObjectArray& request) {
|
|||
SecureSocketUtils::FetchErrorString(filter->ssl_, &error_string);
|
||||
CObjectArray* result = new CObjectArray(CObject::NewArray(2));
|
||||
result->SetAt(0, new CObjectInt32(CObject::NewInt32(error_code)));
|
||||
result->SetAt(1, new CObjectString(CObject::NewString(error_string.buf())));
|
||||
result->SetAt(1,
|
||||
new CObjectString(CObject::NewString(error_string.buffer())));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ void SecureSocketUtils::ThrowIOException(int status,
|
|||
{
|
||||
TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE);
|
||||
SecureSocketUtils::FetchErrorString(ssl, &error_string);
|
||||
OSError os_error_struct(status, error_string.buf(), OSError::kBoringSSL);
|
||||
OSError os_error_struct(status, error_string.buffer(), OSError::kBoringSSL);
|
||||
Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
|
||||
exception =
|
||||
DartUtils::NewDartIOException(exception_type, message, os_error);
|
||||
|
|
|
@ -11,73 +11,46 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
TextBuffer::TextBuffer(intptr_t buf_size) {
|
||||
ASSERT(buf_size > 0);
|
||||
buf_ = reinterpret_cast<char*>(malloc(buf_size));
|
||||
if (buf_ == NULL) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
buf_size_ = buf_size;
|
||||
Clear();
|
||||
}
|
||||
|
||||
TextBuffer::~TextBuffer() {
|
||||
free(buf_);
|
||||
buf_ = NULL;
|
||||
}
|
||||
|
||||
void TextBuffer::Clear() {
|
||||
msg_len_ = 0;
|
||||
buf_[0] = '\0';
|
||||
}
|
||||
|
||||
char* TextBuffer::Steal() {
|
||||
char* r = buf_;
|
||||
buf_ = NULL;
|
||||
buf_size_ = 0;
|
||||
msg_len_ = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void TextBuffer::AddChar(char ch) {
|
||||
EnsureCapacity(sizeof(ch));
|
||||
buf_[msg_len_] = ch;
|
||||
msg_len_++;
|
||||
buf_[msg_len_] = '\0';
|
||||
}
|
||||
|
||||
void TextBuffer::AddRaw(const uint8_t* buffer, intptr_t buffer_length) {
|
||||
EnsureCapacity(buffer_length);
|
||||
memmove(&buf_[msg_len_], buffer, buffer_length);
|
||||
msg_len_ += buffer_length;
|
||||
buf_[msg_len_] = '\0';
|
||||
}
|
||||
|
||||
intptr_t TextBuffer::Printf(const char* format, ...) {
|
||||
intptr_t BaseTextBuffer::Printf(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
intptr_t remaining = buf_size_ - msg_len_;
|
||||
intptr_t remaining = capacity_ - length_;
|
||||
ASSERT(remaining >= 0);
|
||||
intptr_t len = Utils::VSNPrint(buf_ + msg_len_, remaining, format, args);
|
||||
intptr_t len = Utils::VSNPrint(buffer_ + length_, remaining, format, args);
|
||||
va_end(args);
|
||||
if (len >= remaining) {
|
||||
EnsureCapacity(len);
|
||||
remaining = buf_size_ - msg_len_;
|
||||
remaining = capacity_ - length_;
|
||||
ASSERT(remaining > len);
|
||||
va_list args2;
|
||||
va_start(args2, format);
|
||||
intptr_t len2 = Utils::VSNPrint(buf_ + msg_len_, remaining, format, args2);
|
||||
intptr_t len2 =
|
||||
Utils::VSNPrint(buffer_ + length_, remaining, format, args2);
|
||||
va_end(args2);
|
||||
ASSERT(len == len2);
|
||||
}
|
||||
msg_len_ += len;
|
||||
buf_[msg_len_] = '\0';
|
||||
length_ += len;
|
||||
buffer_[length_] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
void BaseTextBuffer::AddChar(char ch) {
|
||||
EnsureCapacity(sizeof(ch));
|
||||
buffer_[length_] = ch;
|
||||
length_++;
|
||||
buffer_[length_] = '\0';
|
||||
}
|
||||
|
||||
void BaseTextBuffer::AddRaw(const uint8_t* buffer, intptr_t buffer_length) {
|
||||
EnsureCapacity(buffer_length);
|
||||
memmove(&buffer_[length_], buffer, buffer_length);
|
||||
length_ += buffer_length;
|
||||
buffer_[length_] = '\0';
|
||||
}
|
||||
|
||||
// Write a UTF-32 code unit so it can be read by a JSON parser in a string
|
||||
// literal. Use official encoding from JSON specification. http://json.org/
|
||||
void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
|
||||
void BaseTextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
|
||||
switch (codeunit) {
|
||||
case '"':
|
||||
AddRaw(reinterpret_cast<uint8_t const*>("\\\""), 2);
|
||||
|
@ -117,31 +90,54 @@ void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
|
|||
|
||||
// Write an incomplete UTF-16 code unit so it can be read by a JSON parser in a
|
||||
// string literal.
|
||||
void TextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) {
|
||||
void BaseTextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) {
|
||||
Printf("\\u%04X", codeunit);
|
||||
}
|
||||
|
||||
void TextBuffer::AddString(const char* s) {
|
||||
void BaseTextBuffer::AddString(const char* s) {
|
||||
Printf("%s", s);
|
||||
}
|
||||
|
||||
void TextBuffer::AddEscapedString(const char* s) {
|
||||
void BaseTextBuffer::AddEscapedString(const char* s) {
|
||||
intptr_t len = strlen(s);
|
||||
for (int i = 0; i < len; i++) {
|
||||
EscapeAndAddCodeUnit(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TextBuffer::TextBuffer(intptr_t buf_size) {
|
||||
ASSERT(buf_size > 0);
|
||||
buffer_ = reinterpret_cast<char*>(malloc(buf_size));
|
||||
if (buffer_ == nullptr) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
capacity_ = buf_size;
|
||||
Clear();
|
||||
}
|
||||
|
||||
TextBuffer::~TextBuffer() {
|
||||
free(buffer_);
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
char* TextBuffer::Steal() {
|
||||
char* r = buffer_;
|
||||
buffer_ = nullptr;
|
||||
capacity_ = 0;
|
||||
length_ = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void TextBuffer::EnsureCapacity(intptr_t len) {
|
||||
intptr_t remaining = buf_size_ - msg_len_;
|
||||
intptr_t remaining = capacity_ - length_;
|
||||
if (remaining <= len) {
|
||||
intptr_t new_size = buf_size_ + Utils::Maximum(buf_size_, len + 1);
|
||||
char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
|
||||
if (new_buf == NULL) {
|
||||
intptr_t new_size = capacity_ + Utils::Maximum(capacity_, len + 1);
|
||||
char* new_buf = reinterpret_cast<char*>(realloc(buffer_, new_size));
|
||||
if (new_buf == nullptr) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
buf_ = new_buf;
|
||||
buf_size_ = new_size;
|
||||
buffer_ = new_buf;
|
||||
capacity_ = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
// TextBuffer maintains a dynamic character buffer with a printf-style way to
|
||||
// append text.
|
||||
class TextBuffer : ValueObject {
|
||||
// BaseTextBuffer maintains a dynamic character buffer with a printf-style way
|
||||
// to append text. Internal buffer management is handled by subclasses.
|
||||
class BaseTextBuffer : public ValueObject {
|
||||
public:
|
||||
explicit TextBuffer(intptr_t buf_size);
|
||||
~TextBuffer();
|
||||
virtual ~BaseTextBuffer() {}
|
||||
|
||||
intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||
void AddChar(char ch);
|
||||
|
@ -25,25 +24,47 @@ class TextBuffer : ValueObject {
|
|||
void AddEscapedString(const char* s);
|
||||
void AddRaw(const uint8_t* buffer, intptr_t buffer_length);
|
||||
|
||||
void Clear();
|
||||
// Returns a pointer to the current internal buffer. Whether the pointer is
|
||||
// still valid after the BaseTextBuffer dies depends on the subclass.
|
||||
char* buffer() const { return buffer_; }
|
||||
intptr_t length() const { return length_; }
|
||||
|
||||
// Clears the stored contents. Unless specified otherwise by the subclass,
|
||||
// should be assumed to invalidate the contents of previous calls to buffer().
|
||||
virtual void Clear() = 0;
|
||||
|
||||
protected:
|
||||
virtual void EnsureCapacity(intptr_t len) = 0;
|
||||
|
||||
char* buffer_ = nullptr;
|
||||
intptr_t capacity_ = 0;
|
||||
intptr_t length_ = 0;
|
||||
};
|
||||
|
||||
// TextBuffer uses manual memory management for the character buffer. Unless
|
||||
// Steal() is used, the internal buffer is deallocated when the object dies.
|
||||
class TextBuffer : public BaseTextBuffer {
|
||||
public:
|
||||
explicit TextBuffer(intptr_t buf_size);
|
||||
~TextBuffer();
|
||||
|
||||
// Resets the contents of the internal buffer.
|
||||
void Clear() { set_length(0); }
|
||||
|
||||
char* buf() { return buf_; }
|
||||
intptr_t length() { return msg_len_; }
|
||||
void set_length(intptr_t len) {
|
||||
ASSERT(len >= 0);
|
||||
ASSERT(len <= msg_len_);
|
||||
msg_len_ = len;
|
||||
ASSERT(len <= length_);
|
||||
length_ = len;
|
||||
buffer_[len] = '\0';
|
||||
}
|
||||
|
||||
// Steal ownership of the buffer pointer.
|
||||
// Take ownership of the buffer contents. Future uses of the TextBuffer object
|
||||
// will not affect the contents of the returned buffer.
|
||||
// NOTE: TextBuffer is empty afterwards.
|
||||
char* Steal();
|
||||
|
||||
private:
|
||||
void EnsureCapacity(intptr_t len);
|
||||
char* buf_;
|
||||
intptr_t buf_size_;
|
||||
intptr_t msg_len_;
|
||||
};
|
||||
|
||||
class BufferFormatter : public ValueObject {
|
||||
|
|
|
@ -102,7 +102,7 @@ static void PrintRoundTripResults(Zone* zone, const RoundTripResults& results) {
|
|||
if (results.serialized != nullptr) {
|
||||
TextBuffer buf(1000);
|
||||
results.serialized->SerializeTo(zone, &buf, "");
|
||||
js.PrintProperty("serialized", buf.buf());
|
||||
js.PrintProperty("serialized", buf.buffer());
|
||||
}
|
||||
|
||||
if (results.error_message != nullptr) {
|
||||
|
@ -112,7 +112,7 @@ static void PrintRoundTripResults(Zone* zone, const RoundTripResults& results) {
|
|||
ASSERT(results.error_sexp != nullptr);
|
||||
TextBuffer buf(1000);
|
||||
results.error_sexp->SerializeTo(zone, &buf, "");
|
||||
js.PrintProperty("expression", buf.buf());
|
||||
js.PrintProperty("expression", buf.buffer());
|
||||
|
||||
auto const sexp_position =
|
||||
GetSExpressionPosition(zone, results.serialized, results.error_sexp);
|
||||
|
@ -121,7 +121,7 @@ static void PrintRoundTripResults(Zone* zone, const RoundTripResults& results) {
|
|||
}
|
||||
|
||||
js.CloseObject();
|
||||
THR_Print("Results of round trip serialization: %s\n", js.buffer()->buf());
|
||||
THR_Print("Results of round trip serialization: %s\n", js.buffer()->buffer());
|
||||
}
|
||||
|
||||
void FlowGraphDeserializer::RoundTripSerialization(CompilerPassState* state) {
|
||||
|
@ -159,7 +159,7 @@ void FlowGraphDeserializer::RoundTripSerialization(CompilerPassState* state) {
|
|||
if (FLAG_trace_round_trip_serialization && results.serialized != nullptr) {
|
||||
TextBuffer buf(1000);
|
||||
results.serialized->SerializeTo(zone, &buf, "");
|
||||
THR_Print("Serialized flow graph:\n%s\n", buf.buf());
|
||||
THR_Print("Serialized flow graph:\n%s\n", buf.buffer());
|
||||
}
|
||||
|
||||
// For the deserializer, use the thread from the compiler pass and zone
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "vm/compiler/method_recognizer.h"
|
||||
#include "vm/object_store.h"
|
||||
#include "vm/os.h"
|
||||
#include "vm/zone_text_buffer.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
|
@ -75,14 +76,9 @@ FlowGraphSerializer::~FlowGraphSerializer() {
|
|||
object_store_->set_llvm_constant_hash_table(llvm_constant_map_.Release());
|
||||
}
|
||||
|
||||
void FlowGraphSerializer::SerializeToBuffer(const FlowGraph* flow_graph,
|
||||
TextBuffer* buffer) {
|
||||
SerializeToBuffer(Thread::Current()->zone(), flow_graph, buffer);
|
||||
}
|
||||
|
||||
void FlowGraphSerializer::SerializeToBuffer(Zone* zone,
|
||||
const FlowGraph* flow_graph,
|
||||
TextBuffer* buffer) {
|
||||
BaseTextBuffer* buffer) {
|
||||
ASSERT(buffer != nullptr);
|
||||
auto const sexp = SerializeToSExp(zone, flow_graph);
|
||||
if (FLAG_pretty_print_serialization) {
|
||||
|
@ -93,10 +89,6 @@ void FlowGraphSerializer::SerializeToBuffer(Zone* zone,
|
|||
buffer->AddString("\n\n");
|
||||
}
|
||||
|
||||
SExpression* FlowGraphSerializer::SerializeToSExp(const FlowGraph* flow_graph) {
|
||||
return SerializeToSExp(Thread::Current()->zone(), flow_graph);
|
||||
}
|
||||
|
||||
SExpression* FlowGraphSerializer::SerializeToSExp(Zone* zone,
|
||||
const FlowGraph* flow_graph) {
|
||||
FlowGraphSerializer serializer(zone, flow_graph);
|
||||
|
@ -163,7 +155,7 @@ SExpression* FlowGraphSerializer::BlockIdToSExp(intptr_t block_id) {
|
|||
return new (zone()) SExpSymbol(OS::SCreate(zone(), "B%" Pd "", block_id));
|
||||
}
|
||||
|
||||
void FlowGraphSerializer::SerializeCanonicalName(TextBuffer* b,
|
||||
void FlowGraphSerializer::SerializeCanonicalName(BaseTextBuffer* b,
|
||||
const Object& obj) {
|
||||
ASSERT(!obj.IsNull());
|
||||
if (obj.IsFunction()) {
|
||||
|
@ -223,9 +215,9 @@ void FlowGraphSerializer::SerializeCanonicalName(TextBuffer* b,
|
|||
|
||||
SExpression* FlowGraphSerializer::CanonicalNameToSExp(const Object& obj) {
|
||||
ASSERT(!obj.IsNull());
|
||||
TextBuffer b(100);
|
||||
ZoneTextBuffer b(zone_, 100);
|
||||
SerializeCanonicalName(&b, obj);
|
||||
return new (zone()) SExpSymbol(OS::SCreate(zone(), "%s", b.buf()));
|
||||
return new (zone()) SExpSymbol(b.buffer());
|
||||
}
|
||||
|
||||
SExpSymbol* FlowGraphSerializer::BlockEntryKindToTag(BlockEntryKind k) {
|
||||
|
|
|
@ -50,12 +50,9 @@ class FlowGraphSerializer : ValueObject {
|
|||
SExpSymbol* BlockEntryKindToTag(BlockEntryKind k);
|
||||
static bool BlockEntryKindHasInitialDefs(BlockEntryKind kind);
|
||||
|
||||
static void SerializeToBuffer(const FlowGraph* flow_graph,
|
||||
TextBuffer* buffer);
|
||||
static void SerializeToBuffer(Zone* zone,
|
||||
const FlowGraph* flow_graph,
|
||||
TextBuffer* buffer);
|
||||
static SExpression* SerializeToSExp(const FlowGraph* flow_graph);
|
||||
BaseTextBuffer* buffer);
|
||||
static SExpression* SerializeToSExp(Zone* zone, const FlowGraph* flow_graph);
|
||||
|
||||
const FlowGraph* flow_graph() const { return flow_graph_; }
|
||||
|
@ -69,7 +66,7 @@ class FlowGraphSerializer : ValueObject {
|
|||
SExpression* UseToSExp(const Definition* definition);
|
||||
|
||||
// Helper method for creating canonical names.
|
||||
void SerializeCanonicalName(TextBuffer* b, const Object& obj);
|
||||
void SerializeCanonicalName(BaseTextBuffer* b, const Object& obj);
|
||||
|
||||
// Methods for serializing Dart values. If the argument
|
||||
// value is the null object, the null pointer is returned.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <ctype.h>
|
||||
#include "platform/utils.h"
|
||||
#include "vm/double_conversion.h"
|
||||
#include "vm/zone_text_buffer.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
|
@ -18,13 +19,9 @@ SExpression* SExpression::FromCString(Zone* zone, const char* str) {
|
|||
}
|
||||
|
||||
const char* SExpression::ToCString(Zone* zone) const {
|
||||
TextBuffer buf(1 * KB);
|
||||
ZoneTextBuffer buf(zone, 1 * KB);
|
||||
SerializeToLine(&buf);
|
||||
auto const buf_len = buf.length();
|
||||
char* ret = zone->Alloc<char>(buf_len + 1);
|
||||
strncpy(ret, buf.buf(), buf_len);
|
||||
ret[buf_len] = '\0';
|
||||
return ret;
|
||||
return buf.buffer();
|
||||
}
|
||||
|
||||
bool SExpBool::Equals(SExpression* sexp) const {
|
||||
|
@ -36,7 +33,7 @@ bool SExpBool::Equals(bool val) const {
|
|||
return value() == val;
|
||||
}
|
||||
|
||||
void SExpBool::SerializeToLine(TextBuffer* buffer) const {
|
||||
void SExpBool::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
buffer->AddString(value() ? SExpParser::kBoolTrueSymbol
|
||||
: SExpParser::kBoolFalseSymbol);
|
||||
}
|
||||
|
@ -50,7 +47,7 @@ bool SExpDouble::Equals(double val) const {
|
|||
return value() == val;
|
||||
}
|
||||
|
||||
void SExpDouble::SerializeToLine(TextBuffer* buffer) const {
|
||||
void SExpDouble::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
// Use existing Dart serialization for Doubles.
|
||||
const intptr_t kBufSize = 128;
|
||||
char strbuf[kBufSize];
|
||||
|
@ -67,7 +64,7 @@ bool SExpInteger::Equals(int64_t val) const {
|
|||
return value() == val;
|
||||
}
|
||||
|
||||
void SExpInteger::SerializeToLine(TextBuffer* buffer) const {
|
||||
void SExpInteger::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
buffer->Printf("%" Pd64 "", value());
|
||||
}
|
||||
|
||||
|
@ -80,10 +77,12 @@ bool SExpString::Equals(const char* str) const {
|
|||
return strcmp(value(), str) == 0;
|
||||
}
|
||||
|
||||
void SExpString::SerializeToLine(TextBuffer* buffer) const {
|
||||
buffer->AddChar('"');
|
||||
buffer->AddEscapedString(value());
|
||||
buffer->AddChar('"');
|
||||
void SExpString::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
TextBuffer buf(80);
|
||||
buf.AddChar('"');
|
||||
buf.AddEscapedString(value());
|
||||
buf.AddChar('"');
|
||||
buffer->AddString(buf.buffer());
|
||||
}
|
||||
|
||||
bool SExpSymbol::Equals(SExpression* sexp) const {
|
||||
|
@ -95,7 +94,7 @@ bool SExpSymbol::Equals(const char* str) const {
|
|||
return strcmp(value(), str) == 0;
|
||||
}
|
||||
|
||||
void SExpSymbol::SerializeToLine(TextBuffer* buffer) const {
|
||||
void SExpSymbol::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
buffer->AddString(value());
|
||||
}
|
||||
|
||||
|
@ -128,9 +127,9 @@ const char* const SExpList::kElemIndent = " ";
|
|||
const char* const SExpList::kExtraIndent = " ";
|
||||
|
||||
static intptr_t HandleLineBreaking(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
SExpression* element,
|
||||
TextBuffer* line_buffer,
|
||||
BaseTextBuffer* line_buffer,
|
||||
const char* sub_indent,
|
||||
intptr_t width,
|
||||
bool leading_space,
|
||||
|
@ -141,7 +140,7 @@ static intptr_t HandleLineBreaking(Zone* zone,
|
|||
|
||||
if ((leading_length + single_line_width) < remaining) {
|
||||
if (leading_space) buffer->AddChar(' ');
|
||||
buffer->AddString(line_buffer->buf());
|
||||
buffer->AddString(line_buffer->buffer());
|
||||
line_buffer->Clear();
|
||||
return remaining - (leading_length + single_line_width);
|
||||
}
|
||||
|
@ -150,7 +149,7 @@ static intptr_t HandleLineBreaking(Zone* zone,
|
|||
const intptr_t line_used = buffer->length() - old_length + 1;
|
||||
remaining = width - line_used;
|
||||
if ((single_line_width < remaining) || element->IsAtom()) {
|
||||
buffer->AddString(line_buffer->buf());
|
||||
buffer->AddString(line_buffer->buffer());
|
||||
line_buffer->Clear();
|
||||
return remaining - single_line_width;
|
||||
}
|
||||
|
@ -161,7 +160,7 @@ static intptr_t HandleLineBreaking(Zone* zone,
|
|||
|
||||
// Assumes that we are starting on a line after [indent] amount of space.
|
||||
void SExpList::SerializeTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
intptr_t width) const {
|
||||
TextBuffer single_line(width);
|
||||
|
@ -177,14 +176,14 @@ void SExpList::SerializeTo(Zone* zone,
|
|||
if (!extra_info_.IsEmpty()) {
|
||||
SerializeExtraInfoToLine(&single_line);
|
||||
if (single_line.length() < remaining - 1) {
|
||||
buffer->Printf(" %s", single_line.buf());
|
||||
buffer->Printf(" %s", single_line.buffer());
|
||||
} else {
|
||||
const intptr_t old_length = buffer->length();
|
||||
buffer->Printf("\n%s", sub_indent);
|
||||
const intptr_t line_used = buffer->length() - old_length + 1;
|
||||
remaining = width - line_used;
|
||||
if (single_line.length() < remaining) {
|
||||
buffer->AddString(single_line.buf());
|
||||
buffer->AddString(single_line.buffer());
|
||||
} else {
|
||||
SerializeExtraInfoTo(zone, buffer, sub_indent, width);
|
||||
}
|
||||
|
@ -193,7 +192,7 @@ void SExpList::SerializeTo(Zone* zone,
|
|||
buffer->AddChar(')');
|
||||
}
|
||||
|
||||
void SExpList::SerializeToLine(TextBuffer* buffer) const {
|
||||
void SExpList::SerializeToLine(BaseTextBuffer* buffer) const {
|
||||
buffer->AddChar('(');
|
||||
for (intptr_t i = 0; i < contents_.length(); i++) {
|
||||
if (i != 0) buffer->AddChar(' ');
|
||||
|
@ -207,7 +206,7 @@ void SExpList::SerializeToLine(TextBuffer* buffer) const {
|
|||
}
|
||||
|
||||
void SExpList::SerializeExtraInfoTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
int width) const {
|
||||
const char* sub_indent = OS::SCreate(zone, "%s%s", indent, kExtraIndent);
|
||||
|
@ -226,7 +225,7 @@ void SExpList::SerializeExtraInfoTo(Zone* zone,
|
|||
buffer->Printf("\n%s}", indent);
|
||||
}
|
||||
|
||||
void SExpList::SerializeExtraInfoToLine(TextBuffer* buffer) const {
|
||||
void SExpList::SerializeExtraInfoToLine(BaseTextBuffer* buffer) const {
|
||||
buffer->AddString("{");
|
||||
auto it = ExtraIterator();
|
||||
while (auto kv = it.Next()) {
|
||||
|
|
|
@ -81,10 +81,10 @@ class SExpression : public ZoneAllocated {
|
|||
virtual const char* DebugName() const = 0;
|
||||
virtual bool Equals(SExpression* sexp) const = 0;
|
||||
virtual void SerializeTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
intptr_t width = 80) const = 0;
|
||||
virtual void SerializeToLine(TextBuffer* buffer) const = 0;
|
||||
virtual void SerializeToLine(BaseTextBuffer* buffer) const = 0;
|
||||
|
||||
private:
|
||||
// Starting character position of the s-expression in the original
|
||||
|
@ -100,7 +100,7 @@ class SExpAtom : public SExpression {
|
|||
virtual const SExpAtom* AsAtom() const { return this; }
|
||||
// No atoms have sub-elements, so they always print to a single line.
|
||||
virtual void SerializeTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
intptr_t width = 80) const {
|
||||
SerializeToLine(buffer);
|
||||
|
@ -124,7 +124,7 @@ class SExpAtom : public SExpression {
|
|||
value_type value() const { return val_; } \
|
||||
virtual bool Equals(SExpression* sexp) const; \
|
||||
bool Equals(value_type val) const; \
|
||||
virtual void SerializeToLine(TextBuffer* buffer) const; \
|
||||
virtual void SerializeToLine(BaseTextBuffer* buffer) const; \
|
||||
DEFINE_S_EXPRESSION_TYPE_CHECK(name) \
|
||||
private: \
|
||||
value_type const val_; \
|
||||
|
@ -168,20 +168,20 @@ class SExpList : public SExpression {
|
|||
DEFINE_S_EXPRESSION_TYPE_CHECK(List)
|
||||
virtual bool Equals(SExpression* sexp) const;
|
||||
virtual void SerializeTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
intptr_t width = 80) const;
|
||||
virtual void SerializeToLine(TextBuffer* buffer) const;
|
||||
virtual void SerializeToLine(BaseTextBuffer* buffer) const;
|
||||
|
||||
private:
|
||||
static const char* const kElemIndent;
|
||||
static const char* const kExtraIndent;
|
||||
|
||||
void SerializeExtraInfoTo(Zone* zone,
|
||||
TextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const char* indent,
|
||||
int width) const;
|
||||
void SerializeExtraInfoToLine(TextBuffer* buffer) const;
|
||||
void SerializeExtraInfoToLine(BaseTextBuffer* buffer) const;
|
||||
|
||||
ZoneGrowableArray<SExpression*> contents_;
|
||||
ExtraInfoHashMap extra_info_;
|
||||
|
|
|
@ -191,13 +191,13 @@ ISOLATE_UNIT_TEST_CASE(DeserializeSExpRoundTrip) {
|
|||
|
||||
TextBuffer buf(100);
|
||||
sexp->SerializeTo(zone, &buf, "", 9999);
|
||||
SExpression* round_trip = SExpression::FromCString(zone, buf.buf());
|
||||
SExpression* round_trip = SExpression::FromCString(zone, buf.buffer());
|
||||
CheckDeserializedSExpParts(round_trip);
|
||||
EXPECT(sexp->Equals(round_trip));
|
||||
|
||||
char* const old_serialization = buf.Steal();
|
||||
round_trip->SerializeTo(zone, &buf, "", 9999);
|
||||
char* const new_serialization = buf.buf();
|
||||
char* const new_serialization = buf.buffer();
|
||||
EXPECT_STREQ(old_serialization, new_serialization);
|
||||
free(old_serialization);
|
||||
}
|
||||
|
|
|
@ -562,7 +562,7 @@ COMPILER_PASS(SerializeGraph, {
|
|||
FlowGraphSerializer::SerializeToBuffer(stack_zone.GetZone(), flow_graph,
|
||||
&buffer);
|
||||
|
||||
file_write(buffer.buf(), buffer.length(), stream);
|
||||
file_write(buffer.buffer(), buffer.length(), stream);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
|
|
@ -855,7 +855,7 @@ static void PrintLLVMConstantPool(Thread* T, Isolate* I) {
|
|||
}
|
||||
b.AddString("End of function pool.\n\n");
|
||||
}
|
||||
THR_Print("%s", b.buf());
|
||||
THR_Print("%s", b.buffer());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -774,7 +774,7 @@ const char* Dwarf::Deobfuscate(const char* cstr) {
|
|||
i += offset;
|
||||
}
|
||||
if (!changed) return cstr;
|
||||
return OS::SCreate(zone_, "%s", buffer.buf());
|
||||
return OS::SCreate(zone_, "%s", buffer.buffer());
|
||||
}
|
||||
|
||||
Trie<const char>* Dwarf::CreateReverseObfuscationTrie(Zone* zone) {
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace dart {
|
|||
TEST_CASE(JSON_TextBuffer) {
|
||||
TextBuffer w(5); // Small enough to make buffer grow at least once.
|
||||
w.Printf("{ \"%s\" : %d", "length", 175);
|
||||
EXPECT_STREQ("{ \"length\" : 175", w.buf());
|
||||
EXPECT_STREQ("{ \"length\" : 175", w.buffer());
|
||||
w.Printf(", \"%s\" : \"%s\" }", "command", "stopIt");
|
||||
EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }", w.buf());
|
||||
EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }", w.buffer());
|
||||
}
|
||||
|
||||
TEST_CASE(JSON_JSONStream_Primitives) {
|
||||
|
|
|
@ -69,7 +69,7 @@ void JSONWriter::OpenObject(const char* property_name) {
|
|||
void JSONWriter::UncloseObject() {
|
||||
intptr_t len = buffer_.length();
|
||||
ASSERT(len > 0);
|
||||
ASSERT(buffer_.buf()[len - 1] == '}');
|
||||
ASSERT(buffer_.buffer()[len - 1] == '}');
|
||||
open_objects_++;
|
||||
buffer_.set_length(len - 1);
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ void JSONWriter::PrintCommaIfNeeded() {
|
|||
}
|
||||
|
||||
bool JSONWriter::NeedComma() {
|
||||
const char* buffer = buffer_.buf();
|
||||
const char* buffer = buffer_.buffer();
|
||||
intptr_t length = buffer_.length();
|
||||
if (length == 0) {
|
||||
return false;
|
||||
|
|
|
@ -17,7 +17,7 @@ class JSONWriter : ValueObject {
|
|||
explicit JSONWriter(intptr_t buf_size = 256);
|
||||
|
||||
TextBuffer* buffer() { return &buffer_; }
|
||||
const char* ToCString() { return buffer_.buf(); }
|
||||
const char* ToCString() { return buffer_.buffer(); }
|
||||
|
||||
void Steal(char** buffer, intptr_t* buffer_length);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "include/dart_api.h"
|
||||
#include "platform/assert.h"
|
||||
#include "platform/text_buffer.h"
|
||||
#include "platform/unaligned.h"
|
||||
#include "platform/unicode.h"
|
||||
#include "vm/bit_vector.h"
|
||||
|
@ -183,7 +184,7 @@ ClassPtr Object::weak_serialization_reference_class_ =
|
|||
|
||||
const double MegamorphicCache::kLoadFactor = 0.50;
|
||||
|
||||
static void AppendSubString(ZoneTextBuffer* buffer,
|
||||
static void AppendSubString(BaseTextBuffer* buffer,
|
||||
const char* name,
|
||||
intptr_t start_pos,
|
||||
intptr_t len) {
|
||||
|
@ -5941,7 +5942,7 @@ void TypeArguments::PrintSubvectorName(
|
|||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
BaseTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation /* = NameDisambiguation::kNo */)
|
||||
const {
|
||||
printer->AddString("<");
|
||||
|
@ -8900,7 +8901,7 @@ StringPtr Function::UserVisibleSignature() const {
|
|||
void Function::PrintSignatureParameters(Thread* thread,
|
||||
Zone* zone,
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer) const {
|
||||
BaseTextBuffer* printer) const {
|
||||
AbstractType& param_type = AbstractType::Handle(zone);
|
||||
const intptr_t num_params = NumParameters();
|
||||
const intptr_t num_fixed_params = num_fixed_parameters();
|
||||
|
@ -8941,7 +8942,7 @@ void Function::PrintSignatureParameters(Thread* thread,
|
|||
if (num_opt_named_params > 0) {
|
||||
name = ParameterNameAt(i);
|
||||
printer->AddString(" ");
|
||||
printer->AddString(name);
|
||||
printer->AddString(name.ToCString());
|
||||
}
|
||||
if (i != (num_params - 1)) {
|
||||
printer->AddString(", ");
|
||||
|
@ -8993,7 +8994,7 @@ intptr_t Function::ComputeClosureHash() const {
|
|||
}
|
||||
|
||||
void Function::PrintSignature(NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer) const {
|
||||
BaseTextBuffer* printer) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
Isolate* isolate = thread->isolate();
|
||||
|
@ -9279,7 +9280,7 @@ StringPtr Function::QualifiedUserVisibleName() const {
|
|||
}
|
||||
|
||||
void Function::PrintName(const NameFormattingParams& params,
|
||||
ZoneTextBuffer* printer) const {
|
||||
BaseTextBuffer* printer) const {
|
||||
// If |this| is the generated asynchronous body closure, use the
|
||||
// name of the parent function.
|
||||
Function& fun = Function::Handle(raw());
|
||||
|
@ -19220,14 +19221,14 @@ StringPtr AbstractType::UserVisibleName() const {
|
|||
|
||||
void AbstractType::PrintName(
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
BaseTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation /* = NameDisambiguation::kNo */)
|
||||
const {
|
||||
ASSERT(name_visibility != kScrubbedName);
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
Class& cls = Class::Handle(zone);
|
||||
String& class_name = String::Handle(zone);
|
||||
String& name_str = String::Handle(zone);
|
||||
if (IsTypeParameter()) {
|
||||
const TypeParameter& param = TypeParameter::Cast(*this);
|
||||
|
||||
|
@ -19249,7 +19250,8 @@ void AbstractType::PrintName(
|
|||
}
|
||||
}
|
||||
|
||||
printer->AddString(String::Handle(zone, param.name()));
|
||||
name_str = param.name();
|
||||
printer->AddString(name_str.ToCString());
|
||||
printer->AddString(NullabilitySuffix(name_visibility));
|
||||
return;
|
||||
}
|
||||
|
@ -19275,10 +19277,10 @@ void AbstractType::PrintName(
|
|||
}
|
||||
// Instead of printing the actual signature, use the typedef name with
|
||||
// its type arguments, if any.
|
||||
class_name = cls.Name(); // Typedef name.
|
||||
name_str = cls.Name(); // Typedef name.
|
||||
if (!IsFinalized() || IsBeingFinalized()) {
|
||||
// TODO(regis): Check if this is dead code.
|
||||
printer->AddString(class_name);
|
||||
printer->AddString(name_str.ToCString());
|
||||
printer->AddString(NullabilitySuffix(name_visibility));
|
||||
return;
|
||||
}
|
||||
|
@ -19287,8 +19289,8 @@ void AbstractType::PrintName(
|
|||
// Do not print the full vector, but only the declared type parameters.
|
||||
num_type_params = cls.NumTypeParameters();
|
||||
if (name_visibility == kInternalName) {
|
||||
class_name = cls.Name();
|
||||
printer->AddString(class_name);
|
||||
name_str = cls.Name();
|
||||
printer->AddString(name_str.ToCString());
|
||||
} else {
|
||||
ASSERT(name_visibility == kUserVisibleName);
|
||||
// Map internal types to their corresponding public interfaces.
|
||||
|
@ -21021,18 +21023,21 @@ void TypeParameter::set_flags(uint8_t flags) const {
|
|||
const char* TypeParameter::ToCString() const {
|
||||
Thread* thread = Thread::Current();
|
||||
ZoneTextBuffer printer(thread->zone());
|
||||
auto& name_str = String::Handle(thread->zone(), name());
|
||||
printer.Printf("TypeParameter: name ");
|
||||
printer.AddString(String::Handle(name()));
|
||||
printer.AddString(name_str.ToCString());
|
||||
printer.AddString(NullabilitySuffix(kInternalName));
|
||||
printer.Printf("; index: %" Pd ";", index());
|
||||
if (IsFunctionTypeParameter()) {
|
||||
const Function& function = Function::Handle(parameterized_function());
|
||||
printer.Printf(" function: ");
|
||||
printer.AddString(String::Handle(function.name()));
|
||||
name_str = function.name();
|
||||
printer.AddString(name_str.ToCString());
|
||||
} else {
|
||||
const Class& cls = Class::Handle(parameterized_class());
|
||||
printer.Printf(" class: ");
|
||||
printer.AddString(String::Handle(cls.Name()));
|
||||
name_str = cls.Name();
|
||||
printer.AddString(name_str.ToCString());
|
||||
}
|
||||
printer.Printf("; bound: ");
|
||||
const AbstractType& upper_bound = AbstractType::Handle(bound());
|
||||
|
@ -24320,7 +24325,7 @@ StackTracePtr StackTrace::New(const Array& code_array,
|
|||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
// Prints the best representation(s) for the call address.
|
||||
static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
|
||||
static void PrintNonSymbolicStackFrameBody(BaseTextBuffer* buffer,
|
||||
uword call_addr,
|
||||
uword isolate_instructions,
|
||||
uword vm_instructions,
|
||||
|
@ -24356,12 +24361,12 @@ static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void PrintSymbolicStackFrameIndex(ZoneTextBuffer* buffer,
|
||||
static void PrintSymbolicStackFrameIndex(BaseTextBuffer* buffer,
|
||||
intptr_t frame_index) {
|
||||
buffer->Printf("#%-6" Pd "", frame_index);
|
||||
}
|
||||
|
||||
static void PrintSymbolicStackFrameBody(ZoneTextBuffer* buffer,
|
||||
static void PrintSymbolicStackFrameBody(BaseTextBuffer* buffer,
|
||||
const char* function_name,
|
||||
const char* url,
|
||||
intptr_t line = -1,
|
||||
|
@ -24377,7 +24382,7 @@ static void PrintSymbolicStackFrameBody(ZoneTextBuffer* buffer,
|
|||
}
|
||||
|
||||
static void PrintSymbolicStackFrame(Zone* zone,
|
||||
ZoneTextBuffer* buffer,
|
||||
BaseTextBuffer* buffer,
|
||||
const Function& function,
|
||||
TokenPosition token_pos,
|
||||
intptr_t frame_index) {
|
||||
|
|
|
@ -71,7 +71,7 @@ REUSABLE_HANDLE_LIST(REUSABLE_FORWARD_DECLARATION)
|
|||
#undef REUSABLE_FORWARD_DECLARATION
|
||||
|
||||
class Symbols;
|
||||
class ZoneTextBuffer;
|
||||
class BaseTextBuffer;
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define CHECK_HANDLE() CheckHandle();
|
||||
|
@ -2478,7 +2478,7 @@ class Function : public Object {
|
|||
const char* NameCString(NameVisibility name_visibility) const;
|
||||
|
||||
void PrintName(const NameFormattingParams& params,
|
||||
ZoneTextBuffer* printer) const;
|
||||
BaseTextBuffer* printer) const;
|
||||
StringPtr QualifiedScrubbedName() const;
|
||||
StringPtr QualifiedUserVisibleName() const;
|
||||
|
||||
|
@ -2552,7 +2552,7 @@ class Function : public Object {
|
|||
StringPtr UserVisibleSignature() const;
|
||||
|
||||
void PrintSignature(NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer) const;
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
// Returns true if the signature of this function is instantiated, i.e. if it
|
||||
// does not involve generic parameter types or generic result type.
|
||||
|
@ -3792,7 +3792,7 @@ class Function : public Object {
|
|||
void PrintSignatureParameters(Thread* thread,
|
||||
Zone* zone,
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer) const;
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
// Returns true if the type of the formal parameter at the given position in
|
||||
// this function is contravariant with the type of the other formal parameter
|
||||
|
@ -7583,7 +7583,7 @@ class TypeArguments : public Instance {
|
|||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
BaseTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation = NameDisambiguation::kNo) const;
|
||||
|
||||
// Check if the subvector of length 'len' starting at 'from_index' of this
|
||||
|
@ -7910,7 +7910,7 @@ class AbstractType : public Instance {
|
|||
// type arguments, if any.
|
||||
void PrintName(
|
||||
NameVisibility visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
BaseTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation = NameDisambiguation::kNo) const;
|
||||
|
||||
// Add the class name and URI of each occuring type to the uris
|
||||
|
|
|
@ -643,7 +643,7 @@ void HeapSnapshotWriter::Flush(bool last) {
|
|||
}
|
||||
|
||||
Service::SendEventWithData(Service::heapsnapshot_stream.id(), "HeapSnapshot",
|
||||
kMetadataReservation, js.buffer()->buf(),
|
||||
kMetadataReservation, js.buffer()->buffer(),
|
||||
js.buffer()->length(), buffer_, size_);
|
||||
buffer_ = nullptr;
|
||||
size_ = 0;
|
||||
|
|
|
@ -1142,7 +1142,7 @@ void Service::HandleEvent(ServiceEvent* event) {
|
|||
event->stream_info()->consumer() != nullptr) {
|
||||
auto length = js.buffer()->length();
|
||||
event->stream_info()->consumer()(
|
||||
reinterpret_cast<uint8_t*>(js.buffer()->buf()), length);
|
||||
reinterpret_cast<uint8_t*>(js.buffer()->buffer()), length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1623,8 +1623,9 @@ void Service::SendEchoEvent(Isolate* isolate, const char* text) {
|
|||
data[reservation + 0] = 0;
|
||||
data[reservation + 1] = 128;
|
||||
data[reservation + 2] = 255;
|
||||
SendEventWithData(echo_stream.id(), "_Echo", reservation, js.buffer()->buf(),
|
||||
js.buffer()->length(), data, data_size);
|
||||
SendEventWithData(echo_stream.id(), "_Echo", reservation,
|
||||
js.buffer()->buffer(), js.buffer()->length(), data,
|
||||
data_size);
|
||||
}
|
||||
|
||||
static bool TriggerEchoEvent(Thread* thread, JSONStream* js) {
|
||||
|
|
|
@ -14,51 +14,13 @@
|
|||
namespace dart {
|
||||
|
||||
ZoneTextBuffer::ZoneTextBuffer(Zone* zone, intptr_t initial_capacity)
|
||||
: zone_(zone), buffer_(NULL), length_(0), capacity_(0) {
|
||||
: zone_(zone) {
|
||||
ASSERT(initial_capacity > 0);
|
||||
buffer_ = reinterpret_cast<char*>(zone->Alloc<char>(initial_capacity));
|
||||
capacity_ = initial_capacity;
|
||||
buffer_[length_] = '\0';
|
||||
}
|
||||
|
||||
intptr_t ZoneTextBuffer::Printf(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
intptr_t remaining = capacity_ - length_;
|
||||
ASSERT(remaining >= 0);
|
||||
intptr_t len = Utils::VSNPrint(buffer_ + length_, remaining, format, args);
|
||||
va_end(args);
|
||||
if (len >= remaining) {
|
||||
EnsureCapacity(len);
|
||||
remaining = capacity_ - length_;
|
||||
ASSERT(remaining > len);
|
||||
va_list args2;
|
||||
va_start(args2, format);
|
||||
intptr_t len2 =
|
||||
Utils::VSNPrint(buffer_ + length_, remaining, format, args2);
|
||||
va_end(args2);
|
||||
ASSERT(len == len2);
|
||||
}
|
||||
length_ += len;
|
||||
buffer_[length_] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
void ZoneTextBuffer::AddChar(char ch) {
|
||||
EnsureCapacity(sizeof(ch));
|
||||
buffer_[length_] = ch;
|
||||
length_++;
|
||||
buffer_[length_] = '\0';
|
||||
}
|
||||
|
||||
void ZoneTextBuffer::AddString(const char* s) {
|
||||
Printf("%s", s);
|
||||
}
|
||||
|
||||
void ZoneTextBuffer::AddString(const String& s) {
|
||||
Printf("%s", s.ToCString());
|
||||
}
|
||||
|
||||
void ZoneTextBuffer::Clear() {
|
||||
const intptr_t initial_capacity = 64;
|
||||
buffer_ = reinterpret_cast<char*>(zone_->Alloc<char>(initial_capacity));
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef RUNTIME_VM_ZONE_TEXT_BUFFER_H_
|
||||
#define RUNTIME_VM_ZONE_TEXT_BUFFER_H_
|
||||
|
||||
#include "platform/text_buffer.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/globals.h"
|
||||
|
||||
|
@ -13,29 +14,20 @@ namespace dart {
|
|||
class String;
|
||||
class Zone;
|
||||
|
||||
// TextBuffer maintains a dynamic character buffer with a printf-style way to
|
||||
// append text.
|
||||
class ZoneTextBuffer : ValueObject {
|
||||
// ZoneTextBuffer allocates the character buffer in the given zone. Thus,
|
||||
// pointers returned by buffer() have the same lifetime as the zone.
|
||||
class ZoneTextBuffer : public BaseTextBuffer {
|
||||
public:
|
||||
explicit ZoneTextBuffer(Zone* zone, intptr_t initial_capacity = 64);
|
||||
~ZoneTextBuffer() {}
|
||||
|
||||
intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||
void AddChar(char ch);
|
||||
void AddString(const char* s);
|
||||
void AddString(const String& s);
|
||||
|
||||
char* buffer() { return buffer_; }
|
||||
intptr_t length() const { return length_; }
|
||||
|
||||
// Allocates a new internal buffer. Thus, the contents of buffers returned by
|
||||
// previous calls to buffer() are no longer affected by this object.
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
void EnsureCapacity(intptr_t len);
|
||||
Zone* zone_;
|
||||
char* buffer_;
|
||||
intptr_t length_;
|
||||
intptr_t capacity_;
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
|
Loading…
Reference in a new issue