Skip to content

Commit

Permalink
log contents of fields as written to storage after constructor calls (#…
Browse files Browse the repository at this point in the history
…417)

* first pass at logging, todo

* emit logs for both primitve and non-primitive fields

* updating test desecriptions; code scraps

* making logging in the tracers a little bit more modular

* moving code back into the right case branch
  • Loading branch information
ivoysey committed Feb 17, 2022
1 parent 4626c1c commit 56bec1f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
4 changes: 2 additions & 2 deletions resources/tests/GanacheTests/tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,14 @@
"file": "SetGetLogs.obs",
"expected": "15",
"trans" : "main_sgl",
"logged" : [256, 288, 320],
"logged" : [0, 224, 224],
"shows_that_we_support": "simple set-get with tracers that emit values to the logs. this shows that the harness can read logs; the values logged are immaterial"
},
{
"file": "SetGetConstructorField.obs",
"expected": "12",
"trans" : "main",
"logged" : [224, 224, 224],
"logged" : [0,0,0],
"shows_that_we_support": "set-get with a field so that the emitted tracer is not trivial, and that uses the constructor for that field "
}
]
Expand Down
42 changes: 31 additions & 11 deletions src/main/scala/edu/cmu/cs/obsidian/codegen/CodeGenYul.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ object CodeGenYul extends CodeGenerator {
}

def writeTracers(ct: SymbolTable, name: String): Seq[FunctionDefinition] = {
// this is a stand in for a more robust mechanism for choosing when to emit logs.
// we'll want to be able to turn it off to do performance testing in the future.
val emit_logs: Boolean = true

val c: Contract = ct.contract(name) match {
case Some(value) => value.contract
case None => throw new RuntimeException()
Expand All @@ -125,23 +129,41 @@ object CodeGenYul extends CodeGenerator {
d match {
case Field(_, typ, fname, _) =>
val loc = fieldFromThis(ct.contractLookup(name), fname)
val log_temp = nextTemp()
val log =
if (emit_logs) {
Seq(LineComment("logging"),
// allocate memory to log from
decl_1exp(log_temp, apply("allocate_memory", intlit(32))),
// load what we just wrote to storage to that location
ExpressionStatement(apply("mstore", log_temp, apply("sload", loc))),
// emit the log
ExpressionStatement(apply("log0", log_temp, intlit(32)))
)
} else {
Seq()
}
val load = Seq(
//sstore(add(this,offset), mload(add(this,offset)))
LineComment("loading"),
ExpressionStatement(apply("sstore", loc, apply("mload", loc))))


typ match {
case t: NonPrimitiveType => t match {
case ContractReferenceType(contractType, _, _) =>
body = body ++ Seq(
//sstore(add(this,offset), mload(add(this,offset)))
ExpressionStatement(apply("sstore", loc, apply("mload", loc))),
ExpressionStatement(apply(nameTracer(contractType.contractName), loc))
)
body = body ++ load ++ log ++
Seq(
LineComment("traversal"),
ExpressionStatement(apply(nameTracer(contractType.contractName), loc))
)
// todo: this recursive call may not be needed if we generate tracers
// for every contract in the program
others = others ++ writeTracers(ct, contractType.contractName)
case _ => Seq()
}
case _: PrimitiveType =>
body = body :+
//sstore(add(this,offset), mload(add(this,offset)))
ExpressionStatement(apply("sstore", loc, apply("mload", loc)))
body = body ++ load ++ log
case _ => Seq()
}
case _ => Seq()
Expand All @@ -151,9 +173,7 @@ object CodeGenYul extends CodeGenerator {
FunctionDefinition(name = nameTracer(name),
parameters = Seq(TypedName("this", YATAddress())),
returnVariables = Seq(),
body = Block(Seq(
ExpressionStatement(apply("log0", intlit(64), intlit(32)))
) ++ body :+ Leave())
body = Block(body :+ Leave())
) +: others.distinctBy(fd => fd.name)
}

Expand Down

0 comments on commit 56bec1f

Please sign in to comment.