[pypy-svn] r42790 - pypy/dist/pypy/translator/js
fijal at codespeak.net
fijal at codespeak.net
Mon May 7 13:17:59 CEST 2007
Author: fijal
Date: Mon May 7 13:17:59 2007
New Revision: 42790
Modified:
pypy/dist/pypy/translator/js/asmgen.py
pypy/dist/pypy/translator/js/function.py
pypy/dist/pypy/translator/js/js.py
pypy/dist/pypy/translator/js/jsbuiltin.py
pypy/dist/pypy/translator/js/metavm.py
pypy/dist/pypy/translator/js/opcodes.py
Log:
* builtin refactorings, got rid of some ugly hacks
* subst_table is working again => better resulting code
* be insanly delicate about stack. No unnecessary values
should reside on stack any more
* this refactoring should fix misterious test failure apeearing from
time to time in the nightly test run
Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py (original)
+++ pypy/dist/pypy/translator/js/asmgen.py Mon May 7 13:17:59 2007
@@ -53,6 +53,15 @@
def __len__(self):
return len(self.l)
+ def __nonzero__(self):
+ return len(self.l) > 0
+
+ def empty(self):
+ self.l = []
+
+ def __repr__(self):
+ return "<Queue %s>" % (repr(self.l),)
+
class AsmGen(object):
""" JS 'assembler' generator routines
"""
@@ -166,9 +175,8 @@
self.codegenerator.openblock()
def change_name(self, from_name, to_name):
- # if isinstance(from_name,Variable) and isinstance(to_name,Variable):
- # self.subst_table[from_name.name] = to_name.name
- pass
+ if isinstance(from_name,Variable) and isinstance(to_name,Variable):
+ self.subst_table[from_name.name] = to_name.name
def cast_function(self, name, num):
# FIXME: redundancy with call
@@ -193,7 +201,7 @@
def set_field(self, useless_parameter, name):
v = self.right_hand.pop()
self.codegenerator.writeline("%s.%s = %s;"%(self.right_hand.pop(), name, v))
- self.right_hand.append(None)
+ #self.right_hand.append(None)
def call_method(self, obj, name, signature):
l = [self.right_hand.pop() for i in signature]
@@ -215,7 +223,7 @@
self.right_hand.append("this")
def store_void(self):
- if len(self.right_hand) == 0:
+ if not len(self.right_hand):
return
v = self.right_hand.pop()
if v is not None and v.find('('):
@@ -286,3 +294,6 @@
def throw_real(self, s):
self.codegenerator.writeline("throw(%s);"%s)
+
+ def clean_stack(self):
+ self.right_hand.empty()
Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py (original)
+++ pypy/dist/pypy/translator/js/function.py Mon May 7 13:17:59 2007
@@ -34,13 +34,11 @@
assert False
def store(self, v):
- if isinstance(v, flowmodel.Variable):
- if v.concretetype is not Void:
- self.ilasm.store_local(v)
- else:
- self.ilasm.store_void()
+ assert isinstance(v, flowmodel.Variable)
+ if v.concretetype is not Void:
+ self.ilasm.store_local(v)
else:
- assert False
+ self.ilasm.store_void()
def change_name(self, name, to_name):
self.ilasm.change_name(name, to_name)
@@ -230,3 +228,6 @@
def begin_try(self):
self.ilasm.begin_try()
+
+ def clean_stack(self):
+ self.ilasm.clean_stack()
Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py (original)
+++ pypy/dist/pypy/translator/js/js.py Mon May 7 13:17:59 2007
@@ -101,6 +101,7 @@
self.gen_pendings()
self.db.gen_constants(self.ilasm, self.db._pending_nodes)
self.ilasm.close()
+ assert len(self.ilasm.right_hand) == 0
return self.tmpfile.strpath
def write_source(self):
Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py (original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py Mon May 7 13:17:59 2007
@@ -1,55 +1,52 @@
""" JavaScript builtin mappings
"""
-from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs
+from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs,\
+ _PushAllArgs
from pypy.translator.js.metavm import SetBuiltinField, ListGetitem, ListSetitem, \
GetBuiltinField, CallBuiltin, Call, SetTimeout, ListContains,\
- NewBuiltin, SetOnEvent
+ NewBuiltin, SetOnEvent, ListRemove, CallBuiltinMethod, _GetPredefinedField,\
+ _SetPredefinedField
from pypy.rpython.ootypesystem import ootype
class _Builtins(object):
def __init__(self):
- list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2])
+ list_resize = _SetPredefinedField('length')
self.builtin_map = {
'll_js_jseval' : CallBuiltin('eval'),
'set_on_keydown' : SetOnEvent('onkeydown'),
'set_on_keyup' : SetOnEvent('onkeyup'),
'setTimeout' : SetTimeout,
- 'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]),
- 'll_strconcat' : InstructionList([PushAllArgs, '+']),
+ 'll_int_str' : CallBuiltinMethod('toString', [2]),
+ 'll_strconcat' : InstructionList([_PushAllArgs(slice(1, None)), '+']),
'll_int' : CallBuiltin('parseInt'),
#'alert' : CallBuiltin('alert'),
'seval' : CallBuiltin('seval'),
'date': NewBuiltin('Date'),
- 'll_math.ll_math_fmod' : InstructionList([PushAllArgs, '%']),
+ 'll_math.ll_math_fmod' : InstructionList([_PushAllArgs(slice(1, None)), '%']),
'll_time_time' : CallBuiltin('time'),
'll_time_clock' : CallBuiltin('clock'),
'll_os_write' : CallBuiltin('print'),
}
self.builtin_obj_map = {
ootype.String.__class__: {
- 'll_strconcat' : InstructionList([PushAllArgs, '+']),
- 'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'),
- 'll_stritem_nonneg' : lambda g, op: Call._render_builtin_method(g, 'charAt', [op.args[1], op.args[2]]),
- 'll_streq' : InstructionList([PushAllArgs, '==']),
+ 'll_strconcat' : InstructionList([_PushAllArgs(slice(1, None)), '+']),
+ 'll_strlen' : _GetPredefinedField('length'),
+ 'll_stritem_nonneg' : CallBuiltinMethod('charAt', slice(1,None)),
+ 'll_streq' : InstructionList([_PushAllArgs(slice(1, None)), '==']),
'll_strcmp' : CallBuiltin('strcmp'),
'll_startswith' : CallBuiltin('startswith'),
'll_endswith' : CallBuiltin('endswith'),
'll_split_chr' : CallBuiltin('splitchr'),
- #'ll_substring' : lambda g,op: Call._render_builtin_method(g, 'substring', [op.args[1], op.args[2], op.args[3]]),
'll_substring' : CallBuiltin('substring'),
- 'll_lower' : lambda g, op: Call._render_builtin_method(g, 'toLowerCase', [op.args[1]]),
- 'll_upper' : lambda g, op: Call._render_builtin_method(g, 'toUpperCase', [op.args[1]]),
+ 'll_lower' : CallBuiltinMethod('toLowerCase', slice(1, None)),
+ 'll_upper' : CallBuiltinMethod('toUpperCase', slice(1, None)),
'll_find' : CallBuiltin('findIndexOf'),
'll_find_char' : CallBuiltin('findIndexOf'),
- #'ll_find' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]),
- #'ll_find_char' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]),
'll_contains' : CallBuiltin('findIndexOfTrue'),
- 'll_replace_chr_chr' : lambda g, op:
- Call._render_builtin_method(g, 'replace',
- [op.args[1], op.args[2], op.args[3], 'g']),
+ 'll_replace_chr_chr' : CallBuiltinMethod('replace', slice(1, None), ['g']),
'll_count_char' : CallBuiltin('countCharOf'),
'll_count' : CallBuiltin('countOf'),
},
@@ -59,7 +56,7 @@
'_ll_resize' : list_resize,
'_ll_resize_ge' : list_resize,
'_ll_resize_le' : list_resize,
- 'll_length' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'),
+ 'll_length' : _GetPredefinedField('length'),
},
ootype.Dict: {
'll_get' : ListGetitem,
@@ -67,7 +64,7 @@
'll_contains' : ListContains,
'll_get_items_iterator' : CallBuiltin('dict_items_iterator'),
'll_length' : CallBuiltin('get_dict_len'),
- 'll_remove' : lambda g, op: CallBuiltin('delete')._render_builtin_prepared_args(g, 'delete', ['%s[%s]' % (op.args[1], op.args[2])]),
+ 'll_remove' : ListRemove,
'll_clear': CallBuiltin('clear_dict'),
},
ootype.Record: {
@@ -76,5 +73,12 @@
'll_contains' : ListContains,
}
}
+ self.fix_opcodes()
+
+ def fix_opcodes(self):
+ from pypy.translator.js.metavm import fix_opcodes
+ #fix_opcodes(self.builtin_map)
+ #for value in self.builtin_obj_map.values():
+ # fix_opcodes(value)
Builtins = _Builtins()
Modified: pypy/dist/pypy/translator/js/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/js/metavm.py (original)
+++ pypy/dist/pypy/translator/js/metavm.py Mon May 7 13:17:59 2007
@@ -3,7 +3,7 @@
#from pypy.translator.js.jsbuiltin import Builtins
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\
- InstructionList, New, SetField, GetField, MicroInstruction
+ InstructionList, New, GetField, MicroInstruction
from pypy.translator.js.log import log
from pypy.rpython.ootypesystem import ootype
@@ -82,6 +82,20 @@
def render(self, generator, op):
self._render_builtin(generator, self.builtin, op.args)
+class CallBuiltinMethod(_Call):
+ def __init__(self, builtin, slice=None, additional_args=[]):
+ self.builtin = builtin
+ self.slice = slice
+ self.additional_args = additional_args
+
+ def render(self, generator, op):
+ if self.slice is not None:
+ args = op.args[self.slice]
+ else:
+ args = op.args
+ args += self.additional_args
+ self._render_builtin_method(generator, self.builtin, args)
+
class _SameAs(MicroInstruction):
def render(self, generator, op):
generator.change_name(op.result, op.args[0])
@@ -128,11 +142,17 @@
def render(self, generator, op):
this = op.args[0]
field = op.args[1].value[1:]
- self.run_it(generator, this, field)
-
- def run_it(self, generator, this, field_name):
generator.load(this)
- generator.get_field(None, field_name)
+ generator.get_field(None, field)
+
+class _GetPredefinedField(MicroInstruction):
+ def __init__(self, field):
+ self.field = field
+
+ def render(self, generator, op):
+ this = op.args[1]
+ generator.load(this)
+ generator.get_field(None, self.field)
GetBuiltinField = _GetBuiltinField()
@@ -151,6 +171,15 @@
generator.load(this)
generator.load_special(value)
generator.set_field(None, field_name)
+
+class _SetPredefinedField(_SetBuiltinField):
+ def __init__(self, field):
+ self.field = field
+
+ def render(self, generator, op):
+ value = op.args[2]
+ this = op.args[1]
+ self.run_it(generator, this, self.field, value)
class _SetExternalField(_SetBuiltinField):
def render(self, generator, op):
@@ -177,7 +206,7 @@
this = op.args[1].concretetype
method = op.args[0]
method_name = method.value
- generator.load(op.args[1])
+ #generator.load(op.args[1])
self._render_builtin_method(generator, method_name, op.args[1:])
CallBuiltinObject = _CallBuiltinObject()
@@ -213,6 +242,10 @@
generator.load(op.args[2])
generator.call_external('setTimeout',[0]*2)
+class _DiscardStack(MicroInstruction):
+ def render(self, generator, op):
+ generator.clean_stack()
+
class SetOnEvent(MicroInstruction):
def __init__(self, field):
self.field = field
@@ -222,29 +255,23 @@
val = op.args[1].value
val = val.concretize().value
assert(isinstance(val, ootype._static_meth))
- #if isinstance(val, ootype.StaticMethod):
real_name = val._name
generator.db.pending_function(val.graph)
- #generator.db.pending_function(val.graph)
- #else:
- # concrete = val.concretize()
- # real_name = concrete.value._name
- # generator.db.pending_function(concrete.value.graph)
- #generator.load_str("'%s()'" % real_name)
- #generator.load(op.args[2])
generator.load_str("document")
generator.load_str(real_name)
generator.set_field(None, self.field)
- #generator.call_external('setTimeout',[0]*2)
-##class _XmlSetCallback(MicroInstruction):
-## # FIXME: Another dirty hack. To remove soon
-## def render(self, generator, op):
-## generator.load(op.args[2])
-## generator.load(op.args[1])
-## generator.set_field(None, 'onreadystatechange')
-##
-##XmlSetCallback = _XmlSetCallback()
+class _CheckLength(MicroInstruction):
+ def render(self, generator, op):
+ assert not generator.ilasm.right_hand
+
+class _ListRemove(MicroInstruction):
+ def render(self, generator, op):
+ generator.list_getitem(op.args[1], op.args[2])
+ generator.call_external('delete', [0])
+
+ListRemove = _ListRemove()
+CheckLength = _CheckLength()
SetTimeout = _SetTimeout()
IndirectCall = _IndirectCall()
IsInstance = _IsInstance()
@@ -252,3 +279,19 @@
CopyName = [PushAllArgs, _SameAs ()]
CastString = _CastFun("convertToString", 1)
SameAs = CopyName
+DiscardStack = _DiscardStack()
+
+def fix_opcodes(opcodes):
+ for key, value in opcodes.iteritems():
+ if type(value) is str:
+ value = InstructionList([PushAllArgs, value, StoreResult, CheckLength])
+ elif value == []:
+ value = InstructionList([CheckLength])
+ elif value is not None:
+ if StoreResult not in value:
+ value.append(StoreResult)
+ if CheckLength not in value:
+ value.append(CheckLength)
+ value = InstructionList(value)
+
+ opcodes[key] = value
Modified: pypy/dist/pypy/translator/js/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/js/opcodes.py (original)
+++ pypy/dist/pypy/translator/js/opcodes.py Mon May 7 13:17:59 2007
@@ -2,19 +2,21 @@
"""
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\
- InstructionList, New, SetField, GetField, MicroInstruction, RuntimeNew, PushPrimitive
+ InstructionList, New, GetField, MicroInstruction, RuntimeNew, PushPrimitive
from pypy.translator.oosupport.metavm import _GetFieldDispatcher, _SetFieldDispatcher, \
- _CallDispatcher, _MethodDispatcher
+ _CallDispatcher, _MethodDispatcher, SetField
-from pypy.translator.js.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\
- _Prefix, _CastFun, _NotImplemented, CallBuiltin, CallBuiltinObject, GetBuiltinField, SetBuiltinField,\
- IndirectCall, CallExternalObject, SetExternalField, _CastMethod, _LoadConst
+from pypy.translator.js.metavm import IsInstance, Call, CallMethod,\
+ CopyName, CastString, _Prefix, _CastFun, _NotImplemented, CallBuiltin,\
+ CallBuiltinObject, GetBuiltinField, SetBuiltinField, IndirectCall,\
+ CallExternalObject, SetExternalField, _CastMethod, _LoadConst,\
+ DiscardStack, CheckLength, fix_opcodes
from pypy.translator.js.jsbuiltin import Builtins
from pypy.rpython.ootypesystem import ootype
-DoNothing = [PushAllArgs]
+DoNothing = []
from pypy.translator.js.log import log
@@ -113,7 +115,7 @@
'direct_call' : [_CallDispatcher(Builtins, class_map)],
'indirect_call' : [IndirectCall],
- 'same_as' : SameAs,
+ 'same_as' : CopyName,
'new' : [New],
'runtimenew' : [RuntimeNew],
'instanceof' : [IsInstance],
@@ -124,8 +126,8 @@
'oosetfield' : [_SetFieldDispatcher(Builtins, class_map)],
'oogetfield' : [_GetFieldDispatcher(Builtins, class_map)],
'oosend' : [_MethodDispatcher(Builtins, class_map)],
- 'ooupcast' : DoNothing,
- 'oodowncast' : DoNothing,
+ 'ooupcast' : CopyName,
+ 'oodowncast' : CopyName,
'oononnull' : [PushAllArgs,_Prefix('!!')],
'oostring' : [PushArg(0),CastString],
'ooparse_int' : [PushAllArgs,_CastFun("parseInt",2)],
@@ -153,12 +155,4 @@
'is_early_constant': [PushPrimitive(ootype.Bool, False)],
}
-for key, value in opcodes.iteritems():
- if type(value) is str:
- value = InstructionList([PushAllArgs, value, StoreResult])
- elif value is not None:
- if StoreResult not in value:
- value.append(StoreResult)
- value = InstructionList(value)
-
- opcodes[key] = value
+fix_opcodes(opcodes)
More information about the pypy-svn
mailing list