Commit 0c825721 authored by Michael Büsch's avatar Michael Büsch

param assign: Use dynattrs

Signed-off-by: Michael Büsch's avatarMichael Buesch <[email protected]>
parent 572e039a
......@@ -88,13 +88,17 @@ class CallStackElem(object):
# Copy the inbound data into the instance DB
# and add the outbound parameters to the list.
for param in parameters:
if param.isOutbound(blockInterface):
#TODO param interface and instanceDB assignments should
# be done at translation time.
param.interface, param.instanceDB =\
blockInterface, instanceDB
if param.isOutbound:
# This is an outbound parameter.
self.__outboundParams.append(param)
if param.isInbound(blockInterface):
if param.isInbound:
# This is an inbound parameter.
# Transfer data into DBI
structField = param.getLvalueStructField(instanceDB)
structField = param.lValueStructField
if structField.dataType.type in callByRef_Types:
data = param.rvalueOp.resolve().value.byteOffset
else:
......@@ -116,7 +120,7 @@ class CallStackElem(object):
"FC parameter '%s' for call. The specified "
"actual-parameter is not allowed in this call." %\
str(param))
self.interfRefs[param.getInterfaceFieldIndex(blockInterface)] =\
self.interfRefs[param.interfaceFieldIndex] =\
translator(self, param.rvalueOp)
def __trans_IMM(self, oper):
......@@ -159,11 +163,12 @@ class CallStackElem(object):
def __trans_MEM_DB(self, oper):
# A parameter is forwarded from an FB to an FC.
#FIXME the data should be copied to VL
# That also means we need to copy it back into the DB, if var is OUT or INOUT
if oper.value.dbNumber is not None:
# This is a fully qualified DB access.
# Just forward it.
return oper
#FIXME the data should be copied
offset = oper.value.dup()
offset.dbNumber = self.cpu.dbRegister.index
return AwlOperator(oper.MEM_DB,
......@@ -173,7 +178,8 @@ class CallStackElem(object):
def __trans_MEM_DI(self, oper):
# A parameter is forwarded from an FB to an FC.
#FIXME the data should be copied
#FIXME the data should be copied to VL
# That also means we need to copy it back into the DB, if var is OUT or INOUT
offset = oper.value.dup()
offset.dbNumber = self.cpu.diRegister.index
return AwlOperator(oper.MEM_DB,
......@@ -238,7 +244,7 @@ class CallStackElem(object):
for param in self.__outboundParams:
cpu.store(
param.rvalueOp,
structInstance.getFieldData(param.getLvalueStructField(instanceDB))
structInstance.getFieldData(param.lValueStructField)
)
# Assign the DB/DI registers.
self.cpu.dbRegister, self.cpu.diRegister = self.instanceDB, self.prevDiRegister
......
......@@ -2,7 +2,7 @@
#
# AWL simulator - call parameters
#
# Copyright 2013 Michael Buesch <[email protected]>
# Copyright 2013-2014 Michael Buesch <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -26,65 +26,56 @@ from awlsim.core.datastructure import *
from awlsim.core.datablocks import *
from awlsim.core.blocks import *
from awlsim.core.util import *
from awlsim.core.dynattrs import *
class AwlParamAssign(object):
class AwlParamAssign(DynAttrs):
"Parameter assignment for CALL"
def __init__(self, lvalueName, rvalueOp):
self.lvalueName = lvalueName
self.rvalueOp = rvalueOp
dynAttrs = {
# isInbound attribute is True, if this is an
# IN or IN_OUT parameter assignment.
"isInbound" : lambda self, name: self.__isInbound(),
# isOutbound attribute is True, if this is an
# OUT or IN_OUT parameter assignment.
"isOutbound" : lambda self, name: self.__isOutbound(),
def __retTrue(self, interface):
return True
# lValueStructField attribute is the AwlStructField corresponding
# to this parameter's l-value.
"lValueStructField" : lambda self, name: self.__lValueStructField(),
def __retFalse(self, interface):
return False
# interfaceFieldIndex attribute is the index number for the
# parameter assignment l-value in the block interface refs.
"interfaceFieldIndex" : lambda self, name: self.__interfaceFieldIndex(),
}
# Re-assign the isInbound() and isOutbound() methods
# to methods return static values.
def __reassignInboundOutboundMethods(self, interface):
self.isInbound, self.isOutbound = self.__retFalse, self.__retFalse
field = interface.getFieldByName(self.lvalueName)
if field.fieldType == BlockInterfaceField.FTYPE_IN or\
field.fieldType == BlockInterfaceField.FTYPE_INOUT:
self.isInbound = self.__retTrue
if field.fieldType == BlockInterfaceField.FTYPE_OUT or\
field.fieldType == BlockInterfaceField.FTYPE_INOUT:
self.isOutbound = self.__retTrue
def __init__(self, lvalueName, rvalueOp):
self.lvalueName = lvalueName
self.rvalueOp = rvalueOp
self.interface = None
self.instanceDB = None
def isInbound(self, interface):
self.__reassignInboundOutboundMethods(interface)
# Call the re-assigned method
return self.isInbound(None)
def __isInbound(self):
field = self.interface.getFieldByName(self.lvalueName)
return field.fieldType == BlockInterfaceField.FTYPE_IN or\
field.fieldType == BlockInterfaceField.FTYPE_INOUT
def isOutbound(self, interface):
self.__reassignInboundOutboundMethods(interface)
# Call the re-assigned method
return self.isOutbound(None)
def __isOutbound(self):
field = self.interface.getFieldByName(self.lvalueName)
return field.fieldType == BlockInterfaceField.FTYPE_OUT or\
field.fieldType == BlockInterfaceField.FTYPE_INOUT
def __getLvalueStructField_static(self, instanceDB):
return self.__LvaluestructField
# Get the AwlStructField corresponding to this parameter lvalue
def getLvalueStructField(self, instanceDB):
def __lValueStructField(self):
# Find the l-value struct field
self.__LvaluestructField = instanceDB.structInstance.struct.getField(self.lvalueName)
# Re-assign this method to return the found and stored static value.
self.getLvalueStructField = self.__getLvalueStructField_static
# Call the re-assigned method
return self.getLvalueStructField(None)
def __getInterfaceFieldIndex_static(self, interface):
return self.__LvalueInterfIndex
return self.instanceDB.structInstance.struct.getField(self.lvalueName)
def getInterfaceFieldIndex(self, interface):
def __interfaceFieldIndex(self):
# Find the index number for the l-value
self.__LvalueInterfIndex = interface.getFieldIndex(self.lvalueName)
# Re-assign this method to return the found and stored static index value.
self.getInterfaceFieldIndex = self.__getInterfaceFieldIndex_static
# Call the re-assigned method
return self.getInterfaceFieldIndex(None)
return self.interface.getFieldIndex(self.lvalueName)
def __repr__(self):
return "%s := %s" % (self.lvalueName, str(self.rvalueOp))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment