@@ -807,22 +807,43 @@ def _visit_dart_classdef(self, node):
807807
808808 writer .pull ()
809809
810+ def is_gpu_method (self , n ):
811+ for dec in n .decorator_list :
812+ if isinstance (dec , Attribute ) and isinstance (dec .value , Name ) and dec .value .id == 'gpu' :
813+ if dec .attr == 'method' :
814+ return True
815+
816+
810817 def _visit_js_classdef (self , node ):
811818 name = node .name
812- log ('JavaScript-ClassDef: %s' % name )
813819 self ._js_classes [ name ] = node
814820 self ._in_js_class = True
821+ class_decorators = []
822+ gpu_object = False
823+
824+ for decorator in node .decorator_list : ## class decorators
825+ if isinstance (decorator , Attribute ) and isinstance (decorator .value , Name ) and decorator .value .id == 'gpu' :
826+ if decorator .attr == 'object' :
827+ gpu_object = True
828+ else :
829+ raise SyntaxError ( self .format_error ('invalid gpu class decorator' ) )
830+ else :
831+ class_decorators .append ( decorator )
815832
816833 methods = {}
817834 class_vars = []
835+
818836 for item in node .body :
819837 if isinstance (item , FunctionDef ):
820838 methods [ item .name ] = item
821- item .args .args = item .args .args [1 :] ## remove self
822- finfo = inspect_function ( item )
823- for n in finfo ['name_nodes' ]:
824- if n .id == 'self' :
825- n .id = 'this'
839+ if self .is_gpu_method ( item ):
840+ item .args .args [0 ].id = name ## change self to the class name
841+ else :
842+ item .args .args = item .args .args [1 :] ## remove self
843+ finfo = inspect_function ( item )
844+ for n in finfo ['name_nodes' ]:
845+ if n .id == 'self' :
846+ n .id = 'this'
826847 elif isinstance (item , ast .Expr ) and isinstance (item .value , Str ): ## skip doc strings
827848 pass
828849 else :
@@ -845,17 +866,22 @@ def _visit_js_classdef(self, node):
845866 writer .write ('def %s(%s):' % (name ,',' .join (args )))
846867 writer .push ()
847868 if init :
869+ tail = ''
870+ if gpu_object :
871+ tail = 'this.__struct_name__="%s"' % name
872+
873+
848874 #for b in init.body:
849875 # line = self.visit(b)
850876 # if line: writer.write( line )
851877
852878 if hasattr (init , '_code' ): ## cached ##
853879 code = init ._code
854880 elif args :
855- code = '%s.__init__(this, %s)' % (name , ',' .join (args ))
881+ code = '%s.__init__(this, %s); %s ' % (name , ',' .join (args ), tail )
856882 init ._code = code
857883 else :
858- code = '%s.__init__(this)' % name
884+ code = '%s.__init__(this); %s' % ( name , tail )
859885 init ._code = code
860886
861887 writer .write (code )
@@ -879,12 +905,25 @@ def _visit_js_classdef(self, node):
879905 keys .sort ()
880906 for mname in keys :
881907 method = methods [mname ]
882- writer .write ('@%s.prototype' % name )
883- line = self .visit (method )
884- if line : writer .write ( line )
885- #writer.write('%s.prototype.%s = %s'%(name,mname,mname))
886- f = 'function () { return %s.prototype.%s.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }' % (name , mname )
887- writer .write ('%s.%s = JS("%s")' % (name ,mname ,f ))
908+ gpu_method = False
909+ for dec in method .decorator_list :
910+ if isinstance (dec , Attribute ) and isinstance (dec .value , Name ) and dec .value .id == 'gpu' :
911+ if dec .attr == 'method' :
912+ gpu_method = True
913+
914+ if gpu_method :
915+ method .name = '%s_%s' % (name , method .name )
916+ line = self .visit (method )
917+ if line : writer .write ( line )
918+
919+ else :
920+
921+ writer .write ('@%s.prototype' % name )
922+ line = self .visit (method )
923+ if line : writer .write ( line )
924+ #writer.write('%s.prototype.%s = %s'%(name,mname,mname))
925+ f = 'function () { return %s.prototype.%s.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }' % (name , mname )
926+ writer .write ('%s.%s = JS("%s")' % (name ,mname ,f ))
888927
889928 for base in node .bases :
890929 base = self .visit (base )
@@ -906,6 +945,9 @@ def _visit_js_classdef(self, node):
906945 self .visit (item ) # this will output the code for the assign
907946 writer .write ('%s.prototype.%s = %s' % (name , item_name , item .targets [0 ].id ))
908947
948+ if gpu_object :
949+ ## TODO check class variables ##
950+ writer .write ('%s.prototype.__struct_name__ = "%s"' % (name ,name ))
909951
910952 ## TODO support property decorators in javascript-mode ##
911953 writer .write ('%s.prototype.__properties__ = {}' % name )
@@ -923,7 +965,6 @@ def visit_ClassDef(self, node):
923965 return
924966
925967 name = node .name
926- log ('ClassDef: %s' % name )
927968 self ._in_class = name
928969 self ._classes [ name ] = list () ## method names
929970 self ._class_parents [ name ] = set ()
@@ -933,19 +974,17 @@ def visit_ClassDef(self, node):
933974 self ._decorator_class_props [ name ] = self ._decorator_properties
934975 self ._instances [ 'self' ] = name
935976
977+ self ._injector = [] ## DEPRECATED
936978 class_decorators = []
937- self ._injector = []
979+ gpu_object = False
980+
938981 for decorator in node .decorator_list : ## class decorators
939- if isinstance (decorator , Attribute ) and isinstance (decorator .value , Name ) and decorator .value .id == 'pythonjs' :
940- if decorator .attr == 'property_callbacks' :
941- self ._injector .append ('set' )
942- elif decorator .attr == 'init_callbacks' :
943- self ._injector .append ('init' )
982+ if isinstance (decorator , Attribute ) and isinstance (decorator .value , Name ) and decorator .value .id == 'gpu' :
983+ if decorator .attr == 'object' :
984+ gpu_object = True
944985 else :
945- raise SyntaxError ( 'unsupported pythonjs class decorator' )
946-
986+ raise SyntaxError ( self .format_error ('invalid gpu class decorator' ) )
947987 else :
948- #raise SyntaxError( 'unsupported class decorator' )
949988 class_decorators .append ( decorator )
950989
951990 ## always catch attributes ##
@@ -1025,9 +1064,11 @@ def visit_ClassDef(self, node):
10251064 self ._in_class = False
10261065
10271066 writer .write ('%s = __create_class__("%s", __%s_parents, __%s_attrs, __%s_properties)' % (name , name , name , name , name ))
1028- if 'init' in self ._injector :
1029- writer .write ('%s.init_callbacks = JSArray()' % name )
1030- self ._injector = []
1067+
1068+ ## DEPRECATED
1069+ #if 'init' in self._injector:
1070+ # writer.write('%s.init_callbacks = JSArray()' %name)
1071+ #self._injector = []
10311072
10321073 for dec in class_decorators :
10331074 writer .write ('%s = __get__(%s,"__call__")( [%s], JSObject() )' % (name , self .visit (dec ), name ))
@@ -2433,6 +2474,7 @@ def visit_FunctionDef(self, node):
24332474 gpu = False
24342475 gpu_main = False
24352476 gpu_vectorize = False
2477+ gpu_method = False
24362478 local_typedefs = []
24372479
24382480 ## deprecated?
@@ -2487,8 +2529,8 @@ def visit_FunctionDef(self, node):
24872529 gpu_vectorize = True
24882530 elif decorator .attr == 'main' :
24892531 gpu_main = True
2490- elif decorator .attr == 'typedef ' :
2491- pass
2532+ elif decorator .attr == 'method ' :
2533+ gpu_method = True
24922534 else :
24932535 raise NotImplementedError (decorator )
24942536
@@ -2592,12 +2634,19 @@ def visit_FunctionDef(self, node):
25922634
25932635 if gpu_vectorize :
25942636 writer .write ('@gpu.vectorize' )
2637+ if gpu_method :
2638+ writer .write ('@gpu.method' )
2639+
25952640 ## force python variable scope, and pass user type information to second stage of translation.
25962641 ## the dart backend can use this extra type information.
25972642 vars = []
25982643 local_typedef_names = set ()
25992644 if not self ._with_coffee :
2600- local_vars , global_vars = retrieve_vars (node .body )
2645+ try :
2646+ local_vars , global_vars = retrieve_vars (node .body )
2647+ except SyntaxError as err :
2648+ raise SyntaxError ( self .format_error (err ) )
2649+
26012650 local_vars = local_vars - global_vars
26022651 if local_vars :
26032652 args_typedefs = []
0 commit comments