2012-12-07 98 views
2

以下運行錯誤:AS3怪異的堆棧溢出occurence

Output is too long but this is the main idea:

" > outer-scope error "

" > [File_fla::MainTimeline~[O] Object[A] Object[A] *[A] *[A]] {}()"

previous line repeated for every abc bytecode: pushscope, subtract, multiply and convert_d etc.

" > VerifyError: Error #1023: Stack overflow occurred."

此代碼:

import flash.geom.Point; 
function d(p1:Object, p2:Object):Number 
{ 
    var dx:Number = p2.x - p1.x; 
    var dy:Number = p2.y - p1.y; 
    // problem here as adding this line solves it -> (dx *= 1;) 
    dy *= dy; 
    dy += dx; 
    return dy; 
} 
var pt1:Point = new Point(0, 0); 
var pt2:Point = new Point(1, 0); 
d(pt1, pt2); 

我不感興趣,在解決錯誤,
但知道爲什麼會發生:來自有知識的用戶的解釋。

猜測:我猜測它可以在流水線涉及到數據的危險(使用DY之前它已準備好),其添加註釋行上述解決它。

編輯:此圖像顯示的SWF的用於輕微代碼變體和調試模式SWF(由Daniel評價精確定位)
http://imageshack.us/a/img853/4057/stackoverflowdecompile.jpg 的反編譯

如果問題的來源正確定位,問題將變爲爲什麼連續'dup'調用中的函數進入導致堆棧溢出的無限循環?

+0

腳本,因爲它似乎沒有什麼不尋常的,所以它可能是由您執行它的方式造成的。你能添加一些關於這個或更多代碼的更多信息嗎? – inhan

+1

很好找,看起來像只要你在'dy * = dy'之前放置任何東西就行了''它可以工作。另外'dy * = 1 * dy'的作品,所以在我看來,輸入是原因。我注意到另一件事,當你在調試模式下運行它時,它不會跳起來,所以總而言之,我會說你的猜測是正確的 – Daniel

+0

@Daniel出於好奇 - 不是我與你有任何分歧 - 怎麼做你提出這個想法?上述片段是否會向您輸出運行時錯誤? – inhan

回答

0

你究竟想要達到什麼目的? dy *= dy;看起來像你試圖平方dy(dy = dy*dy;)。

如果你正在寫一個平方距離函數,這部分看起來很奇怪:dy += dx;。 我會寫這樣的:

function d(p1:Point, p2:Point):Number 
{ 
    var dx:Number = p2.x - p1.x; 
    var dy:Number = p2.y - p1.y; 
    return dx*dx+dy*dy; 
} 

,如果它比使用Point's distance()方法

有點偏離主題,裸記住Object有點慢快我沒有測試過,你不應該需要在你的情況下使用它。波紋管是一個非常基本的測試:

import flash.utils.*; 
import flash.geom.Point; 

function d(p1:Point, p2:Point):Number 
{ 
    var dx:Number = p2.x - p1.x; 
    var dy:Number = p2.y - p1.y; 
    return dx*dx+dy*dy; 
} 
function d2(p1:Point, p2:Point):Number 
{ 
    var d:Point = p2.subtract(p1); 
    return d.x*d.x+d.y*d.y; 
} 

var p1:Point = new Point(); 
var p2:Point = new Point(1,0); 
var runs:int = 1000000; 

var now:int = getTimer(); 
for(var i:int = 0; i < runs; i++){ 
    d(p1,p2);  
} 
trace(getTimer() - now + " ms");//99ms distanceSquared using typed objects (untyped is~160ms) 

now = getTimer(); 
for(i = 0; i < runs; i++){ 
    d2(p1,p2); 
} 
trace(getTimer() - now + " ms");//689ms distanceSquared using subract and getters - slow 

now = getTimer(); 
for(i = 0; i < runs; i++){ 
    Point.distance(p1,p2); 
} 
trace(getTimer() - now + " ms");//468ms native static method 
+0

嘿喬治,最初代碼的目的是驗證是否連續使用變量會有任何性能優勢:比如先取得dx然後再調用dx,然後再調用dx,我會通過獲得dx並將其平方後節省幾個週期,然後dy ...(避免一個集合,並獲取字節碼,並將變量保存在寄存器中,我猜)...直到我偶然發現了所提出的問題,並且想知道它現在是這個問題核心的原因。 – chadiik

+0

加上我很抱歉dx和dy的命名可能會導致每個主題的混淆。至於Object而不是Point:它是在那裏創建的函數,它可以作爲params Point,也可以是其他自定義類的xs和ys,但是感謝大家:)。 – chadiik