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 slicc.ast.ExprAST import ExprAST 296657Snate@binkert.org 306657Snate@binkert.orgclass MethodCallExprAST(ExprAST): 316657Snate@binkert.org def __init__(self, slicc, proc_name, expr_ast_vec): 326657Snate@binkert.org super(MethodCallExprAST, self).__init__(slicc) 336657Snate@binkert.org self.proc_name = proc_name 346657Snate@binkert.org self.expr_ast_vec = expr_ast_vec 356657Snate@binkert.org 366657Snate@binkert.org def generate(self, code): 376999Snate@binkert.org tmp = self.slicc.codeFormatter() 386657Snate@binkert.org paramTypes = [] 396657Snate@binkert.org for expr_ast in self.expr_ast_vec: 406657Snate@binkert.org return_type = expr_ast.generate(tmp) 416657Snate@binkert.org paramTypes.append(return_type) 426657Snate@binkert.org 436657Snate@binkert.org obj_type, methodId, prefix = self.generate_prefix(paramTypes) 446657Snate@binkert.org 456657Snate@binkert.org # generate code 466657Snate@binkert.org params = [] 476657Snate@binkert.org for expr_ast in self.expr_ast_vec: 486657Snate@binkert.org return_type,tcode = expr_ast.inline(True) 496657Snate@binkert.org params.append(str(tcode)) 506657Snate@binkert.org fix = code.nofix() 516657Snate@binkert.org code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") 526657Snate@binkert.org code.fix(fix) 536657Snate@binkert.org 546657Snate@binkert.org # Verify that this is a method of the object 556657Snate@binkert.org if methodId not in obj_type.methods: 566690SBrad.Beckmann@amd.com self.error("Invalid method call: Type '%s' does not have a method '%s'", 576690SBrad.Beckmann@amd.com obj_type, methodId) 586657Snate@binkert.org 5911062Snilay@cs.wisc.edu func = obj_type.methods[methodId] 6011062Snilay@cs.wisc.edu func.checkArguments(self.expr_ast_vec) 616657Snate@binkert.org 626657Snate@binkert.org # Return the return type of the method 636657Snate@binkert.org return obj_type.methods[methodId].return_type 646657Snate@binkert.org 656657Snate@binkert.org def findResources(self, resources): 666657Snate@binkert.org pass 676657Snate@binkert.org 686657Snate@binkert.orgclass MemberMethodCallExprAST(MethodCallExprAST): 6911062Snilay@cs.wisc.edu def __init__(self, slicc, obj_expr_ast, func_call): 706657Snate@binkert.org s = super(MemberMethodCallExprAST, self) 7111062Snilay@cs.wisc.edu s.__init__(slicc, func_call.proc_name, func_call.exprs) 726657Snate@binkert.org self.obj_expr_ast = obj_expr_ast 736657Snate@binkert.org 746657Snate@binkert.org def __repr__(self): 756657Snate@binkert.org return "[MethodCallExpr: %r%r %r]" % (self.proc_name, 766657Snate@binkert.org self.obj_expr_ast, 776657Snate@binkert.org self.expr_ast_vec) 786657Snate@binkert.org def generate_prefix(self, paramTypes): 796999Snate@binkert.org code = self.slicc.codeFormatter() 806657Snate@binkert.org 816657Snate@binkert.org # member method call 826657Snate@binkert.org obj_type = self.obj_expr_ast.generate(code) 836657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 846657Snate@binkert.org 856657Snate@binkert.org prefix = "" 866882SBrad.Beckmann@amd.com implements_interface = False 877839Snilay@cs.wisc.edu 887839Snilay@cs.wisc.edu if methodId in obj_type.methods: 897839Snilay@cs.wisc.edu return_type = obj_type.methods[methodId].return_type 907839Snilay@cs.wisc.edu 917839Snilay@cs.wisc.edu else: 926882SBrad.Beckmann@amd.com # 937839Snilay@cs.wisc.edu # Check whether the method is implemented by the super class 947839Snilay@cs.wisc.edu if "interface" in obj_type: 957839Snilay@cs.wisc.edu interface_type = self.symtab.find(obj_type["interface"]); 967839Snilay@cs.wisc.edu 977839Snilay@cs.wisc.edu if methodId in interface_type.methods: 987839Snilay@cs.wisc.edu return_type = interface_type.methods[methodId].return_type 997839Snilay@cs.wisc.edu obj_type = interface_type 1007839Snilay@cs.wisc.edu 1016882SBrad.Beckmann@amd.com else: 1027839Snilay@cs.wisc.edu self.error("Invalid method call: " \ 1037839Snilay@cs.wisc.edu "Type '%s' does not have a method %s, '%s'", 1047839Snilay@cs.wisc.edu obj_type, self.proc_name, methodId) 1056882SBrad.Beckmann@amd.com 1066882SBrad.Beckmann@amd.com else: 1077839Snilay@cs.wisc.edu # 1087839Snilay@cs.wisc.edu # The initial method check has failed, but before generating an 1097839Snilay@cs.wisc.edu # error we must check whether any of the paramTypes implement 1107839Snilay@cs.wisc.edu # an interface. If so, we must check if the method ids using 1117839Snilay@cs.wisc.edu # the inherited types exist. 1127839Snilay@cs.wisc.edu # 1137839Snilay@cs.wisc.edu # This code is a temporary fix and only checks for the methodId 1147839Snilay@cs.wisc.edu # where all paramTypes are converted to their inherited type. The 1157839Snilay@cs.wisc.edu # right way to do this is to replace slicc's simple string 1167839Snilay@cs.wisc.edu # comparison for determining the correct overloaded method, with a 1177839Snilay@cs.wisc.edu # more robust param by param check. 1187839Snilay@cs.wisc.edu # 1197839Snilay@cs.wisc.edu implemented_paramTypes = [] 1207839Snilay@cs.wisc.edu for paramType in paramTypes: 1217839Snilay@cs.wisc.edu implemented_paramType = paramType 1227839Snilay@cs.wisc.edu if paramType.isInterface: 1237839Snilay@cs.wisc.edu implements_interface = True 1247839Snilay@cs.wisc.edu implemented_paramType.abstract_ident = paramType["interface"] 1257839Snilay@cs.wisc.edu else: 1267839Snilay@cs.wisc.edu implemented_paramType.abstract_ident = paramType.c_ident 1277839Snilay@cs.wisc.edu 1287839Snilay@cs.wisc.edu implemented_paramTypes.append(implemented_paramType) 1297839Snilay@cs.wisc.edu 13010075Snilay@cs.wisc.edu implementedMethodId = "" 1317839Snilay@cs.wisc.edu if implements_interface: 13210075Snilay@cs.wisc.edu implementedMethodId = obj_type.methodIdAbstract( 13310075Snilay@cs.wisc.edu self.proc_name, implemented_paramTypes) 1347839Snilay@cs.wisc.edu 1357839Snilay@cs.wisc.edu if implementedMethodId not in obj_type.methods: 13610075Snilay@cs.wisc.edu self.error("Invalid method call: Type '%s' " \ 13710075Snilay@cs.wisc.edu "does not have a method %s, '%s' nor '%s'", 13810075Snilay@cs.wisc.edu obj_type, self.proc_name, methodId, 13910075Snilay@cs.wisc.edu implementedMethodId) 14010075Snilay@cs.wisc.edu 14110075Snilay@cs.wisc.edu # Replace the methodId with the implementedMethodId 14210075Snilay@cs.wisc.edu # found in the method list. 14310075Snilay@cs.wisc.edu methodId = implementedMethodId 14410075Snilay@cs.wisc.edu return_type = obj_type.methods[methodId].return_type 1457839Snilay@cs.wisc.edu 1468341Snilay@cs.wisc.edu if str(obj_type) == "AbstractCacheEntry" or \ 1478644Snilay@cs.wisc.edu str(obj_type) == "AbstractEntry" or \ 1488644Snilay@cs.wisc.edu ("interface" in obj_type and ( 1498644Snilay@cs.wisc.edu obj_type["interface"] == "AbstractCacheEntry" or 1508644Snilay@cs.wisc.edu obj_type["interface"] == "AbstractEntry")): 1518341Snilay@cs.wisc.edu prefix = "%s((*(%s))." % (prefix, code) 1528341Snilay@cs.wisc.edu else: 1538341Snilay@cs.wisc.edu prefix = "%s((%s)." % (prefix, code) 1546657Snate@binkert.org 1556657Snate@binkert.org return obj_type, methodId, prefix 1566657Snate@binkert.org 1576657Snate@binkert.org 1586657Snate@binkert.orgclass ClassMethodCallExprAST(MethodCallExprAST): 1596657Snate@binkert.org def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): 1606657Snate@binkert.org s = super(ClassMethodCallExprAST, self) 1616657Snate@binkert.org s.__init__(slicc, proc_name, expr_ast_vec) 1626657Snate@binkert.org 1636657Snate@binkert.org self.type_ast = type_ast 1646657Snate@binkert.org 1656657Snate@binkert.org def __repr__(self): 1666657Snate@binkert.org return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) 1676657Snate@binkert.org 1686657Snate@binkert.org def generate_prefix(self, paramTypes): 1696657Snate@binkert.org 1706657Snate@binkert.org # class method call 1716657Snate@binkert.org prefix = "(%s::" % self.type_ast 1726657Snate@binkert.org obj_type = self.type_ast.type 1736657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 1746657Snate@binkert.org 1756657Snate@binkert.org return obj_type, methodId, prefix 1766657Snate@binkert.org 1776657Snate@binkert.org__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] 178