[pypy-commit] lang-js default: wip... compiles with jit
stepahn
noreply at buildbot.pypy.org
Fri Dec 28 11:34:53 CET 2012
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r271:1783ca154ffd
Date: 2012-08-03 17:41 +0200
http://bitbucket.org/pypy/lang-js/changeset/1783ca154ffd/
Log: wip... compiles with jit
diff --git a/js/builtins_global.py b/js/builtins_global.py
--- a/js/builtins_global.py
+++ b/js/builtins_global.py
@@ -88,7 +88,7 @@
rpos -= 1
assert rpos >= 0
- result = unistr[lpos: rpos]
+ result = unistr[lpos:rpos]
return result
def _lstrip(unistr):
@@ -161,25 +161,29 @@
return NAN
+
# 15.1.2.3
@w_return
def parse_float(this, args):
- from pypy.rlib.rsre import rsre_re as re
+ from pypy.rlib.rsre import rsre_core as re
from runistr import encode_unicode_utf8
+ from js.constants import num_lit_rexp
string = get_arg(args, 0)
input_string = string.to_string()
trimmed_string = _strip(input_string)
str_trimmed_string = encode_unicode_utf8(trimmed_string)
- number_string = str_trimmed_string
+ match_data = num_lit_rexp.match(str_trimmed_string)
+ if match_data is not None:
+ number_string = match_data.group()
+ else:
+ number_string = ''
- #rexp = r'(?:[+-]?((?:(?:\d+)(?:\.\d*)?)|Infinity|(?:\.[0-9]+))(?:[eE][\+\-]?[0-9]*)?)'
- #match_data = re.match(rexp, str_trimmed_string)
- #if match_data is not None:
- #number_string = match_data.group()
- #else:
- #number_string = ''
+ if number_string == 'Infinity' or number_string == '+Infinity':
+ return INFINITY
+ elif number_string == '-Infinity':
+ return -INFINITY
try:
number = float(number_string)
@@ -294,7 +298,7 @@
@w_return
def pypy_repr(this, args):
o = args[0]
- return unicode(o)
+ return str(o)
@w_return
def inspect(this, args):
diff --git a/js/constants.py b/js/constants.py
--- a/js/constants.py
+++ b/js/constants.py
@@ -1,29 +1,7 @@
-escapes = [
- r'\n',
- r'\r',
- r'\f',
- r'\v',
- r'\ ',
- r'\t',
- r"\'",
- r'\b',
- r'\"',
- r'\\',
- r'\u'] #don't know what to do with these
+from pypy.rlib.rsre.rsre_re import compile
-codes = [
- '\n',
- '\r',
- '\f',
- '\v',
- '\ ',
- '\t',
- "'",
- "\b",
- '"',
- '\\',
- '\u']
-
-escapedict = dict(zip(codes, escapes))
-unescapedict = dict(zip(escapes, codes))
-
+num_lit_exp = r'(?:[+-]?((?:(?:\d+)(?:\.\d*)?)|Infinity|(?:\.[0-9]+))(?:[eE][\+\-]?[0-9]*)?)'
+num_lit_rexp = compile(num_lit_exp)
+num_rexp = compile(r'^%s$' % num_lit_exp)
+hex_rexp = compile(r'^0[xX]([\dA-Fa-f]+)$')
+oct_rexp = compile(r'^0([0-7]+)$')
diff --git a/js/contants.py b/js/contants.py
new file mode 100644
--- /dev/null
+++ b/js/contants.py
@@ -0,0 +1,6 @@
+from js import jsobj
+
+w_Null = jsobj.W_Null()
+w_Undefined = jsobj.W_Undefined()
+w_False = jsobj.W_Boolean(False)
+w_True = jsobj.W_Boolean(True)
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -8,13 +8,15 @@
from pypy.rlib import jit, debug
-def get_printable_location(pc, jsfunction):
- try:
- return str(jsfunction.opcodes[pc])
- except IndexError:
- return "???"
+def get_printable_location(pc, debug, jscode):
+ if pc < jscode._opcode_count():
+ opcode = jscode._get_opcode(pc)
+ return '%d: %s' % (pc, str(opcode))
+ else:
+ return '%d: %s' % (pc, 'end of opcodes')
#jitdriver = JitDriver(greens=['pc', 'self'], reds=['ctx'], get_printable_location = get_printable_location, virtualizables=['ctx'])
+jitdriver = JitDriver(greens=['pc', 'debug', 'self'], reds=['result', 'ctx'], get_printable_location = get_printable_location)
def ast_to_bytecode(ast, symbol_map):
bytecode = JsCode(symbol_map)
@@ -58,7 +60,6 @@
def params(self):
return self._symbols.parameters
- @jit.elidable
def estimated_stack_size(self):
# TODO: compute only once
if self._estimated_stack_size == -1:
@@ -214,7 +215,7 @@
self.unlabel()
- if len(self.opcodes) == 0:
+ if self._opcode_count() == 0:
return NormalCompletion()
if debug:
@@ -223,7 +224,8 @@
pc = 0
result = None
while True:
- if pc >= len(self.opcodes):
+ jitdriver.jit_merge_point(pc = pc, debug = debug, self = self, ctx = ctx, result = result)
+ if pc >= self._opcode_count():
break
opcode = self._get_opcode(pc)
result = opcode.eval(ctx)
@@ -241,6 +243,8 @@
if isinstance(opcode, BaseJump):
new_pc = opcode.do_jump(ctx, pc)
+ if new_pc < pc:
+ jitdriver.can_enter_jit(pc = pc, debug = debug, self = self, ctx = ctx, result = result)
pc = new_pc
continue
else:
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -1069,6 +1069,7 @@
return False
return True
+
class W_String(W_Primitive):
_type_ = 'string'
@@ -1097,36 +1098,46 @@
return True
def ToNumber(self):
+ from js.builtins_global import _strip
+ from runistr import encode_unicode_utf8
+ from js.constants import hex_rexp, oct_rexp, num_rexp
+
u_strval = self._strval_
- if u_strval == u'':
+ u_strval = _strip(u_strval)
+ s = encode_unicode_utf8(u_strval)
+
+ if s == '':
return 0.0
- if _isspace(u_strval):
- return 0.0
+ match_data = num_rexp.match(s)
+ if match_data is not None:
+ num_lit = match_data.group()
+ assert num_lit is not None
+ assert isinstance(num_lit, str)
- strval = str(u_strval)
- print(strval)
+ if num_lit == 'Infinity' or num_lit == '+Infinity':
+ return INFINITY
+ elif num_lit == '-Infinity':
+ return -INFINITY
- try:
- return float(strval)
- except ValueError:
- try:
- s = strval
- if len(s) > 2 and (s.startswith('0x') or s.startswith('0X')):
- s = s[2:]
- return float(int(s, 16))
- except ValueError:
- try:
- return float(int(strval, 8))
- except ValueError:
- return NAN
- except OverflowError:
- return INFINITY
- except OverflowError:
- return INFINITY
- except OverflowError:
- return INFINITY
+ return float(num_lit)
+
+ match_data = hex_rexp.match(s)
+ if match_data is not None:
+ hex_lit = match_data.group(1)
+ assert hex_lit is not None
+ assert hex_lit.startswith('0x') is False
+ assert hex_lit.startswith('0X') is False
+ return int(hex_lit, 16)
+
+ match_data = oct_rexp.match(s)
+ if match_data is not None:
+ oct_lit = match_data.group(1)
+ assert oct_lit is not None
+ return int(oct_lit, 8)
+
+ return NAN
class W_Number(W_Primitive):
""" Base class for numbers, both known to be floats
diff --git a/js/jsparser.py b/js/jsparser.py
--- a/js/jsparser.py
+++ b/js/jsparser.py
@@ -13,7 +13,20 @@
print e.nice_error_message(filename=str(GFILE),source=t)
raise
+NFILE = py.path.local(__file__).dirpath().join('jsgrammar_numeric.txt')
+try:
+ n = NFILE.read(mode='U')
+ n_regexs, n_rules, n_ToAST = parse_ebnf(n)
+except ParseError,e:
+ print e.nice_error_message(filename=str(GFILE),source=t)
+ raise
+
parsef = make_parse_function(regexs, rules, eof=True)
def parse(code):
t = parsef(code)
return ToAST().transform(t)
+
+parsen = make_parse_function(n_regexs, n_rules, eof=True)
+def parse_numbe(code):
+ t = parsen(code)
+ return n_ToAST().transform(t)
diff --git a/js/py-js.py b/js/py-js.py
new file mode 100755
--- /dev/null
+++ b/js/py-js.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+import os, sys
+from js.execution import JsException
+from pypy.rlib.objectmodel import enforceargs
+from pypy.rlib.parsing.parsing import ParseError
+
+def main(argv):
+ opts, files = parse_args(argv)
+
+ debug = opts.get('debug', False)
+ inspect = opts.get('inspect', False)
+
+ try:
+ run(files, debug, inspect)
+ except SystemExit:
+ printmessage(u"\n")
+
+ return 0
+
+def run(files, debug, inspect):
+ from js.object_space import object_space
+ from js.interpreter import Interpreter
+
+ interactive = len(files) == 0
+
+ object_space.DEBUG = debug
+ interp = Interpreter()
+
+ for f in files:
+ try:
+ interp.run_file(f)
+ except JsException as e:
+ printerrormessage(unicode(f), e._msg())
+ raise SystemExit
+
+ if inspect or interactive:
+ repl(interp)
+
+ at enforceargs(unicode, unicode)
+def printerrormessage(filename, message):
+ printmessage(u"ERROR in %s: %s\n" % (filename, message))
+
+
+def repl(interpreter):
+ filename = u'<stdin>'
+ while True:
+ printmessage(u'js> ')
+ line = readline()
+
+ try:
+ result = interpreter.run_src(line)
+ result_string = result.to_string()
+ printmessage(u"%s\n"% (result_string))
+ except ParseError as exc:
+ printsyntaxerror(filename, exc, line)
+ continue
+ except JsException as e:
+ printerrormessage(filename, e._msg())
+ continue
+
+# https://bitbucket.org/cfbolz/pyrolog/src/f18f2ccc23a4/prolog/interpreter/translatedmain.py
+ at enforceargs(unicode)
+def printmessage(msg):
+ from js.runistr import encode_unicode_utf8
+ os.write(1, encode_unicode_utf8(msg))
+
+def printsyntaxerror(filename, exc, source):
+ # XXX format syntax errors nicier
+ marker_indent = u' ' * exc.source_pos.columnno
+ error = exc.errorinformation.failure_reasons
+ error_lineno = exc.source_pos.lineno
+ error_line = (source.splitlines())[error_lineno]
+ printmessage(u'Syntax Error in: %s:%d\n' % (unicode(filename), error_lineno))
+ printmessage(u'%s\n' % (unicode(error_line)))
+ printmessage(u'%s^\n' %(marker_indent))
+ printmessage(u'Error: %s\n' %(unicode(str(error))))
+
+# https://bitbucket.org/cfbolz/pyrolog/src/f18f2ccc23a4/prolog/interpreter/translatedmain.py
+def readline():
+ result = []
+ while True:
+ s = os.read(0, 1)
+ result.append(s)
+ if s == "\n":
+ break
+ if s == '':
+ if len(result) > 1:
+ break
+ raise SystemExit
+ return "".join(result)
+
+def parse_args(argv):
+ opts = {'inspect': False, 'debug': False}
+
+ for i in xrange(len(argv)):
+ if argv[i] == '-d':
+ opts['debug'] = True
+ del(argv[i])
+ break
+
+ for i in xrange(len(argv)):
+ if argv[i] == '-i':
+ opts['inspect'] = True
+ del(argv[i])
+ break
+
+ del(argv[0])
+
+ return opts, argv
+
+if __name__ == '__main__':
+ import sys
+ main(sys.argv)
+
+# _____ Define and setup target ___
+
+def target(driver, args):
+ driver.exe_name = 'py-js'
+ return entry_point, None
+
+def jitpolicy(driver):
+ from pypy.jit.codewriter.policy import JitPolicy
+ return JitPolicy()
+
+def entry_point(argv):
+ return main(argv)
More information about the pypy-commit
mailing list