[pypy-commit] lang-js default: wip

stepahn noreply at buildbot.pypy.org
Fri Dec 28 11:33:26 CET 2012


Author: Stephan <stephan at stzal.com>
Branch: 
Changeset: r186:77f1751dd1f3
Date: 2012-05-10 15:24 +0200
http://bitbucket.org/pypy/lang-js/changeset/77f1751dd1f3/

Log:	wip

diff --git a/js/functions.py b/js/functions.py
new file mode 100644
--- /dev/null
+++ b/js/functions.py
@@ -0,0 +1,241 @@
+from js.opcodes import BaseJump
+
+class JsBaseFunction(object):
+    eval_code = False
+    function_code = False
+    configurable_bindings = False
+    strict = False
+
+    def __init__(self):
+        pass
+
+    def run(self, ctx):
+        raise NotImplementedError
+
+    def estimated_stack_size(self):
+        return 2
+
+    def to_string(self):
+        return 'function() {}'
+
+    def variables(self):
+        return []
+
+    def functions(self):
+        return []
+
+    #def index_for_symbol(self, symbol):
+        #return None
+
+    #def symbols(self):
+        #return []
+
+    #def symbol_for_index(self, index):
+        #return None
+
+    def params(self):
+        return []
+
+    def name(self):
+        return '_unnamed_'
+
+    def is_eval_code(self):
+        return False
+
+    def is_function_code(self):
+        return False
+
+class JsNativeFunction(JsBaseFunction):
+    def __init__(self, function, name = None):
+        JsBaseFunction.__init__(self)
+        self._name_ = name
+        self._function_ = function
+
+    def name(self):
+        return self._name_
+
+    def run(self, ctx):
+        args = ctx.argv()
+        this = ctx.this_binding()
+        return self._function_(this, args)
+
+    def to_string(self):
+        name = self.name()
+        if name is not None:
+            return 'function %s() { [native code] }' % (name, )
+        else:
+            return 'function () { [native code] }'
+
+class JsIntimateFunction(JsNativeFunction):
+    def run(self, ctx):
+        return self._function_(ctx)
+
+class JsExecutableCode(JsBaseFunction):
+    def __init__(self, js_code):
+        JsBaseFunction.__init__(self)
+        self._js_code_ = js_code
+        self.stack_size = js_code.estimated_stack_size()
+        self.opcodes = self._opcodes_from_code_()
+
+    def _opcodes_from_code_(self):
+        return self._js_code_.to_executable_opcodes()
+
+    #def estimated_stack_size(self):
+        #return self.stack_size
+
+    def _get_opcode(self, pc):
+        assert pc >= 0
+        return self.opcodes[pc]
+
+    def run(self, ctx):
+        pc = 0
+        while True:
+            if pc >= len(self.opcodes):
+                break
+            opcode = self._get_opcode(pc)
+            result = opcode.eval(ctx)
+            assert result is None
+            #print('pc:%d, opcode:%s, stack:%s'%(pc, repr(opcode), str(ctx._stack_)))
+
+            from js.opcodes import RETURN
+            if isinstance(opcode, BaseJump):
+                new_pc = opcode.do_jump(ctx, pc)
+                pc = new_pc
+                continue
+            elif isinstance(opcode, RETURN):
+                break
+            else:
+                pc += 1
+
+        return ctx.stack_top()
+
+    def variables(self):
+        return self._js_code_.variables()
+
+    def functions(self):
+        return self._js_code_.functions()
+
+    #def index_for_symbol(self, symbol):
+        #return self._js_code_.index_for_symbol(symbol)
+
+    #def symbols(self):
+        #return self._js_code_.symbols()
+
+    #def symbol_for_index(self, index):
+        #return self._js_code_.symbol_for_index(index)
+
+    def params(self):
+        return self._js_code_.params()
+
+    def name(self):
+        return '_unnamed_'
+
+    def to_string(self):
+        name = self.name()
+        if name is not None:
+            return 'function %s() { }' % (name, )
+        else:
+            return 'function () { }'
+
+class JsGlobalCode(JsExecutableCode):
+    def _opcodes_from_code_(self):
+        return self._js_code_.to_global_opcodes()
+
+class JsEvalCode(JsExecutableCode):
+    def _opcodes_from_code_(self):
+        return self._js_code_.to_global_opcodes()
+
+    def is_eval_code(self):
+        return True
+
+class JsFunction(JsExecutableCode):
+    #_immutable_fields_ = ["opcodes[*]", 'name', 'params', 'code', 'scope']
+
+    def __init__(self, name, js_code):
+        JsExecutableCode.__init__(self, js_code)
+        self._name_ = name
+
+    def _opcodes_from_code_(self):
+        return self._js_code_.to_function_opcodes()
+        #self.opcodes = make_sure_not_resized(code.opcodes[:])
+
+    def name(self):
+        return self._name_
+
+    def is_function_code(self):
+        return True
+
+    #@jit.unroll_safe
+    #def run(self, ctx, args=[], this=None):
+        #from js.jsexecution_context import make_activation_context, make_function_context
+
+        #from js.jsobj import W_Arguments, w_Undefined
+        #w_Arguments = W_Arguments(self, args)
+        #act = make_activation_context(ctx, this, w_Arguments)
+        #newctx = make_function_context(act, self)
+
+        #paramn = len(self.params)
+        #for i in range(paramn):
+            #paramname = self.params[i]
+            #try:
+                #value = args[i]
+            #except IndexError:
+                #value = w_Undefined
+            #newctx.declare_variable(paramname)
+            #newctx.assign(paramname, value)
+
+        #return self._run_with_context(ctx=newctx, save_stack = False)
+
+    #def _run_with_context(self, ctx, check_stack=True, save_stack=True):
+        #state = ([], 0)
+        #if save_stack:
+            #state = _save_stack(ctx, self.estimated_stack_size())
+
+        #try:
+            #self._run_bytecode(ctx)
+            #if check_stack:
+                #ctx.check_stack()
+            #return ctx.top()
+        #except ReturnException, e:
+            #return e.value
+        #finally:
+            #if save_stack:
+                #_restore_stack(ctx, state)
+
+    #def _run_bytecode(self, ctx, pc=0):
+        #while True:
+            #jitdriver.jit_merge_point(pc=pc, self=self, ctx=ctx)
+            #if pc >= len(self.opcodes):
+                #break
+
+            #opcode = self._get_opcode(pc)
+            ##if we_are_translated():
+            ##    #this is an optimization strategy for translated code
+            ##    #on top of cpython it destroys the performance
+            ##    #besides, this code might be completely wrong
+            ##    for name, op in opcode_unrolling:
+            ##        opcode = hint(opcode, deepfreeze=True)
+            ##        if isinstance(opcode, op):
+            ##            result = opcode.eval(ctx, stack)
+            ##            assert result is None
+            ##            break
+            ##else:
+            #result = opcode.eval(ctx)
+            #assert result is None
+
+            #if isinstance(opcode, BaseJump):
+                #new_pc = opcode.do_jump(ctx, pc)
+                #condition = new_pc < pc
+                #pc = new_pc
+                #if condition:
+                    #jitdriver.can_enter_jit(pc=pc, self=self, ctx=ctx)
+                #continue
+            #else:
+                #pc += 1
+
+            #if isinstance(opcode, WITH_START):
+                #pc = self._run_bytecode(opcode.newctx, pc)
+            #elif isinstance(opcode, WITH_END):
+                #break
+
+        #return pc


More information about the pypy-commit mailing list