Mercurial > py-js
view test.py @ 0:e985e6d762b9 default tip
Origination.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Wed, 24 Sep 2008 16:47:18 -0700 |
parents | |
children |
line wrap: on
line source
import sys import os import tempfile import subprocess import dis import json def disassemble(co, lasti=-1): """Disassemble a code object and return a JSON-able dictionary of its representation. This function is a slightly modified version of dis.disassemble().""" code = co.co_code labels = dis.findlabels(code) linestarts = dict(dis.findlinestarts(co)) n = len(code) i = 0 extended_arg = 0 free = None op_infos = [] bytes_to_op_infos = {} while i < n: op_info = {} op_infos.append(op_info) bytes_to_op_infos[i] = len(op_infos) - 1 c = code[i] op = ord(c) if i in linestarts: op_info['line'] = linestarts[i] op_info['op'] = dis.opname[op] i = i+1 if op >= dis.HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg extended_arg = 0 i = i+2 if op == dis.EXTENDED_ARG: extended_arg = oparg*65536L op_info['arg'] = oparg return {'ops': op_infos, 'bytes_to_ops': bytes_to_op_infos} def exec_js(code, extra_output=None): if extra_output is None: extra_output = {} fd, temppath = tempfile.mkstemp('.js') os.close(fd) temp = open(temppath, 'w') temp.write(code.encode('utf-8')) temp.close() extra_output['errors'] = [] BRANCH_LIMIT = '500' OUTPUT_FILENAME = '__temp_output.txt' ERROR_FILENAME = '__temp_input.txt' out_file = open(OUTPUT_FILENAME, 'w') err_file = open(ERROR_FILENAME, 'w') args = ['js', '-b', BRANCH_LIMIT, '-f', 'json2.js', '-f', 'py.js', '-f', temppath, '-f', 'post.js'] popen = subprocess.Popen(args, stdout=out_file, stderr=err_file) popen.wait() os.remove(temppath) out_file = open(OUTPUT_FILENAME, 'r') output = out_file.read() err_file = open(ERROR_FILENAME, 'r') error = err_file.read() out_file.close() err_file.close() os.remove(OUTPUT_FILENAME) os.remove(ERROR_FILENAME) output = output.strip() if error: extra_output['errors'].append(error) try: obj = json.read(output) except Exception, e: extra_output['errors'].append(str(e)) obj = None return obj def run(pycode): bytecode = compile(pycode, "<string>", "exec") jsoncode = {'co_consts': bytecode.co_consts, 'co_names': bytecode.co_names, 'co_code': disassemble(bytecode)} extra = {} retval = exec_js('jsoncode = %s' % json.write(jsoncode), extra) if extra['errors']: print "Errors occurred: " print for error in extra['errors']: print " * %s" % error, print print print "Disassembly of code:" print dis.dis(bytecode) raise Exception() return retval def test_assignment_works(): """ >>> run('a = 1')['locals']['a'] 1 """ pass def test_binary_addition_works(): """ >>> run('a = 1; a = 5 + a')['locals']['a'] 6 """ pass def test_global_works(): """ >>> run('global a; a = 1')['globals']['a'] 1 """ pass if __name__ == '__main__': import doctest doctest.testmod()