61 llvm::raw_string_ostream os(s);
63 for (
auto &d : data) {
64 if (
auto s = std::get_if<std::string>(&d))
65 os <<
'"' << *s <<
'"';
66 else if (
auto u = std::get_if<uint64_t>(&d))
68 else if (
auto i = std::get_if<int64_t>(&d))
70 else if (
auto valobj = std::get_if<ValueObjectSP>(&d)) {
74 os <<
"object(" << valobj->get()->GetValueAsCString() <<
')';
75 }
else if (
auto type = std::get_if<CompilerType>(&d)) {
76 os <<
'(' << type->GetTypeName(
true) <<
')';
77 }
else if (
auto sel = std::get_if<FormatterBytecode::Selectors>(&d)) {
90 auto fmt = data.
Pop<std::string>();
92 llvm::formatv_object_base::parseFormatString(fmt, 0,
false);
94 llvm::raw_string_ostream os(s);
95 unsigned num_args = 0;
96 for (
const auto &r : replacements)
97 if (r.Type == llvm::ReplacementType::Format)
98 num_args = std::max(num_args, r.Index + 1);
100 if (data.size() < num_args)
101 return llvm::createStringError(
"not enough arguments");
103 for (
const auto &r : replacements) {
104 if (r.Type == llvm::ReplacementType::Literal) {
108 using namespace llvm::support::detail;
109 auto arg = data[data.size() - num_args + r.Index];
110 auto format = [&](format_adapter &&adapter) {
111 llvm::FmtAlign
Align(adapter, r.Where, r.Width, r.Pad);
112 Align.format(os, r.Options);
115 if (
auto s = std::get_if<std::string>(&arg))
116 format(build_format_adapter(s->c_str()));
117 else if (
auto u = std::get_if<uint64_t>(&arg))
118 format(build_format_adapter(u));
119 else if (
auto i = std::get_if<int64_t>(&arg))
120 format(build_format_adapter(i));
121 else if (
auto valobj = std::get_if<ValueObjectSP>(&arg)) {
123 format(build_format_adapter(
"null object"));
125 format(build_format_adapter(valobj->get()->GetValueAsCString()));
126 }
else if (
auto type = std::get_if<CompilerType>(&arg))
127 format(build_format_adapter(type->GetDisplayTypeName()));
128 else if (
auto sel = std::get_if<FormatterBytecode::Selectors>(&arg))
129 format(build_format_adapter(
toString(*sel)));
132 return llvm::Error::success();
135static llvm::Error
TypeCheck(llvm::ArrayRef<DataStackElement> data,
138 return llvm::createStringError(
"not enough elements on data stack");
140 auto &elem = data.back();
145 if (!std::holds_alternative<std::string>(elem))
146 return llvm::createStringError(
"expected String");
149 if (!std::holds_alternative<uint64_t>(elem))
150 return llvm::createStringError(
"expected UInt");
153 if (!std::holds_alternative<int64_t>(elem))
154 return llvm::createStringError(
"expected Int");
157 if (!std::holds_alternative<ValueObjectSP>(elem))
158 return llvm::createStringError(
"expected Object");
161 if (!std::holds_alternative<CompilerType>(elem))
162 return llvm::createStringError(
"expected Type");
165 if (!std::holds_alternative<Selectors>(elem))
166 return llvm::createStringError(
"expected Selector");
169 return llvm::Error::success();
188 return llvm::Error::success();
191 llvm::DataExtractor cur_block(control.back(),
true);
192 llvm::DataExtractor::Cursor
pc(0);
194 while (!control.empty()) {
196 auto activate_block = [&]() {
198 if (control.size() > 1)
199 control[control.size() - 2] = cur_block.getData().drop_front(
pc.tell());
200 cur_block = llvm::DataExtractor(control.back(),
true);
202 pc = llvm::DataExtractor::Cursor(0);
206 auto next_byte = [&]() -> uint8_t {
208 while (
pc.tell() >= cur_block.size() && !control.empty()) {
209 if (control.size() == 1) {
218 return cur_block.getU8(
pc);
223 if (control.empty() || !
pc)
224 return pc.takeError();
227 "[eval {0}] opcode={1}, control={2}, data={3}",
232#define TYPE_CHECK(...) \
233 if (auto error = TypeCheck(data, __VA_ARGS__)) \
236 auto error = [&](llvm::Twine msg) {
237 return llvm::createStringError(msg +
"(opcode=" +
toString(opcode) +
")");
244 data.
Push(data.back());
252 uint64_t idx = data.
Pop<uint64_t>();
253 if (idx >= data.size())
254 return error(
"index out of bounds");
255 data.
Push(data[idx]);
260 data.
Push(data[data.size() - 2]);
283 uint64_t length = cur_block.getULEB128(
pc);
285 return pc.takeError();
286 llvm::StringRef block = cur_block.getBytes(
pc, length);
288 return pc.takeError();
289 control.push_back(block);
294 if (data.
Pop<uint64_t>() != 0) {
295 if (!cur_block.size())
296 return error(
"empty control stack");
303 if (cur_block.size() < 2)
304 return error(
"empty control stack");
305 if (data.
Pop<uint64_t>() == 0)
306 control[control.size() - 2] = control.back();
312 return pc.takeError();
316 data.
Push(cur_block.getULEB128(
pc));
319 data.
Push(cur_block.getSLEB128(
pc));
321 case op_lit_selector:
324 case op_lit_string: {
325 uint64_t length = cur_block.getULEB128(
pc);
326 llvm::StringRef bytes = cur_block.getBytes(
pc, length);
327 data.
Push(bytes.str());
333 int64_t val = data.
Pop<int64_t>();
334 memcpy(&casted, &val,
sizeof(val));
341 uint64_t val = data.
Pop<uint64_t>();
342 memcpy(&casted, &val,
sizeof(val));
353#define BINOP_IMPL(OP, CHECK_ZERO) \
355 TYPE_CHECK(Any, Any); \
356 auto y = data.PopAny(); \
357 if (std::holds_alternative<uint64_t>(y)) { \
358 if (CHECK_ZERO && !std::get<uint64_t>(y)) \
359 return error(#OP " by zero"); \
361 data.Push((uint64_t)(data.Pop<uint64_t>() OP std::get<uint64_t>(y))); \
362 } else if (std::holds_alternative<int64_t>(y)) { \
363 if (CHECK_ZERO && !std::get<int64_t>(y)) \
364 return error(#OP " by zero"); \
366 data.Push((int64_t)(data.Pop<int64_t>() OP std::get<int64_t>(y))); \
368 return error("unsupported data types"); \
370#define BINOP(OP) BINOP_IMPL(OP, false)
371#define BINOP_CHECKZERO(OP) BINOP_IMPL(OP, true)
388#define SHIFTOP(OP, LEFT) \
390 TYPE_CHECK(Any, UInt); \
391 uint64_t y = data.Pop<uint64_t>(); \
393 return error("shift out of bounds"); \
394 if (std::holds_alternative<uint64_t>(data.back())) { \
395 uint64_t x = data.Pop<uint64_t>(); \
397 } else if (std::holds_alternative<int64_t>(data.back())) { \
398 int64_t x = data.Pop<int64_t>(); \
400 return error("left shift of negative value"); \
402 return error("shift out of bounds"); \
405 return error("unsupported data types"); \
423 data.
Push(~data.
Pop<uint64_t>());
448#define POP_VALOBJ(VALOBJ) \
449 auto VALOBJ = data.Pop<ValueObjectSP>(); \
451 return error("null object");
453 auto sel_error = [&](
const char *msg) {
454 return llvm::createStringError(
"{0} (opcode={1}, selector={2})", msg,
463 const char *summary = valobj->GetSummaryAsCString();
464 data.
Push(summary ? std::string(valobj->GetSummaryAsCString())
468 case sel_get_num_children: {
471 auto result = valobj->GetNumChildren();
473 return result.takeError();
474 data.
Push((uint64_t)*result);
477 case sel_get_child_at_index: {
479 auto index = data.
Pop<uint64_t>();
481 data.
Push(valobj->GetChildAtIndex(index));
484 case sel_get_child_with_name: {
486 auto name = data.
Pop<std::string>();
488 data.
Push(valobj->GetChildMemberWithName(name));
491 case sel_get_child_index: {
493 auto name = data.
Pop<std::string>();
495 if (
auto index_or_err = valobj->GetIndexOfChildWithName(name))
496 data.
Push((uint64_t)*index_or_err);
498 return index_or_err.takeError();
501 case sel_get_parent: {
504 auto *parent = valobj->GetParent();
512 data.
Push(valobj->GetTypeImpl().GetCompilerType(
false));
515 case sel_get_template_argument_type: {
517 auto index = data.
Pop<uint64_t>();
520 data.
Push(type.GetTypeTemplateArgument(index,
true));
523 case sel_get_synthetic_value: {
526 data.
Push(valobj->GetSyntheticValue());
529 case sel_get_non_synthetic_value: {
532 data.
Push(valobj->GetNonSyntheticValue());
535 case sel_get_value: {
538 data.
Push(std::string(valobj->GetValueAsCString()));
541 case sel_get_value_as_unsigned: {
545 uint64_t val = valobj->GetValueAsUnsigned(0, &success);
548 return sel_error(
"failed to get value");
551 case sel_get_value_as_signed: {
555 int64_t val = valobj->GetValueAsSigned(0, &success);
558 return sel_error(
"failed to get value");
561 case sel_get_value_as_address: {
565 uint64_t addr = valobj->GetValueAsUnsigned(0, &success);
567 return sel_error(
"failed to get value");
568 if (
auto process_sp = valobj->GetProcessSP())
569 addr = process_sp->FixDataAddress(addr);
577 data.
Push(valobj->Cast(type));
582 auto new_name = data.
Pop<std::string>();
584 data.
Push(valobj->Clone(new_name));
589 data.
Push((uint64_t)data.
Pop<std::string>().size());
599 return sel_error(
"selector not implemented");
604 return error(
"opcode not implemented");
606 return pc.takeError();