Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Bool variable being set to an object #1029

Open
wklingler opened this issue Nov 3, 2016 · 1 comment
Open

Bool variable being set to an object #1029

wklingler opened this issue Nov 3, 2016 · 1 comment
Labels

Comments

@wklingler
Copy link

wklingler commented Nov 3, 2016

I'm not sure if you have ever run into this before and I'm not even sure if you can do anything on your end but I thought I would just let you know about it and see what your suggestions might be. This function:

public Polygon CalcOuterRect(Polygon fp)
{
            PointD orient = _orientation.NormalizeXY();
            bool bSkipTransform = orient.X== 1.0 && orient.Y== 0.0; // skip if it would be the identity matrix
            double eave0 = _eaveHeight0 + BaseElev;
            double eave1 = _eaveHeight1 + BaseElev;
            Mat4 t = null;

            // [FIXIT] Does this if block need to be here? We're just preserving it from the previous change.
            // I suspect that this was a fix applied to the incorrect place. See GetEaveHeight(), I suspect
            // that's what they were really trying to fix; the 0 elevation check in particular.
            if (_roofType == RoofType.Shed && _eaveHeight0== 0 && _eaveHeight1==0)
            {
                eave0 += 1;
                eave1 += 1;
            }

		    BoundingCube bc;
            if (bSkipTransform)
            {
                bc = fp.GetBoundingCube();
            }
            else
            {
                Polygon fpCopy = new Polygon(fp);
				PointD orientation = new PointD(orient.X, orient.Y);
                PointD leftOrientation = orientation.RotateXY90();
                t = new Mat4();
                //otherToSketch.Set3x3Col(orientation, leftOrientation, PointD.Z_Vector); // this is otherToSketch
                t.Set3x3Row(orientation, leftOrientation, PointD.Z_Vector); // this is sketchToOtherF
                //Mat4 sketchToOther = new Mat4(otherToSketch);
                
                fpCopy.Transform(t);
                bc = fpCopy.GetBoundingCube();
            }
            var lo = bc.lo;
            var hi = bc.hi;

            PointD BL = new PointD(lo.X, hi.Y, eave0);
            PointD FL = new PointD(hi.X, hi.Y, eave0);
            PointD FR = new PointD(hi.X, lo.Y, eave1);
            PointD BR = new PointD(lo.X, lo.Y, eave1);

			Polygon outer = new Polygon(BL, FL, FR, BR);

            if (!bSkipTransform)
            {
                t.Transpose(); // inverse of a rotation transform
                outer.Transform(t);
            }

            return outer;
		}

becomes this in JS:

function Roof2_CalcOuterRect (fp) {
    var orient = (this._orientation).NormalizeXY();
    var eave0 = +this._eaveHeight0 + +this.get_BaseElev();
    var eave = +this._eaveHeight1 + +this.get_BaseElev();
    var t = null;
    if (!((this._roofType !== $T1A().Shed) || 
        (+this._eaveHeight0 !== 0) || (+this._eaveHeight1 !== 0))) {
      eave0 += 1;
      eave += 1;
    }
    var expr_92 = ((+orient.X === 1) && 
      (+orient.Y === 0));
    if (expr_92 !== null) {
      var bc = fp.GetBoundingCube();
    } else {
      var arg_DF_0 = $S07().Construct(fp);
      var orientation = $S04().Construct(orient.X, orient.Y, 0);
      var leftOrientation = orientation.RotateXY90();
      t = $S08().Construct();
      t.Set3x3Row(orientation, leftOrientation, $T09().Z_Vector);
      $S09().CallVirtual("Transform", null, arg_DF_0, t);
      bc = arg_DF_0.GetBoundingCube();
    }
    var lo = bc.lo;
    var hi = bc.hi;
    var arg_15B_0 = $S04().Construct(lo.X, hi.Y, eave0);
    var FL = $S04().Construct(hi.X, hi.Y, eave0);
    var FR = $S04().Construct(hi.X, lo.Y, eave);
    var BR = $S04().Construct(lo.X, lo.Y, eave);
    var outer = $S0A().Construct(arg_15B_0, FL, FR, BR);
    if (expr_92 === null) {
      t.Transpose();
      $S09().CallVirtual("Transform", null, outer, t);
    }
    return outer;
  };

The IL code (from ILSpy) for this function is here:

public Polygon CalcOuterRect(Polygon fp)
{
	PointD orient = this._orientation.NormalizeXY();
	object arg_92_0 = orient.X == 1.0 && orient.Y == 0.0;
	double eave0 = this._eaveHeight0 + this.BaseElev;
	double eave = this._eaveHeight1 + this.BaseElev;
	Mat4 t = null;
	if (this._roofType == RoofType.Shed && this._eaveHeight0 == 0.0 && this._eaveHeight1 == 0.0)
	{
		eave0 += 1.0;
		eave += 1.0;
	}
	object expr_92 = arg_92_0;
	BoundingCube bc;
	if (expr_92 != null)
	{
		bc = fp.GetBoundingCube();
	}
	else
	{
		Polygon arg_DF_0 = new Polygon(fp);
		PointD orientation = new PointD(orient.X, orient.Y, 0.0);
		PointD leftOrientation = orientation.RotateXY90();
		t = new Mat4();
		t.Set3x3Row(orientation, leftOrientation, PointD.Z_Vector);
		arg_DF_0.Transform(t);
		bc = arg_DF_0.GetBoundingCube();
	}
	PointD lo = bc.lo;
	PointD hi = bc.hi;
	PointD arg_15B_0 = new PointD(lo.X, hi.Y, eave0);
	PointD FL = new PointD(hi.X, hi.Y, eave0);
	PointD FR = new PointD(hi.X, lo.Y, eave);
	PointD BR = new PointD(lo.X, lo.Y, eave);
	Polygon outer = new Polygon(arg_15B_0, FL, FR, BR);
	if (expr_92 == null)
	{
		t.Transpose();
		outer.Transform(t);
	}
	return outer;
}

So it makes sense where the JS code came from but it looks like there might be some optimization that the C# compiler is doing and understands how to resolve the IL code to make it work properly because if I turn the optimizer off for the project then arg_92_0 is actually set to a bool and everything works fine in the JS code.

The issue is that when the optimizer is on then the if statement if(expr_92 != null) changes the entire flow of the function because expr_92 will never be null and therefore the else block is never entered.

The workaround that I found is if I actually move

bool bSkipTransform = orient.X== 1.0 && orient.Y== 0.0; // skip if it would be the identity matrix

to right before the if statement so it looks like this:

bool bSkipTransform = orient.X== 1.0 && orient.Y== 0.0; // skip if it would be the identity matrix
if (bSkipTransform)

Then it all translates just fine (in both IL and JSIL). The only reason this worries me is that this problem could happen in a ton of other locations just depending on how the developer likes to format their code. Plus, this type of error was horrible to debug and find and I would prefer to not have to go through that process again. Do you have ideas or suggestions for this?

Thanks!

@iskiselev
Copy link
Member

Could you report it to ILSpy?

@kg kg added the Bug label Feb 24, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants