def mk_temp_lval(self) -> AST.ASTLval: tmpname = "temp" + str(self.new_tmp_id()) varinfo = self.get_symbol(tmpname, None, None, None, None) id = self.new_id() var = AST.ASTVariable(id, varinfo) id = self.new_id() return AST.ASTLval(id, var, AST.ASTNoOffset(-1))
def mk_field_offset( self, fieldname: str, fieldtype: "BCTyp", offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTFieldOffset: id = self.new_id() return AST.ASTFieldOffset(id, fieldname, fieldtype, offset)
def get_global_denotation( self, gvinfo: AST.ASTVarInfo, gaddr: str, offset: AST.ASTOffset) -> Tuple[AST.ASTVariable, AST.ASTOffset]: addr = int(gaddr, 16) if gvinfo.is_struct: compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo ioffset = addr - gvinfo.global_address fieldoffsets = compinfo.fieldoffsets() prevfinfo: Optional["BCFieldInfo"] = None prevoffset = -1 for (foffset, finfo) in fieldoffsets: if ioffset == foffset: id = self.new_id() var = AST.ASTVariable(id, gvinfo) if finfo.fieldtype.is_array: offset = self.mk_scalar_index_offset(0, offset) offset = self.mk_field_offset(finfo.fieldname, finfo.fieldtype, offset) return (var, offset) elif ioffset > foffset: prevfinfo = finfo prevoffset = foffset else: if prevfinfo is None: raise Exception("Offset mismatch") if prevfinfo.fieldtype.is_array: ftype = cast("BCTypArray", prevfinfo.fieldtype) eltsize = ftype.tgttyp.byte_size() aoffset = ioffset - prevoffset if aoffset % eltsize == 0: aindex = aoffset // eltsize offset = self.mk_scalar_index_offset( aindex, offset) else: raise Exception("Offset mismatch") id = self.new_id() var = AST.ASTVariable(id, gvinfo) offset = self.mk_field_offset(prevfinfo.fieldname, prevfinfo.fieldtype, offset) return (var, offset) else: name = "gv_" + gaddr return (self.mk_global_variable(name, globaladdress=int( gaddr, 16)), offset) else: name = "gv_" + gaddr return (self.mk_global_variable(name, globaladdress=int(gaddr, 16)), offset) else: id = self.new_id() var = AST.ASTVariable(id, gvinfo) return (var, offset)
def mk_register_variable_lval( self, name: str, vtype: Optional["BCTyp"] = None, parameter: Optional[int] = None) -> AST.ASTLval: id = self.new_id() var = self.mk_register_variable(name, vtype, parameter) return AST.ASTLval(id, var, nooffset)
def mk_register_variable_expr( self, name: str, vtype: Optional["BCTyp"] = None, parameter: Optional[int] = None) -> AST.ASTExpr: id = self.new_id() lval = self.mk_register_variable_lval(name, vtype, parameter) return AST.ASTLvalExpr(id, lval)
def mk_global_variable_expr( self, name: str, vtype: Optional["BCTyp"] = None, globaladdress: Optional[int] = None) -> AST.ASTExpr: id = self.new_id() lval = self.mk_global_variable_lval(name, vtype, globaladdress) return AST.ASTLvalExpr(id, lval)
def mk_global_variable_lval( self, name: str, vtype: Optional["BCTyp"] = None, globaladdress: Optional[int] = None) -> AST.ASTLval: id = self.new_id() var = self.mk_global_variable(name, vtype, globaladdress) return AST.ASTLval(id, var, nooffset)
def mk_global_variable( self, name: str, vtype: Optional["BCTyp"] = None, globaladdress: Optional[int] = None) -> AST.ASTVariable: id = self.new_id() varinfo = self.get_symbol(name, vtype, None, None, globaladdress) return AST.ASTVariable(id, varinfo)
def add_symbol(self, vname: str, vtype: Optional["BCTyp"], altname: Optional[str], parameter: Optional[int], globaladdress: Optional[int]) -> None: id = self.new_id() varinfo = AST.ASTVarInfo(id, vname, vtype, altname, parameter, globaladdress) index = (vname, altname) if altname else (vname, "__none__") self._symboltable[index] = varinfo
def mk_call(self, lval: Optional[AST.ASTLval], tgt: AST.ASTExpr, args: List[AST.ASTExpr]) -> AST.ASTCall: id = self.new_id() if not lval: lval = self.mk_ignored_lval() returntype = self.function_returntype(str(tgt)) if returntype and returntype in ["void", "VOID"]: lval = self.mk_ignored_lval() return AST.ASTCall(id, lval, tgt, args)
def mk_returnval_variable_lval(self, iaddr: str, vtype: Optional["BCTyp"]) -> AST.ASTLval: othername = self.other_variable_name("rtn_" + iaddr) if othername is not None and othername.startswith("ignore-"): return self.mk_ignored_lval() else: id = self.new_id() var = self.mk_returnval_variable(iaddr, vtype) return AST.ASTLval(id, var, nooffset)
def mk_branch(self, condition: Optional[AST.ASTExpr], ifbranch: AST.ASTStmt, elsebranch: AST.ASTStmt, relative_offset: int) -> AST.ASTStmt: id = self.new_id() if condition is None: # create a new unknown (unitialized) variable condvar = self.mk_temp_lval() condition = self.mk_lval_expr(condvar) return AST.ASTBranch(id, condition, ifbranch, elsebranch, relative_offset)
def get_struct_field_address(self, gaddr: int) -> AST.ASTExpr: gvname: Optional[str] = None gvinfo: Optional[AST.ASTVarInfo] = None for ((name, _), vinfo) in self.symboltable.items(): if vinfo.is_struct and vinfo.is_global: compinfo = (cast("BCTypComp", vinfo.vtype)).compinfo gvaddr = vinfo.global_address gvextent = gvaddr + compinfo.byte_size() if gaddr >= gvaddr and gaddr < gvextent: gvname = name gvinfo = vinfo break if gvname and gvinfo: compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo ioffset = gaddr - gvinfo.global_address fieldoffsets = compinfo.fieldoffsets() prevfinfo: Optional["BCFieldInfo"] = None prevoffset = -1 if ioffset == 0: id = self.new_id() var = AST.ASTVariable(id, gvinfo) lval = self.mk_lval(var, AST.ASTNoOffset(-1)) return self.mk_address_of(lval) for (foffset, finfo) in fieldoffsets: if ioffset == foffset: id = self.new_id() var = AST.ASTVariable(id, gvinfo) offset = self.mk_field_offset(finfo.fieldname, finfo.fieldtype, AST.ASTNoOffset(-1)) lval = self.mk_lval(var, offset) if finfo.fieldtype.is_array: return self.mk_lval_expr(lval) else: return self.mk_address_of(lval) raise Exception("Struct field not found for address " + hex(gaddr))
def mk_returnval_variable(self, iaddr: str, vtype: Optional["BCTyp"]) -> AST.ASTVariable: id = self.new_id() name = "rtn_" + iaddr altname = self.other_variable_name(name) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, None, None) else: varinfo = self.get_symbol(name, vtype, altname, None, None) return AST.ASTVariable(id, varinfo)
def mk_register_variable( self, name: str, vtype: Optional["BCTyp"] = None, parameter: Optional[int] = None) -> AST.ASTVariable: id = self.new_id() altname = self.register_variable_name(name) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, parameter, None) else: varinfo = self.get_symbol(name, vtype, altname, parameter, None) return AST.ASTVariable(id, varinfo)
def mk_stack_variable(self, offset: int) -> AST.ASTVariable: id = self.new_id() if offset < 0: name = "localvar_" + str(-offset) elif offset == 0: name = "localvar_0" else: name = "argvar_" + str(offset) altname = self.stack_variable_name(offset) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, None, None) else: varinfo = self.get_symbol(name, None, altname, None, None) return AST.ASTVariable(id, varinfo)
def mk_lval_expr(self, lval: AST.ASTLval) -> AST.ASTExpr: id = self.new_id() return AST.ASTLvalExpr(id, lval)
def mk_unary_op(self, op: str, exp: AST.ASTExpr) -> AST.ASTExpr: id = self.new_id() return AST.ASTUnaryOp(id, op, exp)
def mk_question(self, exp1: AST.ASTExpr, exp2: AST.ASTExpr, exp3: AST.ASTExpr) -> AST.ASTExpr: id = self.new_id() return AST.ASTQuestion(id, exp1, exp2, exp3)
def mk_binary_op(self, op: str, exp1: AST.ASTExpr, exp2: AST.ASTExpr) -> AST.ASTExpr: id = self.new_id() return AST.ASTBinaryOp(id, op, exp1, exp2)
def mk_address_of(self, lval: AST.ASTLval) -> AST.ASTAddressOf: id = self.new_id() return AST.ASTAddressOf(id, lval)
def mk_assign(self, lval: AST.ASTLval, rhs: AST.ASTExpr) -> AST.ASTAssign: id = self.new_id() return AST.ASTAssign(id, lval, rhs)
def mk_string_constant(self, expr: AST.ASTExpr, cstr: str, saddr: str) -> AST.ASTStringConstant: id = self.new_id() return AST.ASTStringConstant(id, expr, cstr, saddr)
def mk_integer_constant(self, cvalue: int) -> AST.ASTIntegerConstant: gvinfo = AU.has_global_denotation(self.global_symbols(), hex(cvalue)) id = self.new_id() return AST.ASTIntegerConstant(id, cvalue)
def mk_stack_variable_lval(self, offset: int) -> AST.ASTLval: id = self.new_id() var = self.mk_stack_variable(offset) return AST.ASTLval(id, var, nooffset)
def mk_variable_lval(self, name: str) -> AST.ASTLval: var = self.mk_variable(name) id = self.new_id() return AST.ASTLval(id, var, nooffset)
def mk_scalar_index_offset( self, index: int, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTIndexOffset: indexexpr = self.mk_integer_constant(index) id = self.new_id() return AST.ASTIndexOffset(id, indexexpr, offset)
def mk_memref_expr( self, memexp: AST.ASTExpr, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTExpr: memreflval = self.mk_memref_lval(memexp, offset) id = self.new_id() return AST.ASTLvalExpr(id, memreflval)
def mk_memref_lval( self, memexp: AST.ASTExpr, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTLval: memref = self.mk_memref(memexp) id = self.new_id() return AST.ASTLval(id, memref, offset)
def mk_memref(self, memexp: AST.ASTExpr) -> AST.ASTMemRef: id = self.new_id() return AST.ASTMemRef(id, memexp)