From 1510ef47902ed1201c398da54bf2bf83bbd6a61f Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Tue, 8 Aug 2017 18:51:02 +0200 Subject: [PATCH 1/6] Parse wordcodes instead of bytecodes Single wordcode is 2 bytes wide and consists of an opcode and its argument (or 0 if no argument is used) --- batavia/VirtualMachine.js | 69 ++++++++++++++++++++++++++++++--------- batavia/core/constants.js | 3 +- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/batavia/VirtualMachine.js b/batavia/VirtualMachine.js index 14562e01e..63ea0ef1c 100644 --- a/batavia/VirtualMachine.js +++ b/batavia/VirtualMachine.js @@ -757,7 +757,7 @@ VirtualMachine.prototype.create_traceback = function() { VirtualMachine.prototype.unpack_code = function(code) { var pos = 0 var unpacked_code = [] - var args + var args = [] var extra = 0 var lo var hi @@ -768,6 +768,7 @@ VirtualMachine.prototype.unpack_code = function(code) { var opcode = code.co_code.val[pos++] // next opcode has 4-byte argument effectively. + // TODO 3.6 if (opcode === dis.EXTENDED_ARG) { lo = code.co_code.val[pos++] hi = code.co_code.val[pos++] @@ -804,14 +805,17 @@ VirtualMachine.prototype.unpack_code = function(code) { continue } - if (opcode < dis.HAVE_ARGUMENT) { - args = [] - } else { + var intArg + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + intArg = code.co_code.val[pos++] + } else if (opcode >= dis.HAVE_ARGUMENT) { lo = code.co_code.val[pos++] hi = code.co_code.val[pos++] - var intArg = lo | (hi << 8) | extra + intArg = lo | (hi << 8) | extra extra = 0 // use extended arg if present + } + if (opcode >= dis.HAVE_ARGUMENT) { // XXX 3.6? if (opcode in dis.hasconst) { args = [code.co_consts[intArg]] } else if (opcode in dis.hasfree) { @@ -1788,11 +1792,34 @@ VirtualMachine.prototype.byte_WITH_CLEANUP_FINISH = function() { } } -VirtualMachine.prototype.byte_MAKE_FUNCTION = function(argc) { +VirtualMachine.prototype.byte_MAKE_FUNCTION = function(arg) { var name = this.pop() var code = this.pop() - var defaults = this.popn(argc) - var fn = new types.Function(name, code, this.frame.f_globals, defaults, null, this) + var closure = null + var annotations = null // eslint-disable-line no-unused-vars + var kwdefaults = null // eslint-disable-line no-unused-vars + var defaults = null + + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + if (arg & 8) { + closure = this.pop() + } + if (arg & 4) { + // XXX unused + annotations = this.pop() + } + if (arg & 2) { + // XXX unused + kwdefaults = this.pop() + } + if (arg & 1) { + defaults = this.pop() + } + } else { + defaults = this.popn(arg) + } + + var fn = new types.Function(name, code, this.frame.f_globals, defaults, closure, this) this.push(fn) } @@ -1818,6 +1845,14 @@ VirtualMachine.prototype.byte_CALL_FUNCTION_VAR = function(arg) { } VirtualMachine.prototype.byte_CALL_FUNCTION_KW = function(arg) { + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + var kw = this.pop() + var namedargs = new types.JSDict() + for (let i = kw.length - 1; i >= 0; i--) { + namedargs[kw[i]] = this.pop() + } + return this.call_function(arg - kw.length, null, namedargs) + } var kwargs = this.pop() return this.call_function(arg, null, kwargs) } @@ -1828,14 +1863,17 @@ VirtualMachine.prototype.byte_CALL_FUNCTION_VAR_KW = function(arg) { } VirtualMachine.prototype.call_function = function(arg, args, kwargs) { - // @arg is based on - // https://docs.python.org/3/library/dis.html#opcode-CALL_FUNCTION - var lenKw = Math.floor(arg / 256) - var lenPos = arg % 256 + var lenPos var namedargs = new types.JSDict() - for (var i = 0; i < lenKw; i++) { - var items = this.popn(2) - namedargs[items[0]] = items[1] + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + lenPos = arg + } else { + var lenKw = Math.floor(arg / 256) + lenPos = arg % 256 + for (var i = 0; i < lenKw; i++) { + var items = this.popn(2) + namedargs[items[0]] = items[1] + } } if (kwargs) { for (let kv of kwargs.items()) { @@ -1848,7 +1886,6 @@ VirtualMachine.prototype.call_function = function(arg, args, kwargs) { posargs.push(elem) } } - var func = this.pop() if (func.__call__ !== undefined) { func = func.__call__.bind(func) diff --git a/batavia/core/constants.js b/batavia/core/constants.js index 818130651..de5b1da48 100644 --- a/batavia/core/constants.js +++ b/batavia/core/constants.js @@ -13,7 +13,8 @@ var constants = { 'BATAVIA_MAGIC_34': String.fromCharCode(238, 12, 13, 10), 'BATAVIA_MAGIC_35a0': String.fromCharCode(248, 12, 13, 10), 'BATAVIA_MAGIC_35': String.fromCharCode(22, 13, 13, 10), - 'BATAVIA_MAGIC_353': String.fromCharCode(23, 13, 13, 10) + 'BATAVIA_MAGIC_353': String.fromCharCode(23, 13, 13, 10), + 'BATAVIA_MAGIC_36': String.fromCharCode(51, 13, 13, 10) } module.exports = constants From 4d86b52ecc03f5259d80b8f67e1216b3ead097a7 Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Sat, 12 Aug 2017 19:18:48 +0200 Subject: [PATCH 2/6] Implement CALL_FUNCTION_EX opcode Prior to 3.6 it was called CALL_FUNCTION_VAR_KW and operated in a slightly different manner --- batavia/VirtualMachine.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/batavia/VirtualMachine.js b/batavia/VirtualMachine.js index 63ea0ef1c..e480a0a18 100644 --- a/batavia/VirtualMachine.js +++ b/batavia/VirtualMachine.js @@ -1858,8 +1858,18 @@ VirtualMachine.prototype.byte_CALL_FUNCTION_KW = function(arg) { } VirtualMachine.prototype.byte_CALL_FUNCTION_VAR_KW = function(arg) { - var items = this.popn(2) - return this.call_function(arg, items[0], items[1]) + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + // opcode: CALL_FUNCTION_EX + var kwargs + if (arg & 1) { + kwargs = this.pop() + } + var args = this.pop() + return this.call_function(0, args, kwargs) + } else { + var items = this.popn(2) + return this.call_function(arg, items[0], items[1]) + } } VirtualMachine.prototype.call_function = function(arg, args, kwargs) { From 44adeb24341be9e7e2226807c0af12f66ad6d8ff Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Tue, 15 Aug 2017 14:43:33 +0200 Subject: [PATCH 3/6] EXTENDED_ARG, BUILD_MAP and BUILD_CONST_KEY_MAP --- batavia/VirtualMachine.js | 102 ++++++++++++++++++++++------------- batavia/modules/dis.js | 5 +- beekeeper.yml | 7 +-- tests/datatypes/test_dict.py | 2 +- 4 files changed, 73 insertions(+), 43 deletions(-) diff --git a/batavia/VirtualMachine.js b/batavia/VirtualMachine.js index e480a0a18..303a94e12 100644 --- a/batavia/VirtualMachine.js +++ b/batavia/VirtualMachine.js @@ -768,54 +768,67 @@ VirtualMachine.prototype.unpack_code = function(code) { var opcode = code.co_code.val[pos++] // next opcode has 4-byte argument effectively. - // TODO 3.6 if (opcode === dis.EXTENDED_ARG) { - lo = code.co_code.val[pos++] - hi = code.co_code.val[pos++] - extra = (lo << 16) | (hi << 24) - // emulate four NOPs - unpacked_code[opcode_start_pos] = { - 'opoffset': opcode_start_pos, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } - unpacked_code[opcode_start_pos + 1] = { - 'opoffset': opcode_start_pos + 1, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } - unpacked_code[opcode_start_pos + 2] = { - 'opoffset': opcode_start_pos + 2, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } - unpacked_code[opcode_start_pos + 3] = { - 'opoffset': opcode_start_pos + 3, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + extra = code.co_code.val[pos++] << 8 + unpacked_code[opcode_start_pos] = { + 'opoffset': opcode_start_pos, + 'opcode': dis.NOP, + 'op_method': this.dispatch_table[dis.NOP], + 'args': [], + 'next_pos': pos + } + } else { + lo = code.co_code.val[pos++] + hi = code.co_code.val[pos++] + extra = (lo << 16) | (hi << 24) + // emulate four NOPs + unpacked_code[opcode_start_pos] = { + 'opoffset': opcode_start_pos, + 'opcode': dis.NOP, + 'op_method': this.dispatch_table[dis.NOP], + 'args': [], + 'next_pos': pos + } + unpacked_code[opcode_start_pos + 1] = { + 'opoffset': opcode_start_pos + 1, + 'opcode': dis.NOP, + 'op_method': this.dispatch_table[dis.NOP], + 'args': [], + 'next_pos': pos + } + unpacked_code[opcode_start_pos + 2] = { + 'opoffset': opcode_start_pos + 2, + 'opcode': dis.NOP, + 'op_method': this.dispatch_table[dis.NOP], + 'args': [], + 'next_pos': pos + } + unpacked_code[opcode_start_pos + 3] = { + 'opoffset': opcode_start_pos + 3, + 'opcode': dis.NOP, + 'op_method': this.dispatch_table[dis.NOP], + 'args': [], + 'next_pos': pos + } } continue } var intArg if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { - intArg = code.co_code.val[pos++] - } else if (opcode >= dis.HAVE_ARGUMENT) { - lo = code.co_code.val[pos++] - hi = code.co_code.val[pos++] - intArg = lo | (hi << 8) | extra - extra = 0 // use extended arg if present + intArg = code.co_code.val[pos++] | extra + extra = 0 } if (opcode >= dis.HAVE_ARGUMENT) { // XXX 3.6? + if (constants.BATAVIA_MAGIC !== constants.BATAVIA_MAGIC_36) { + lo = code.co_code.val[pos++] + hi = code.co_code.val[pos++] + intArg = lo | (hi << 8) | extra + extra = 0 // use extended arg if present + } + if (opcode in dis.hasconst) { args = [code.co_consts[intArg]] } else if (opcode in dis.hasfree) { @@ -1408,6 +1421,7 @@ VirtualMachine.prototype.byte_BUILD_MAP = function(size) { switch (constants.BATAVIA_MAGIC) { case constants.BATAVIA_MAGIC_35: case constants.BATAVIA_MAGIC_353: + case constants.BATAVIA_MAGIC_36: var items = this.popn(size * 2) var dict = new types.Dict() @@ -1432,6 +1446,18 @@ VirtualMachine.prototype.byte_BUILD_MAP = function(size) { } } +VirtualMachine.prototype.byte_BUILD_CONST_KEY_MAP = function(size) { + var keys = this.pop() + var values = this.popn(size) + var dict = new types.Dict() + + for (var i = 0; i < values.length; i += 1) { + dict.__setitem__(keys[i], values[i]) + } + this.push(dict) + return +} + VirtualMachine.prototype.byte_STORE_MAP = function() { switch (constants.BATAVIA_MAGIC) { case constants.BATAVIA_MAGIC_35: diff --git a/batavia/modules/dis.js b/batavia/modules/dis.js index 5e622b9cb..01571e8be 100644 --- a/batavia/modules/dis.js +++ b/batavia/modules/dis.js @@ -112,7 +112,7 @@ def_binary_op('BINARY_OR', 66) def_inplace_op('INPLACE_POWER', 67) def_op('GET_ITER', 68) -// introduced in Python 3.5+ +// Introduced in Python 3.5 def_op('GET_YIELD_FROM_ITER', 69) def_op('PRINT_EXPR', 70) @@ -217,4 +217,7 @@ dis.hasfree[148] = 148 def_op('EXTENDED_ARG', 144) dis.EXTENDED_ARG = 144 +// Introduced in Python 3.6 +def_op('BUILD_CONST_KEY_MAP', 156) + module.exports = dis diff --git a/beekeeper.yml b/beekeeper.yml index c2f1ffef6..f8f5cb3fa 100644 --- a/beekeeper.yml +++ b/beekeeper.yml @@ -18,9 +18,10 @@ pull_request: name: Python 3.5 tests task: batavia-py35 critical: False - # - py3.6: - # name: Python 3.6 tests - # task: batavia-py36 + - py3.6: + name: Python 3.6 tests + task: batavia-py36 + critical: False profile: hi-cpu push: - smoke-test: diff --git a/tests/datatypes/test_dict.py b/tests/datatypes/test_dict.py index 941e0e801..2a41cbb0a 100644 --- a/tests/datatypes/test_dict.py +++ b/tests/datatypes/test_dict.py @@ -37,7 +37,7 @@ def test_creation(self): self.assertCodeExecution(""" x = {1: 2, '1': 1} print(sorted(x.items())) - """, substitutions={'str() < int()': ['int() < str()']}) + """, substitutions={'str() < int()': ['int() < str()']}) def test_getitem(self): # Simple existent key From 675ac688a48a528bbc219143d07ea13cf05065f5 Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Wed, 16 Aug 2017 14:15:41 +0200 Subject: [PATCH 4/6] Refactor 3.6 code to be less intertwined with rest --- batavia/VirtualMachine.js | 270 ++++++++++++++++++++++++-------------- batavia/types/Bytes.js | 2 +- 2 files changed, 169 insertions(+), 103 deletions(-) diff --git a/batavia/VirtualMachine.js b/batavia/VirtualMachine.js index 303a94e12..de88a6885 100644 --- a/batavia/VirtualMachine.js +++ b/batavia/VirtualMachine.js @@ -755,21 +755,21 @@ VirtualMachine.prototype.create_traceback = function() { * unpacked into operations with their respective args */ VirtualMachine.prototype.unpack_code = function(code) { - var pos = 0 - var unpacked_code = [] - var args = [] - var extra = 0 - var lo - var hi + if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + // Python 3.6+, 2-byte opcodes + + let pos = 0 + let unpacked_code = [] + let args = [] + let extra = 0 - while (pos < code.co_code.val.length) { - var opcode_start_pos = pos + while (pos < code.co_code.val.length) { + let opcode_start_pos = pos - var opcode = code.co_code.val[pos++] + let opcode = code.co_code.val[pos++] - // next opcode has 4-byte argument effectively. - if (opcode === dis.EXTENDED_ARG) { - if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { + // next opcode has 4-byte argument effectively. + if (opcode === dis.EXTENDED_ARG) { extra = code.co_code.val[pos++] << 8 unpacked_code[opcode_start_pos] = { 'opoffset': opcode_start_pos, @@ -778,7 +778,62 @@ VirtualMachine.prototype.unpack_code = function(code) { 'args': [], 'next_pos': pos } - } else { + continue + } + + let intArg = code.co_code.val[pos++] | extra + extra = 0 + + if (opcode >= dis.HAVE_ARGUMENT) { + if (opcode in dis.hasconst) { + args = [code.co_consts[intArg]] + } else if (opcode in dis.hasfree) { + if (intArg < code.co_cellvars.length) { + args = [code.co_cellvars[intArg]] + } else { + let var_idx = intArg - code.co_cellvars.length + args = [code.co_freevars[var_idx]] + } + } else if (opcode in dis.hasname) { + args = [code.co_names[intArg]] + } else if (opcode in dis.hasjrel) { + args = [pos + intArg] + } else if (opcode in dis.hasjabs) { + args = [intArg] + } else if (opcode in dis.haslocal) { + args = [code.co_varnames[intArg]] + } else { + args = [intArg] + } + } + + unpacked_code[opcode_start_pos] = { + 'opoffset': opcode_start_pos, + 'opcode': opcode, + 'op_method': this.dispatch_table[opcode], + 'args': args, + 'next_pos': pos + } + } + + code.co_unpacked_code = unpacked_code + } else { + // Until 3.6 Python had variable width opcodes + + let pos = 0 + let unpacked_code = [] + let args + let extra = 0 + let lo + let hi + + while (pos < code.co_code.val.length) { + let opcode_start_pos = pos + + let opcode = code.co_code.val[pos++] + + // next opcode has 4-byte argument effectively. + if (opcode === dis.EXTENDED_ARG) { lo = code.co_code.val[pos++] hi = code.co_code.val[pos++] extra = (lo << 16) | (hi << 24) @@ -811,56 +866,50 @@ VirtualMachine.prototype.unpack_code = function(code) { 'args': [], 'next_pos': pos } + continue } - continue - } - - var intArg - if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { - intArg = code.co_code.val[pos++] | extra - extra = 0 - } - if (opcode >= dis.HAVE_ARGUMENT) { // XXX 3.6? - if (constants.BATAVIA_MAGIC !== constants.BATAVIA_MAGIC_36) { + if (opcode < dis.HAVE_ARGUMENT) { + args = [] + } else { lo = code.co_code.val[pos++] hi = code.co_code.val[pos++] - intArg = lo | (hi << 8) | extra + let intArg = lo | (hi << 8) | extra extra = 0 // use extended arg if present - } - if (opcode in dis.hasconst) { - args = [code.co_consts[intArg]] - } else if (opcode in dis.hasfree) { - if (intArg < code.co_cellvars.length) { - args = [code.co_cellvars[intArg]] + if (opcode in dis.hasconst) { + args = [code.co_consts[intArg]] + } else if (opcode in dis.hasfree) { + if (intArg < code.co_cellvars.length) { + args = [code.co_cellvars[intArg]] + } else { + let var_idx = intArg - code.co_cellvars.length + args = [code.co_freevars[var_idx]] + } + } else if (opcode in dis.hasname) { + args = [code.co_names[intArg]] + } else if (opcode in dis.hasjrel) { + args = [pos + intArg] + } else if (opcode in dis.hasjabs) { + args = [intArg] + } else if (opcode in dis.haslocal) { + args = [code.co_varnames[intArg]] } else { - var var_idx = intArg - code.co_cellvars.length - args = [code.co_freevars[var_idx]] + args = [intArg] } - } else if (opcode in dis.hasname) { - args = [code.co_names[intArg]] - } else if (opcode in dis.hasjrel) { - args = [pos + intArg] - } else if (opcode in dis.hasjabs) { - args = [intArg] - } else if (opcode in dis.haslocal) { - args = [code.co_varnames[intArg]] - } else { - args = [intArg] } - } - unpacked_code[opcode_start_pos] = { - 'opoffset': opcode_start_pos, - 'opcode': opcode, - 'op_method': this.dispatch_table[opcode], - 'args': args, - 'next_pos': pos + unpacked_code[opcode_start_pos] = { + 'opoffset': opcode_start_pos, + 'opcode': opcode, + 'op_method': this.dispatch_table[opcode], + 'args': args, + 'next_pos': pos + } } - } - code.co_unpacked_code = unpacked_code + code.co_unpacked_code = unpacked_code + } } VirtualMachine.prototype.run_code = function(kwargs) { @@ -1026,7 +1075,7 @@ VirtualMachine.prototype.run_frame = function(frame) { while (!why) { operation = this.frame.f_code.co_unpacked_code[this.frame.f_lasti] - var opname = dis.opname[operation.opcode] // eslint-disable-line no-unused-vars + var opname = dis.opname[operation.opcode] // eslint-disable-line no-unused-vars // advance f_lasti to next operation. If the operation is a jump, then this // pointer will be overwritten during the operation's execution. @@ -1244,7 +1293,7 @@ VirtualMachine.prototype.byte_COMPARE_OP = function(opnum) { // the comparison method in a different way, because we can't // bind the operator methods to the null instance. - if (opnum === 6) { // x in None + if (opnum === 6) { // x in None if (items[1] === null) { result = types.NoneType.__contains__(items[0]) } if (items[1].__contains__) { @@ -1253,7 +1302,7 @@ VirtualMachine.prototype.byte_COMPARE_OP = function(opnum) { result = (items[0] in items[1]) } } else if (opnum === 7) { - if (items[1] === null) { // x not in None + if (items[1] === null) { // x not in None result = types.NoneType.__contains__(items[0]).__not__() } else if (items[1].__contains__) { result = items[1].__contains__(items[0]).__not__() @@ -1262,31 +1311,31 @@ VirtualMachine.prototype.byte_COMPARE_OP = function(opnum) { } } else if (items[0] === null) { switch (opnum) { - case 0: // < + case 0: // < result = types.NoneType.__lt__(items[1]) break - case 1: // <= + case 1: // <= result = types.NoneType.__le__(items[1]) break - case 2: // == + case 2: // == result = types.NoneType.__eq__(items[1]) break - case 3: // != + case 3: // != result = types.NoneType.__ne__(items[1]) break - case 4: // > + case 4: // > result = types.NoneType.__gt__(items[1]) break - case 5: // >= + case 5: // >= result = types.NoneType.__ge__(items[1]) break - case 8: // is + case 8: // is result = items[1] === null break - case 9: // is not + case 9: // is not result = items[1] !== null break - case 10: // exception + case 10: // exception result = items[1] === null break default: @@ -1294,55 +1343,55 @@ VirtualMachine.prototype.byte_COMPARE_OP = function(opnum) { } } else { switch (opnum) { - case 0: // < + case 0: // < if (items[0].__lt__) { result = items[0].__lt__(items[1]) } else { result = items[0] < items[1] } break - case 1: // <= + case 1: // <= if (items[0].__le__) { result = items[0].__le__(items[1]) } else { result = items[0] <= items[1] } break - case 2: // == + case 2: // == if (items[0].__eq__) { result = items[0].__eq__(items[1]) } else { result = items[0] === items[1] } break - case 3: // != + case 3: // != if (items[0].__ne__) { result = items[0].__ne__(items[1]) } else { result = items[0] !== items[1] } break - case 4: // > + case 4: // > if (items[0].__gt__) { result = items[0].__gt__(items[1]) } else { result = items[0] > items[1] } break - case 5: // >= + case 5: // >= if (items[0].__ge__) { result = items[0].__ge__(items[1]) } else { result = items[0] >= items[1] } break - case 8: // is + case 8: // is result = items[0] === items[1] break - case 9: // is not + case 9: // is not result = items[0] !== items[1] break - case 10: // exception match + case 10: // exception match result = types.issubclass(items[0], items[1]) break default: @@ -1455,7 +1504,6 @@ VirtualMachine.prototype.byte_BUILD_CONST_KEY_MAP = function(size) { dict.__setitem__(keys[i], values[i]) } this.push(dict) - return } VirtualMachine.prototype.byte_STORE_MAP = function() { @@ -1542,7 +1590,7 @@ VirtualMachine.prototype.byte_PRINT_ITEM = function() { } VirtualMachine.prototype.byte_PRINT_ITEM_TO = function() { - this.pop() // FIXME - the to value is ignored. + this.pop() // FIXME - the to value is ignored. var item = this.pop() this.print_item(item) } @@ -1552,20 +1600,20 @@ VirtualMachine.prototype.byte_PRINT_NEWLINE = function() { } VirtualMachine.prototype.byte_PRINT_NEWLINE_TO = function() { - var to = this.pop() // FIXME - this is ignored. + var to = this.pop() // FIXME - this is ignored. this.print_newline(to) } VirtualMachine.prototype.print_item = function(item, to) { // if (to === undefined) { - // to = sys.stdout; // FIXME - the to value is ignored. + // to = sys.stdout; // FIXME - the to value is ignored. // } sys.stdout.write(item) } VirtualMachine.prototype.print_newline = function(to) { // if (to === undefined) { - // to = sys.stdout; // FIXME - the to value is ignored. + // to = sys.stdout; // FIXME - the to value is ignored. // } sys.stdout.write('') } @@ -1715,9 +1763,9 @@ VirtualMachine.prototype.byte_RAISE_VARARGS = function(argc) { VirtualMachine.prototype.do_raise = function(exc, cause) { var exc_type, val - if (exc === undefined) { // reraise + if (exc === undefined) { // reraise if (this.last_exception.exc_type === undefined) { - return 'exception' // error + return 'exception' // error } else { return 'reraise' } @@ -1730,7 +1778,7 @@ VirtualMachine.prototype.do_raise = function(exc, cause) { exc_type = exc val = new exc_type.$pyclass() } else { - return 'exception' // error + return 'exception' // error } // If you reach this point, you're guaranteed that @@ -1738,7 +1786,7 @@ VirtualMachine.prototype.do_raise = function(exc, cause) { // Now do a similar thing for the cause, if present. if (cause) { // if not isinstance(cause, BaseException): - // return 'exception' // error + // return 'exception' // error val.__cause__ = cause } @@ -1899,36 +1947,54 @@ VirtualMachine.prototype.byte_CALL_FUNCTION_VAR_KW = function(arg) { } VirtualMachine.prototype.call_function = function(arg, args, kwargs) { - var lenPos - var namedargs = new types.JSDict() if (constants.BATAVIA_MAGIC === constants.BATAVIA_MAGIC_36) { - lenPos = arg + let namedargs = new types.JSDict() + let lenPos = arg + if (kwargs) { + for (let kv of kwargs.items()) { + namedargs[kv[0]] = kv[1] + } + } + let posargs = this.popn(lenPos) + if (args) { + for (let elem of args) { + posargs.push(elem) + } + } + let func = this.pop() + if (func.__call__ !== undefined) { + func = func.__call__.bind(func) + } + + let retval = func(posargs, namedargs) + this.push(retval) } else { - var lenKw = Math.floor(arg / 256) - lenPos = arg % 256 + let namedargs = new types.JSDict() + let lenKw = Math.floor(arg / 256) + let lenPos = arg % 256 for (var i = 0; i < lenKw; i++) { var items = this.popn(2) namedargs[items[0]] = items[1] } - } - if (kwargs) { - for (let kv of kwargs.items()) { - namedargs[kv[0]] = kv[1] + if (kwargs) { + for (let kv of kwargs.items()) { + namedargs[kv[0]] = kv[1] + } } - } - var posargs = this.popn(lenPos) - if (args) { - for (let elem of args) { - posargs.push(elem) + let posargs = this.popn(lenPos) + if (args) { + for (let elem of args) { + posargs.push(elem) + } + } + let func = this.pop() + if (func.__call__ !== undefined) { + func = func.__call__.bind(func) } - } - var func = this.pop() - if (func.__call__ !== undefined) { - func = func.__call__.bind(func) - } - var retval = func(posargs, namedargs) - this.push(retval) + let retval = func(posargs, namedargs) + this.push(retval) + } } VirtualMachine.prototype.byte_RETURN_VALUE = function() { diff --git a/batavia/types/Bytes.js b/batavia/types/Bytes.js index bdbf68585..3d669e812 100644 --- a/batavia/types/Bytes.js +++ b/batavia/types/Bytes.js @@ -345,7 +345,7 @@ Bytes.prototype.__or__ = function(other) { Bytes.prototype.__ifloordiv__ = function(other) { var types = require('../types') - + if (types.isinstance(other, [types.Complex])) { throw new exceptions.TypeError.$pyclass("can't take floor of complex number.") } else { From b5a713cdfaf4bb083822eaaf971927a1843da0dc Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Thu, 17 Aug 2017 09:46:47 -0700 Subject: [PATCH 5/6] Tweaked syntax in beekeeper file. --- beekeeper.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/beekeeper.yml b/beekeeper.yml index f8f5cb3fa..5cd36f81b 100644 --- a/beekeeper.yml +++ b/beekeeper.yml @@ -18,10 +18,10 @@ pull_request: name: Python 3.5 tests task: batavia-py35 critical: False - - py3.6: - name: Python 3.6 tests - task: batavia-py36 - critical: False + - py3.6: + name: Python 3.6 tests + task: batavia-py36 + critical: False profile: hi-cpu push: - smoke-test: From 42ab06340a114a5708c197c04c2313f96fafb774 Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Mon, 21 Aug 2017 00:13:21 +0200 Subject: [PATCH 6/6] Remove excess padding from EXTENDED_ARG --- batavia/VirtualMachine.js | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/batavia/VirtualMachine.js b/batavia/VirtualMachine.js index de88a6885..66866d81e 100644 --- a/batavia/VirtualMachine.js +++ b/batavia/VirtualMachine.js @@ -837,7 +837,7 @@ VirtualMachine.prototype.unpack_code = function(code) { lo = code.co_code.val[pos++] hi = code.co_code.val[pos++] extra = (lo << 16) | (hi << 24) - // emulate four NOPs + // emulate NOP unpacked_code[opcode_start_pos] = { 'opoffset': opcode_start_pos, 'opcode': dis.NOP, @@ -845,27 +845,6 @@ VirtualMachine.prototype.unpack_code = function(code) { 'args': [], 'next_pos': pos } - unpacked_code[opcode_start_pos + 1] = { - 'opoffset': opcode_start_pos + 1, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } - unpacked_code[opcode_start_pos + 2] = { - 'opoffset': opcode_start_pos + 2, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } - unpacked_code[opcode_start_pos + 3] = { - 'opoffset': opcode_start_pos + 3, - 'opcode': dis.NOP, - 'op_method': this.dispatch_table[dis.NOP], - 'args': [], - 'next_pos': pos - } continue }