我有以下汇编代码
from PyQt5.QtWidgets import QGraphicsItem, QMenu
from PyQt5.QtGui import QTransform, QPen, QPainter, QColor, QBrush
from PyQt5.QtCore import Qt, QPointF, QRectF, QEvent
from math import sqrt
def scaleRect(rect, scale_x, scale_y):
T = QTransform.fromScale(scale_x, scale_y)
return T.mapRect(rect)
def debugPrintTransformMatrix(T):
print(str(T.m11()) + ' ' + str(T.m12()) + ' ' + str(T.m13()))
print(str(T.m21()) + ' ' + str(T.m22()) + ' ' + str(T.m23()))
print(str(T.m31()) + ' ' + str(T.m32()) + ' ' + str(T.m33()))
# Assumes no shearing or stretching.
# Only Rotation, Translation, and Scaling.
def extractTransformScale(T):
# This is math matrix notation transposed (debug print self.sceneTransform() to see)
Sx = sqrt(T.m11()**2 + T.m12()**2)
Sy = sqrt(T.m21()**2 + T.m22()**2)
return Sx, Sy
def extractTransformTranslate(T):
return T.m31(), T.m32()
class Object(QGraphicsItem):
def sceneEvent(self, event):
if event.type() == QEvent.GraphicsSceneMouseMove:
# move, scale, or rotate
if self._mode in ['scale', 'rotate']:
mouse_pos = event.scenePos()
last_pos = event.lastScenePos()
if self._mode == 'scale':
s = self.mouseScalingFactors(mouse_pos, last_pos)
self.setTransform(self.transform().scale(*s))
if self._mode == 'rotate':
r = self.mouseRotationAngle(mouse_pos, last_pos)
self.setRotation(self.rotation() + r)
return True
return super().sceneEvent(event)
def __init__(self):
super().__init__()
self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsSelectable)
self._selectionPen = QPen(Qt.black, 1.0, style=Qt.DotLine, cap=Qt.FlatCap)
self._lastPos = QPointF(0, 0)
self.setPos(self._lastPos)
self._mode = 'neutral'
def setRenderHints(self, painter):
painter.setRenderHints(QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing | QPainter.TextAntialiasing)
def boundingRectExtraScale(self):
return (1.2 , 1.2)
def mouseScalingFactors(self, pos, last_pos):
delta = pos - last_pos
return (1.01 ** delta.x(), 1.01 ** delta.y())
def mouseRotationAngle(self, pos, last_pos):
return 1 #TODO
def createDefaultContextMenu(self):
menu = QMenu()
if self._mode == 'neutral':
menu.addAction('Scale').triggered.connect(lambda: self.setMode('scale'))
menu.addAction('Rotate').triggered.connect(lambda: self.setMode('rotate'))
else:
menu.addAction('Done Editing').triggered.connect(lambda: self.setMode('neutral'))
return menu
def contextMenuEvent(self, event):
menu = self.createDefaultContextMenu()
menu.exec(event.screenPos())
def setMode(self, mode):
self._mode = mode
def setSelected(self, selected):
super().setSelected(selected)
self.update()
class ShapedObject(Object):
def __init__(self):
super().__init__()
self._shape = {
'name' : 'ellipse',
'radius': 35
}
self._brush = QBrush(Qt.darkGreen)
self._pen = QPen(Qt.yellow, 3)
def shapeDef(self):
return self._shape
def boundingRect(self):
rect = self.shapeRect()
s = self.boundingRectExtraScale()
return scaleRect(rect, *s)
def shape(self): #TODO QPainterPath shape for collision detection
# Should call self.boundingRectExtraScale()
return super().shape()
def paint(self, painter, option, widget):
self.setRenderHints(painter)
#super().paint(painter, option, widget)
shape = self.shapeDef()
name = shape['name']
painter.setBrush(self._brush)
painter.setPen(self._pen)
painter.save()
# ********** HERE IS THE PROBLEM *************
debugPrintTransformMatrix(painter.transform())
painter.rotate(5)
debugPrintTransformMatrix(painter.transform())
rect = self.shapeRect()
if name == 'ellipse':
painter.drawEllipse(rect)
painter.restore()
def shapeRect(self):
shape = self.shapeDef()
name = shape['name']
if name == 'ellipse':
r = shape['radius']
rect = QRectF(-r, -r, 2*r, 2*r)
return rect
####
import sys
from PyQt5.QtWidgets import QMainWindow, QGraphicsScene, QGraphicsView, QApplication
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QMainWindow()
view = QGraphicsView()
scene = QGraphicsScene()
view.setScene(scene)
window.setCentralWidget(view)
ellipse = ShapedObject()
scene.addItem(ellipse)
window.show()
sys.exit(app.exec_())
这适用于静态构建,但共享构建会导致分段错误
.machine power8
.abiversion 2
.section ".toc","aw"
.section .text
GLOBAL(myfunc)
myfunc:
stdu 1,-240(1)
mflr 0
std 0, 0*8(1)
mfcr 8
std 8, 1*8(1)
std 2, 2*8(1)
# Save all non-volatile registers R14-R31
std 14, 4*8(1)
...
# Save all the non-volatile FPRs
...
stwu 1, -48(1)
bl function_call
nop
addi 1, 1, 48
ld 0, 0*8(1)
mtlr 0
ld 8, 1*8(1)
ld 2, 2*8(1)
...
# epilogue, restore stack frame
,是否应该在power8 w.r.t TOC中以不同方式处理共享版本?
答案 0 :(得分:1)
POWER 8和以前的处理器之间的调用约定是相同的。但是,对于ABIv1和ABIv2之间的TOC指针(r2
)处理有一些变化。
在ABIv2中,调用者未在r2
中建立TOC指针;被调用的函数应该对全局入口点执行此操作(即,TOC指针可能与被调用者中使用的指针不同)。为此,ABIv2函数将有一个设置r2
:
0000000000000000 <foo>:
0: 00 00 4c 3c addis r2,r12,0
4: 00 00 42 38 addi r2,r2,0
- 这取决于r12
包含函数全局入口点的地址(这些0值将在最终链接时替换为实际偏移量。)
我在示例中没有看到任何适当的代码设置r12
。你确定你在那里遵守v2 ABI吗?
ABIv2规范可在此处获取:https://members.openpowerfoundation.org/document/dl/576第2.3.2节与此问题最相关。