Merge branch 'mplamann'
Conflicts: public/vm/c0vm.js
This commit is contained in:
@@ -90,6 +90,7 @@ var Bc0File = function (filename) {
|
|||||||
this.function_pool = [];
|
this.function_pool = [];
|
||||||
for (var i = 0; i < this.function_count; i++) {
|
for (var i = 0; i < this.function_count; i++) {
|
||||||
this.function_pool.push(new FunctionInfo(stream));
|
this.function_pool.push(new FunctionInfo(stream));
|
||||||
|
this.function_pool[i].function_id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.native_count = stream.get_u2();
|
this.native_count = stream.get_u2();
|
||||||
|
|||||||
@@ -108,3 +108,46 @@ exports.NATIVE_STRING_TERMINATED = 92
|
|||||||
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
||||||
exports.NATIVE_STRING_TOLOWER = 94
|
exports.NATIVE_STRING_TOLOWER = 94
|
||||||
|
|
||||||
|
callbacks = {};
|
||||||
|
callbacks[exports.NATIVE_STRING_LENGTH] =
|
||||||
|
function(args) {
|
||||||
|
return args[0].length;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_TO_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var address = vm.heap.length;
|
||||||
|
vm.heap.push(args[0].length+1);
|
||||||
|
vm.heap.push(1);
|
||||||
|
for (var i = 0; i < args[0].length; i++) {
|
||||||
|
vm.heap.push(args[0][i]);
|
||||||
|
}
|
||||||
|
vm.heap.push(0);
|
||||||
|
return address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_FROM_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var i = args[0] + 2;
|
||||||
|
var result = "";
|
||||||
|
while (vm.heap[i] !== 0) {
|
||||||
|
result += vm.heap[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_CHR] =
|
||||||
|
function(args) {
|
||||||
|
return String.fromCharCode(args[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_ORD] =
|
||||||
|
function(args) {
|
||||||
|
if (typeof args[0] == "string")
|
||||||
|
return args[0].charCodeAt(0);
|
||||||
|
return args[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.default_callbacks = callbacks;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ var StackFrame = function(file, f) {
|
|||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.pc = 0;
|
this.pc = 0;
|
||||||
this.program = f.code;
|
this.program = f.code;
|
||||||
|
this.function_id = f.function_id;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
for (var i = 0; i < f.num_vars; i++)
|
for (var i = 0; i < f.num_vars; i++)
|
||||||
this.variables.push(0);
|
this.variables.push(0);
|
||||||
@@ -69,6 +70,8 @@ var ProgramState = function(parsed_file, callback_dict) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.breakpoints = [];
|
||||||
|
|
||||||
// Memory is just a big array of bytes, right?
|
// Memory is just a big array of bytes, right?
|
||||||
// "Allocation" is appending onto this array
|
// "Allocation" is appending onto this array
|
||||||
// A pointer to memory is an index into this array.
|
// A pointer to memory is an index into this array.
|
||||||
@@ -341,7 +344,7 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
log("Calling native function with index " + index + " with arguments " +
|
log("Calling native function with index " + index + " with arguments " +
|
||||||
arg_array);
|
arg_array);
|
||||||
this.push(native_function(arg_array));
|
this.push(native_function(arg_array, this));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Memory allocation operations:
|
// Memory allocation operations:
|
||||||
@@ -470,8 +473,11 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes in a parsed .bc0 file and runs it
|
ProgramState.prototype.set_breakpoint = function(function_index, opcode_index) {
|
||||||
function execute(file, callbacks, v) {
|
this.breakpoints.push([function_index, opcode_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize_vm(file, callbacks, v) {
|
||||||
verbose = typeof v !== 'undefined' ? v : true;
|
verbose = typeof v !== 'undefined' ? v : true;
|
||||||
log("Initializing with file " + file);
|
log("Initializing with file " + file);
|
||||||
|
|
||||||
@@ -481,25 +487,44 @@ function execute(file, callbacks, v) {
|
|||||||
|
|
||||||
log("Beginning execution");
|
log("Beginning execution");
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_vm(vm) {
|
||||||
while (true) {
|
while (true) {
|
||||||
var val = state.step();
|
for (breakpoint in vm.breakpoints) {
|
||||||
|
if (vm.frame.function_id == breakpoint[0] &&
|
||||||
|
vm.frame.pc == breakpoint[1]) {
|
||||||
|
console.log("Breakpoint reached!");
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = vm.step();
|
||||||
if (val !== undefined) return val;
|
if (val !== undefined) return val;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
console.log("Machine state:");
|
console.log("Machine vm:");
|
||||||
console.log(" Current Stack Frame:");
|
console.log(" Current Stack Frame:");
|
||||||
console.log(" Stack: " + state.frame.stack);
|
console.log(" Stack: " + vm.frame.stack);
|
||||||
console.log(" PC: " + state.frame.pc);
|
console.log(" PC: " + vm.frame.pc);
|
||||||
console.log(" Vars: " + state.frame.variables);
|
console.log(" Vars: " + vm.frame.variables);
|
||||||
// console.log(" Code: " + state.frame.program);
|
// console.log(" Code: " + vm.frame.program);
|
||||||
console.log(" Heap: " + state.heap);
|
console.log(" Heap: " + vm.heap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (at_breakpoint) {
|
// if (at_breakpoint) {
|
||||||
// save state (maybe in a global in this file?)
|
// save state (maybe in a global in this file?)
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
}
|
// Takes in a parsed .bc0 file and runs it
|
||||||
|
function execute(file, callbacks, v) {
|
||||||
|
var state = initialize_vm(file, callbacks, v);
|
||||||
|
return run_vm(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.execute = execute;
|
exports.execute = execute;
|
||||||
|
exports.initialize_vm = initialize_vm;
|
||||||
|
exports.run_vm = run_vm;
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ var Bc0File = function (filename) {
|
|||||||
this.function_pool = [];
|
this.function_pool = [];
|
||||||
for (var i = 0; i < this.function_count; i++) {
|
for (var i = 0; i < this.function_count; i++) {
|
||||||
this.function_pool.push(new FunctionInfo(stream));
|
this.function_pool.push(new FunctionInfo(stream));
|
||||||
|
this.function_pool[i].function_id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.native_count = stream.get_u2();
|
this.native_count = stream.get_u2();
|
||||||
@@ -267,6 +268,49 @@ exports.NATIVE_STRING_TERMINATED = 92
|
|||||||
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
||||||
exports.NATIVE_STRING_TOLOWER = 94
|
exports.NATIVE_STRING_TOLOWER = 94
|
||||||
|
|
||||||
|
callbacks = {};
|
||||||
|
callbacks[exports.NATIVE_STRING_LENGTH] =
|
||||||
|
function(args) {
|
||||||
|
return args[0].length;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_TO_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var address = vm.heap.length;
|
||||||
|
vm.heap.push(args[0].length+1);
|
||||||
|
vm.heap.push(1);
|
||||||
|
for (var i = 0; i < args[0].length; i++) {
|
||||||
|
vm.heap.push(args[0][i]);
|
||||||
|
}
|
||||||
|
vm.heap.push(0);
|
||||||
|
return address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_FROM_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var i = args[0] + 2;
|
||||||
|
var result = "";
|
||||||
|
while (vm.heap[i] !== 0) {
|
||||||
|
result += vm.heap[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_CHR] =
|
||||||
|
function(args) {
|
||||||
|
return String.fromCharCode(args[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_ORD] =
|
||||||
|
function(args) {
|
||||||
|
if (typeof args[0] == "string")
|
||||||
|
return args[0].charCodeAt(0);
|
||||||
|
return args[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.default_callbacks = callbacks;
|
||||||
|
|
||||||
},{}],4:[function(require,module,exports){
|
},{}],4:[function(require,module,exports){
|
||||||
op = require("./opcodes");
|
op = require("./opcodes");
|
||||||
@@ -313,6 +357,7 @@ var StackFrame = function(file, f) {
|
|||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.pc = 0;
|
this.pc = 0;
|
||||||
this.program = f.code;
|
this.program = f.code;
|
||||||
|
this.function_id = f.function_id;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
for (var i = 0; i < f.num_vars; i++)
|
for (var i = 0; i < f.num_vars; i++)
|
||||||
this.variables.push(0);
|
this.variables.push(0);
|
||||||
@@ -340,6 +385,8 @@ var ProgramState = function(parsed_file, callback_dict) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.breakpoints = [];
|
||||||
|
|
||||||
// Memory is just a big array of bytes, right?
|
// Memory is just a big array of bytes, right?
|
||||||
// "Allocation" is appending onto this array
|
// "Allocation" is appending onto this array
|
||||||
// A pointer to memory is an index into this array.
|
// A pointer to memory is an index into this array.
|
||||||
@@ -612,7 +659,7 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
log("Calling native function with index " + index + " with arguments " +
|
log("Calling native function with index " + index + " with arguments " +
|
||||||
arg_array);
|
arg_array);
|
||||||
this.push(native_function(arg_array));
|
this.push(native_function(arg_array, this));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Memory allocation operations:
|
// Memory allocation operations:
|
||||||
@@ -741,8 +788,11 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes in a parsed .bc0 file and runs it
|
ProgramState.prototype.set_breakpoint = function(function_index, opcode_index) {
|
||||||
function execute(file, callbacks, v) {
|
this.breakpoints.push([function_index, opcode_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize_vm(file, callbacks, v) {
|
||||||
verbose = typeof v !== 'undefined' ? v : true;
|
verbose = typeof v !== 'undefined' ? v : true;
|
||||||
log("Initializing with file " + file);
|
log("Initializing with file " + file);
|
||||||
|
|
||||||
@@ -752,28 +802,47 @@ function execute(file, callbacks, v) {
|
|||||||
|
|
||||||
log("Beginning execution");
|
log("Beginning execution");
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_vm(vm) {
|
||||||
while (true) {
|
while (true) {
|
||||||
var val = state.step();
|
for (breakpoint in vm.breakpoints) {
|
||||||
|
if (vm.frame.function_id == breakpoint[0] &&
|
||||||
|
vm.frame.pc == breakpoint[1]) {
|
||||||
|
console.log("Breakpoint reached!");
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = vm.step();
|
||||||
if (val !== undefined) return val;
|
if (val !== undefined) return val;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
console.log("Machine state:");
|
console.log("Machine vm:");
|
||||||
console.log(" Current Stack Frame:");
|
console.log(" Current Stack Frame:");
|
||||||
console.log(" Stack: " + state.frame.stack);
|
console.log(" Stack: " + vm.frame.stack);
|
||||||
console.log(" PC: " + state.frame.pc);
|
console.log(" PC: " + vm.frame.pc);
|
||||||
console.log(" Vars: " + state.frame.variables);
|
console.log(" Vars: " + vm.frame.variables);
|
||||||
// console.log(" Code: " + state.frame.program);
|
// console.log(" Code: " + vm.frame.program);
|
||||||
console.log(" Heap: " + state.heap);
|
console.log(" Heap: " + vm.heap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (at_breakpoint) {
|
// if (at_breakpoint) {
|
||||||
// save state (maybe in a global in this file?)
|
// save state (maybe in a global in this file?)
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
}
|
// Takes in a parsed .bc0 file and runs it
|
||||||
|
function execute(file, callbacks, v) {
|
||||||
|
var state = initialize_vm(file, callbacks, v);
|
||||||
|
return run_vm(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.execute = execute;
|
exports.execute = execute;
|
||||||
|
exports.initialize_vm = initialize_vm;
|
||||||
|
exports.run_vm = run_vm;
|
||||||
|
|
||||||
},{"./opcodes":6}],5:[function(require,module,exports){
|
},{"./opcodes":6}],5:[function(require,module,exports){
|
||||||
parser = require("./bytecode-parser");
|
parser = require("./bytecode-parser");
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ parser = require("../src/bytecode-parser.js");
|
|||||||
c0vm = require("../src/c0vm.js");
|
c0vm = require("../src/c0vm.js");
|
||||||
c0ffi = require("../src/c0ffi.js");
|
c0ffi = require("../src/c0ffi.js");
|
||||||
|
|
||||||
var callbacks = {}
|
var callbacks = c0ffi.default_callbacks;
|
||||||
|
console.log("Initial callbacks: " + callbacks[c0ffi.NATIVE_STRING_LENGTH](["hi"]));
|
||||||
var printout = "";
|
var printout = "";
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
||||||
@@ -20,30 +21,6 @@ callbacks[c0ffi.NATIVE_PRINTLN] = function(args) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_LENGTH] = function(args) {
|
|
||||||
return args[0].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_TO_CHARARRAY] = function(args) {
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_FROM_CHARARRAY] = function(args) {
|
|
||||||
console.log("string_from_chararray: " + args);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_CHAR_CHR] = function(args) {
|
|
||||||
return String.fromCharCode(args[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_CHAR_ORD] = function(args) {
|
|
||||||
console.log("native_car_ord: " + args);
|
|
||||||
if (typeof args[0] == "string")
|
|
||||||
return args[0].charCodeAt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function doTest(filename, expected_result) {
|
function doTest(filename, expected_result) {
|
||||||
return function(test) {
|
return function(test) {
|
||||||
var result = c0vm.execute(parser.parse(filename), callbacks, false);
|
var result = c0vm.execute(parser.parse(filename), callbacks, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user