Skip to content

Commit 583c340

Browse files
Some bug fix (#100)
* bug fix: remove recalculation of symbolic size * a debug utility * fix: symbol name for combined z3 model * compute composed model by z3::model directly * remove a test case for i64.rotr, which is not use in benchmarks * more debuggiing infos
1 parent e7af779 commit 583c340

File tree

6 files changed

+55
-48
lines changed

6 files changed

+55
-48
lines changed

benchmarks/wasm/i64_ops.wat

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@
8787
i64.eq
8888
call 0
8989

90-
local.get 0
91-
local.get 2
92-
i64.extend_i32_u
93-
i64.rotr
94-
i64.const 4611686018427387909
95-
i64.eq
96-
call 0
90+
;; local.get 0
91+
;; local.get 2
92+
;; i64.extend_i32_u
93+
;; i64.rotr
94+
;; i64.const 4611686018427387909
95+
;; i64.eq
96+
;; call 0
9797

9898
;; comparisons
9999
local.get 0

headers/wasm/smt_solver.hpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static QueryResult
3636
compose_query_results(const std::vector<QueryResult> &results) {
3737
ManagedTimer timer(TimeProfileKind::SPLIT_CONDITIONS);
3838
NumMap combined_map;
39+
z3::model combined_model(global_z3_ctx());
3940
for (const auto &res : results) {
4041
auto num_map = res.map_box;
4142
for (const auto &[id, num] : *num_map) {
@@ -44,19 +45,21 @@ compose_query_results(const std::vector<QueryResult> &results) {
4445
"Conflicting symbolic environment ids when composing query results");
4546
combined_map[id] = num;
4647
}
48+
const z3::model &model = res.model;
49+
for (unsigned i = 0; i < model.num_consts(); ++i) {
50+
z3::func_decl decl = model.get_const_decl(i);
51+
std::string name = decl.name().str();
52+
assert((starts_with(name, "s_int") || starts_with(name, "s_f32") ||
53+
starts_with(name, "s_f64")) &&
54+
"Unexpected declaration in query result model");
55+
assert(!combined_model.has_interp(decl) &&
56+
"Internal Error: Conflicting constant declarations when composing query results");
57+
z3::expr value = model.get_const_interp(decl);
58+
combined_model.add_const_interp(decl, value);
59+
}
4760
}
4861
ImmNumMapBox combined_map_box(combined_map);
49-
50-
z3::solver solver(global_z3_ctx());
51-
52-
// build a combined z3 model
53-
for (const auto &[id, num] : combined_map) {
54-
solver.add(
55-
global_z3_ctx().bv_const(("s_" + std::to_string(id)).c_str(), 32) ==
56-
global_z3_ctx().bv_val(num.value, 32));
57-
}
58-
solver.check();
59-
return QueryResult{combined_map_box, solver.get_model()};
62+
return QueryResult{combined_map_box, combined_model};
6063
}
6164

6265
// VectorGroupResult groups a vector. key is the vector index, and value is the

headers/wasm/sym_rt.hpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class SymStack_t {
4242
void push(SymVal val) {
4343
// Push a symbolic value to the stack
4444
stack.push_back(val);
45-
symbolic_size += val->size();
4645
}
4746

4847
SymVal pop() {
@@ -54,12 +53,10 @@ class SymStack_t {
5453
#ifdef USE_IMM
5554
auto ret = *(stack.end() - 1);
5655
stack.take(stack.size() - 1);
57-
symbolic_size -= ret->size();
5856
return ret;
5957
#else
6058
auto ret = stack.back();
6159
stack.pop_back();
62-
symbolic_size -= ret->size();
6360
return ret;
6461
#endif
6562
}
@@ -71,7 +68,6 @@ class SymStack_t {
7168
for (size_t i = n - size; i < n; ++i) {
7269
assert(i - offset >= 0);
7370
#ifdef USE_IMM
74-
symbolic_size -= stack[i - offset]->size();
7571
stack.set(i - offset, stack[i]);
7672
#else
7773
stack[i - offset] = stack[i];
@@ -149,10 +145,6 @@ class SymFrames_t {
149145
auto frame_base = current_frame_base();
150146
assert(frame_base + size == stack.size());
151147

152-
for (int i = 0; i < size; ++i) {
153-
symbolic_size -= stack[stack.size() - 1 - i]->size();
154-
}
155-
156148
#ifdef USE_IMM
157149
stack.take(stack.size() - size);
158150
#else
@@ -173,10 +165,6 @@ class SymFrames_t {
173165
assert(size >= 0);
174166
assert(static_cast<size_t>(size) <= stack.size());
175167

176-
for (int i = 0; i < size; ++i) {
177-
symbolic_size -= stack[stack.size() - 1 - i]->size();
178-
}
179-
180168
#ifdef USE_IMM
181169
stack.take(stack.size() - size);
182170
#else
@@ -203,7 +191,6 @@ class SymFrames_t {
203191
auto frame_base = current_frame_base();
204192
assert(index >= 0 &&
205193
static_cast<size_t>(frame_base + index) < stack.size());
206-
symbolic_size += val->size() - stack[frame_base + index]->size();
207194
#ifdef USE_IMM
208195
stack.set(frame_base + index, val);
209196
#else
@@ -451,11 +438,6 @@ class SymMemory_t {
451438
exists = (it != memory.end());
452439
#endif
453440
auto old_value = loadSymByte(addr);
454-
if (exists) {
455-
// We are overwriting an existing symbolic value
456-
symbolic_size -= old_value->size();
457-
}
458-
symbolic_size += value->size();
459441
#ifdef USE_IMM
460442
memory.set(addr, value);
461443
#else

headers/wasm/symbolic_decl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ inline std::tuple<int, bool> count_dag_size_aux(Symbolic &val,
314314
} else if (auto witness = dynamic_cast<Witness *>(&val)) {
315315
assert(false && "Witness should not appear during instruction execution");
316316
} else {
317-
throw std::runtime_error("Unknown symbolic type in dag size counting");
317+
assert(false && "Unknown symbolic type in dag size counting");
318318
}
319319
}
320320

headers/wasm/utils.hpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,36 @@ inline bool starts_with(const std::string &str, const std::string &prefix) {
5252
}
5353
#endif
5454

55-
inline std::monostate info() {
56-
#ifdef DEBUG
55+
inline std::monostate print_infos() {
5756
std::cout << std::endl;
58-
#endif
57+
return std::monostate{};
58+
}
59+
60+
template <typename T, typename... Args>
61+
std::monostate print_infos(const T &first, const Args &...args) {
62+
std::cout << first << " ";
63+
print_infos(args...);
5964
return std::monostate{};
6065
}
6166

6267
template <typename T, typename... Args>
6368
std::monostate info(const T &first, const Args &...args) {
6469
#ifdef DEBUG
65-
std::cout << first << " ";
66-
info(args...);
70+
print_infos(first, args...);
71+
#endif
72+
return std::monostate{};
73+
}
74+
75+
constexpr const char *DEBUG_OPTS_ENV_VAR = "GENSYM_DEBUG";
76+
77+
template <typename... Args>
78+
std::monostate infoWhen(const char *dbg_option, const Args &...args) {
79+
#ifdef DEBUGWHEN
80+
const char *env_value = std::getenv(DEBUG_OPTS_ENV_VAR);
81+
if (env_value && std::string(env_value).find(std::string(dbg_option)) !=
82+
std::string::npos) {
83+
print_infos(args...);
84+
}
6785
#endif
6886
return std::monostate{};
6987
}

src/main/scala/wasm/StagedConcolicMiniWasm.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,10 @@ trait DebugInfo extends SAIOps {
11121112
def info(xs: Rep[_]*): Rep[Unit] = {
11131113
"info".reflectCtrlWith[Unit](xs: _*)
11141114
}
1115+
1116+
def infoWhen(envVar: Rep[String], xs: Rep[_]*): Rep[Unit] = {
1117+
"infoWhen".reflectCtrlWith[Unit](envVar :: xs.toList: _*)
1118+
}
11151119
}
11161120

11171121
@virtualize
@@ -1575,7 +1579,7 @@ trait StagedWasmEvaluator extends SAIOps
15751579
}
15761580
tailCall(thnK, ())
15771581
} else {
1578-
info(s"Continue")
1582+
info(s"Continue rest of the block")
15791583
withBlock {
15801584
val control = makeControl(thnK, currentMCont)
15811585
ExploreTree.moveCursor(false, control)
@@ -1671,7 +1675,7 @@ trait StagedWasmEvaluator extends SAIOps
16711675
})
16721676
val newMKont: Rep[MCont[Unit]] = currentMCont.prependCont(restK)
16731677
updateCurrentMCont(newMKont)
1674-
info(s"Calling function at index ", index.toInt, " with call_indirect, stackSize =", Stack.size)
1678+
infoWhen("CALL", s"Calling function at index ", index.toInt, " with call_indirect, stackSize =", Stack.size)
16751679
val argsC = Stack.takeC(functy.inps)
16761680
val argsS = Stack.takeS(functy.inps)
16771681
Frames.pushFrameCallerC(functy.inps)
@@ -1686,7 +1690,7 @@ trait StagedWasmEvaluator extends SAIOps
16861690
compileCache(funcIndex)
16871691
} else {
16881692
def retK(ctx: Context): Rep[Cont[Unit]] = topFun((_: Rep[Unit]) => {
1689-
info(s"Return from the function at $funcIndex, stackSize =", Stack.size)
1693+
infoWhen("CALL", s"Exiting the function at $funcIndex, stackSize =", Stack.size)
16901694
Frames.popFrameCalleeC(locals.size)
16911695
Frames.popFrameCalleeS(locals.size)
16921696
val offset = ctx.stackTypes.size - ty.out.size
@@ -1696,7 +1700,7 @@ trait StagedWasmEvaluator extends SAIOps
16961700
})
16971701

16981702
val func = topFun((_: Rep[Unit]) => {
1699-
info(s"Entered the function at $funcIndex, stackSize =", Stack.size)
1703+
infoWhen("CALL", s"Entered the function at $funcIndex, stackSize =", Stack.size)
17001704
Frames.pushFrameCalleeC(locals.size)
17011705
Frames.pushFrameCalleeS(locals)
17021706
// the return instruction is also stack polymorphic
@@ -1718,14 +1722,14 @@ trait StagedWasmEvaluator extends SAIOps
17181722
val callee = evalFunc(ty, body, funcIndex, ty.inps, bodyLocals)
17191723
// Predef.println(s"[DEBUG] locals size: ${locals.size}")
17201724
withBlock {
1721-
info("Taking arguments from stack to call function at ", funcIndex)
1725+
infoWhen("CALL", s"Taking arguments from stack to call function at ", funcIndex)
17221726
val newCtx = ctx.take(ty.inps.size)
17231727
val argsC = Stack.takeC(ty.inps)
17241728
val argsS = Stack.takeS(ty.inps)
17251729
// We make a new trail by `restK`, since function creates a new block to escape
17261730
// (more or less like `return`)
17271731
val restK: Rep[Cont[Unit]] = topFun((_: Rep[Unit]) => {
1728-
info(s"Exiting the function at $funcIndex, stackSize =", Stack.size)
1732+
infoWhen("CALL", s"Returning from the function at $funcIndex, stackSize =", Stack.size)
17291733
Frames.popFrameCallerC(ty.inps.size)
17301734
Frames.popFrameCallerS(ty.inps.size)
17311735
eval(rest, kont, trail)(newCtx.copy(stackTypes = ty.out.reverse ++ ctx.stackTypes.drop(ty.inps.size)))

0 commit comments

Comments
 (0)