MethodCallExprAST.py revision 6882
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 36657Snate@binkert.org# All rights reserved. 46657Snate@binkert.org# 56657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org# modification, are permitted provided that the following conditions are 76657Snate@binkert.org# met: redistributions of source code must retain the above copyright 86657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org# documentation and/or other materials provided with the distribution; 126657Snate@binkert.org# neither the name of the copyright holders nor the names of its 136657Snate@binkert.org# contributors may be used to endorse or promote products derived from 146657Snate@binkert.org# this software without specific prior written permission. 156657Snate@binkert.org# 166657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org 286657Snate@binkert.orgfrom m5.util import code_formatter 296657Snate@binkert.org 306657Snate@binkert.orgfrom slicc.ast.ExprAST import ExprAST 316657Snate@binkert.org 326657Snate@binkert.orgclass MethodCallExprAST(ExprAST): 336657Snate@binkert.org def __init__(self, slicc, proc_name, expr_ast_vec): 346657Snate@binkert.org super(MethodCallExprAST, self).__init__(slicc) 356657Snate@binkert.org self.proc_name = proc_name 366657Snate@binkert.org self.expr_ast_vec = expr_ast_vec 376657Snate@binkert.org 386657Snate@binkert.org def generate(self, code): 396657Snate@binkert.org tmp = code_formatter() 406657Snate@binkert.org paramTypes = [] 416657Snate@binkert.org for expr_ast in self.expr_ast_vec: 426657Snate@binkert.org return_type = expr_ast.generate(tmp) 436657Snate@binkert.org paramTypes.append(return_type) 446657Snate@binkert.org 456657Snate@binkert.org obj_type, methodId, prefix = self.generate_prefix(paramTypes) 466657Snate@binkert.org 476657Snate@binkert.org # generate code 486657Snate@binkert.org params = [] 496657Snate@binkert.org for expr_ast in self.expr_ast_vec: 506657Snate@binkert.org return_type,tcode = expr_ast.inline(True) 516657Snate@binkert.org params.append(str(tcode)) 526657Snate@binkert.org fix = code.nofix() 536657Snate@binkert.org code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") 546657Snate@binkert.org code.fix(fix) 556657Snate@binkert.org 566657Snate@binkert.org # Verify that this is a method of the object 576657Snate@binkert.org if methodId not in obj_type.methods: 586690SBrad.Beckmann@amd.com self.error("Invalid method call: Type '%s' does not have a method '%s'", 596690SBrad.Beckmann@amd.com obj_type, methodId) 606657Snate@binkert.org 616657Snate@binkert.org if len(self.expr_ast_vec) != \ 626657Snate@binkert.org len(obj_type.methods[methodId].param_types): 636657Snate@binkert.org # Right number of parameters 646690SBrad.Beckmann@amd.com self.error("Wrong number of parameters for function name: '%s', " + \ 656690SBrad.Beckmann@amd.com "expected: , actual: ", proc_name, 666657Snate@binkert.org len(obj_type.methods[methodId].param_types), 676657Snate@binkert.org len(self.expr_ast_vec)) 686657Snate@binkert.org 696657Snate@binkert.org for actual_type, expected_type in \ 706657Snate@binkert.org zip(paramTypes, obj_type.methods[methodId].param_types): 716882SBrad.Beckmann@amd.com if actual_type != expected_type and \ 726882SBrad.Beckmann@amd.com str(actual_type["interface"]) != str(expected_type): 736690SBrad.Beckmann@amd.com self.error("Type mismatch: expected: %s actual: %s", 746690SBrad.Beckmann@amd.com expected_type, actual_type) 756657Snate@binkert.org 766657Snate@binkert.org # Return the return type of the method 776657Snate@binkert.org return obj_type.methods[methodId].return_type 786657Snate@binkert.org 796657Snate@binkert.org def findResources(self, resources): 806657Snate@binkert.org pass 816657Snate@binkert.org 826657Snate@binkert.orgclass MemberMethodCallExprAST(MethodCallExprAST): 836657Snate@binkert.org def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec): 846657Snate@binkert.org s = super(MemberMethodCallExprAST, self) 856657Snate@binkert.org s.__init__(slicc, proc_name, expr_ast_vec) 866657Snate@binkert.org 876657Snate@binkert.org self.obj_expr_ast = obj_expr_ast 886657Snate@binkert.org 896657Snate@binkert.org def __repr__(self): 906657Snate@binkert.org return "[MethodCallExpr: %r%r %r]" % (self.proc_name, 916657Snate@binkert.org self.obj_expr_ast, 926657Snate@binkert.org self.expr_ast_vec) 936657Snate@binkert.org def generate_prefix(self, paramTypes): 946657Snate@binkert.org code = code_formatter() 956657Snate@binkert.org 966657Snate@binkert.org # member method call 976657Snate@binkert.org obj_type = self.obj_expr_ast.generate(code) 986657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 996657Snate@binkert.org 1006657Snate@binkert.org prefix = "" 1016882SBrad.Beckmann@amd.com implements_interface = False 1026780SBrad.Beckmann@amd.com if methodId not in obj_type.methods: 1036882SBrad.Beckmann@amd.com # 1046882SBrad.Beckmann@amd.com # The initial method check has failed, but before generating an 1056882SBrad.Beckmann@amd.com # error we must check whether any of the paramTypes implement 1066882SBrad.Beckmann@amd.com # an interface. If so, we must check if the method ids using 1076882SBrad.Beckmann@amd.com # the inherited types exist. 1086882SBrad.Beckmann@amd.com # 1096882SBrad.Beckmann@amd.com # This code is a temporary fix and only checks for the methodId 1106882SBrad.Beckmann@amd.com # where all paramTypes are converted to their inherited type. The 1116882SBrad.Beckmann@amd.com # right way to do this is to replace slicc's simple string 1126882SBrad.Beckmann@amd.com # comparison for determining the correct overloaded method, with a 1136882SBrad.Beckmann@amd.com # more robust param by param check. 1146882SBrad.Beckmann@amd.com # 1156882SBrad.Beckmann@amd.com implemented_paramTypes = [] 1166882SBrad.Beckmann@amd.com for paramType in paramTypes: 1176882SBrad.Beckmann@amd.com implemented_paramType = paramType 1186882SBrad.Beckmann@amd.com if paramType.isInterface: 1196882SBrad.Beckmann@amd.com implements_interface = True 1206882SBrad.Beckmann@amd.com implemented_paramType.abstract_ident = paramType["interface"] 1216882SBrad.Beckmann@amd.com else: 1226882SBrad.Beckmann@amd.com implemented_paramType.abstract_ident = paramType.c_ident 1236882SBrad.Beckmann@amd.com 1246882SBrad.Beckmann@amd.com implemented_paramTypes.append(implemented_paramType) 1256882SBrad.Beckmann@amd.com 1266882SBrad.Beckmann@amd.com if implements_interface: 1276882SBrad.Beckmann@amd.com implementedMethodId = obj_type.methodIdAbstract(self.proc_name, 1286882SBrad.Beckmann@amd.com implemented_paramTypes) 1296882SBrad.Beckmann@amd.com else: 1306882SBrad.Beckmann@amd.com implementedMethodId = "" 1316882SBrad.Beckmann@amd.com 1326882SBrad.Beckmann@amd.com if implementedMethodId not in obj_type.methods: 1336882SBrad.Beckmann@amd.com self.error("Invalid method call: " \ 1346882SBrad.Beckmann@amd.com "Type '%s' does not have a method '%s' nor '%s'", 1356882SBrad.Beckmann@amd.com obj_type, methodId, implementedMethodId) 1366882SBrad.Beckmann@amd.com else: 1376882SBrad.Beckmann@amd.com # 1386882SBrad.Beckmann@amd.com # Replace the methodId with the implementedMethodId found in 1396882SBrad.Beckmann@amd.com # the method list. 1406882SBrad.Beckmann@amd.com # 1416882SBrad.Beckmann@amd.com methodId = implementedMethodId 1426882SBrad.Beckmann@amd.com 1436657Snate@binkert.org return_type = obj_type.methods[methodId].return_type 1446657Snate@binkert.org if return_type.isInterface: 1456657Snate@binkert.org prefix = "static_cast<%s &>" % return_type.c_ident 1466657Snate@binkert.org prefix = "%s((%s)." % (prefix, code) 1476657Snate@binkert.org 1486657Snate@binkert.org return obj_type, methodId, prefix 1496657Snate@binkert.org 1506657Snate@binkert.org 1516657Snate@binkert.orgclass ClassMethodCallExprAST(MethodCallExprAST): 1526657Snate@binkert.org def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): 1536657Snate@binkert.org s = super(ClassMethodCallExprAST, self) 1546657Snate@binkert.org s.__init__(slicc, proc_name, expr_ast_vec) 1556657Snate@binkert.org 1566657Snate@binkert.org self.type_ast = type_ast 1576657Snate@binkert.org 1586657Snate@binkert.org def __repr__(self): 1596657Snate@binkert.org return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) 1606657Snate@binkert.org 1616657Snate@binkert.org def generate_prefix(self, paramTypes): 1626657Snate@binkert.org 1636657Snate@binkert.org # class method call 1646657Snate@binkert.org prefix = "(%s::" % self.type_ast 1656657Snate@binkert.org obj_type = self.type_ast.type 1666657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 1676657Snate@binkert.org 1686657Snate@binkert.org return obj_type, methodId, prefix 1696657Snate@binkert.org 1706657Snate@binkert.org__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] 171