Skip to content

Commit

Permalink
[ovm2] Implement push/pop/unwind of the block stack.
Browse files Browse the repository at this point in the history
fib_iterative.py now works!

Also add continue_.py and make it work.

- Fix bug in compare.  Operands were reversed.
- Implement BINARY_MODULO bytecode.
  • Loading branch information
Andy Chu committed Nov 9, 2018
1 parent 345497e commit a77cda0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 13 deletions.
7 changes: 7 additions & 0 deletions opy/gold/continue_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/python
i = 0
while i < 20:
i = i + 1
if i % 2 == 0:
continue
print(i)
86 changes: 73 additions & 13 deletions ovm2/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ bool Load(FILE* f, OHeap* heap) {
return true;
}

enum class BlockType {
enum class BlockType : uint8_t {
Loop,
Except,
Finally,
Expand All @@ -531,8 +531,8 @@ enum class BlockType {
// Like PyTryBlock in frameobject.h
struct Block {
BlockType type;
int level; // stack level
int handler; // jump address. TODO: Rename?
uint8_t level; // VALUE stack level to pop to.
uint16_t jump_target; // Called 'handler' in CPython.
};

// Implement hash and equality functors for unordered_set.
Expand Down Expand Up @@ -598,11 +598,6 @@ class Frame {
inline void JumpRelative(int offset) {
last_i_ += offset; // Is this correct?
}
void PushBlock(BlockType type) {
};
void PopBlock() {
};

const Code& co_; // public for now
vector<Handle> value_stack_;
vector<Block> block_stack_;
Expand Down Expand Up @@ -694,6 +689,7 @@ Why VM::RunFrame(Frame* frame) {
Tuple consts = co.consts();

vector<Handle>& value_stack = frame->value_stack_;
vector<Block>& block_stack = frame->block_stack_;

CodeDebugString(co, heap_); // Show what code we're running.

Expand Down Expand Up @@ -826,7 +822,7 @@ Why VM::RunFrame(Frame* frame) {
// CPython inlines cmp(int, int) too.
int64_t a, b;
bool result;
if (heap_->AsInt(w, &a) && heap_->AsInt(v, &b)) {
if (heap_->AsInt(v, &a) && heap_->AsInt(w, &b)) {
switch (oparg) {
case CompareOp::LT: result = a < b; break;
case CompareOp::LE: result = a <= b; break;
Expand Down Expand Up @@ -869,6 +865,32 @@ Why VM::RunFrame(Frame* frame) {
break;
}

case BINARY_MODULO: {
Handle w = value_stack.back();
value_stack.pop_back();
Handle v = value_stack.back();
value_stack.pop_back();

Str s;
if (heap_->AsStr(v, &s)) {
// TODO: Do string formatting
assert(0);
}

int64_t a, b, result;
if (heap_->AsInt(v, &a) && heap_->AsInt(w, &b)) {
result = a % b;
Handle result_h = heap_->NewInt(result);
value_stack.push_back(result_h);
break;
}

// TODO: TypeError
assert(0);

break;
}

//
// Jumps
//
Expand Down Expand Up @@ -898,12 +920,17 @@ Why VM::RunFrame(Frame* frame) {
// Control Flow
//

case SETUP_LOOP:
frame->PushBlock(BlockType::Loop);
case SETUP_LOOP: {
Block b;
b.type = BlockType::Loop;
b.level = value_stack.size();
b.jump_target = frame->last_i_ + oparg; // oparg is relative jump target
block_stack.push_back(b);
break;
}

case POP_BLOCK:
frame->PopBlock();
block_stack.pop_back();
break;

case BREAK_LOOP:
Expand All @@ -917,6 +944,40 @@ Why VM::RunFrame(Frame* frame) {
why = Why::Return;
break;

default:
log("Unhandled instruction");
break;

}

while (why != Why::Not && block_stack.size()) {
assert(why != Why::Yield);
Block b = block_stack.back();

// TODO: This code appears to be unused! continue compiles as
// POP_JUMP_IF_FALSE!
if (b.type == BlockType::Loop && why == Why::Continue) {
assert(0);
// TODO: retval? I guess it's popped off the stack.
frame->JumpTo(retval);
}
block_stack.pop_back();

// Unwind value stack to the saved level.
while (value_stack.size() > b.level) {
value_stack.pop_back();
}

if (b.type == BlockType::Loop && why == Why::Break) {
why = Why::Not;
frame->JumpTo(b.jump_target);
}

if (b.type == BlockType::Finally ||
b.type == BlockType::Except && why == Why::Exception ||
b.type == BlockType::With) {
assert(0);
}
}

// TODO: Handle the block stack. Break should JUMP to the location in the
Expand Down Expand Up @@ -981,7 +1042,6 @@ int main(int argc, char **argv) {
return 1;
}

log("cell = %d", sizeof(Cell));
assert(sizeof(Cell) == 16);

OHeap heap;
Expand Down
5 changes: 5 additions & 0 deletions ovm2/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ hello-py3() {
ovm2-main opy/gold/hello_py3.py
}

# This tickled a couple bugs
continue_() {
ovm2-main opy/gold/continue_.py
}

# This works
fib-iterative() {
ovm2-main $FIB_I
Expand Down

0 comments on commit a77cda0

Please sign in to comment.