2

The following runtime error:

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."

for this code:

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);

I'm not interested in solving the error,
but knowing why it happens: an explanation from a knowledgeable user.

Speculation: I'm guessing it could be related to data hazard in pipelining (using dy before it is ready) as adding the commented line above solves it.

EDIT: This image shows the decompiling of swfs for a slight code variant and a debug mode swf (pinpointed by Daniel in the comments)
http://imageshack.us/a/img853/4057/stackoverflowdecompile.jpg

If the source of the problem was located correctly, the question becomes why is the function at consecutive ‘dup’ calls entering an infinite loop causing the stack to overflow?

4

1 に答える 1

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 の 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
于 2012-12-08T00:57:22.177 に答える