dragome/dragome-sdk

Bug with for loop generate

Closed this issue · 14 comments

I have case where generate wrong for loop.

I write test 8f1f6dc

this core:

for (int i = 0; i < 10; i++) {
    // ....
}

convert to:

i = 0;
L1: {
    while (true) {
        if (i >= 10) {
            break L1;
        }
        // ....
        i += 1;
    }
}

and work well.

but i think that better if variable "i" place in block L1. Something like this:

L1: {
    i = 0;
    while (true) {
        if (i >= 10) {
            break L1;
        }
        // ....
        i += 1;
    }
}

Because scope of "i" variable is restricted to inside that loop for in java.

And very better if convert this construction in native javascript for-loop )

================================================

But there is something more important.

This code in test:

try {
    for (int i = 0; i < oal.size(); i++) {
        final Integer colObj = oal.get(i);
        if (colObj != null) {
            int temp = colObj;
            temp++;
        }
    }
} finally {
    // ....
}

convert to:

L1: { // <<<< !!!! THIS LABEL NEVER USED !!!

    try {
        i = 0;
        while (true) {

            L2: {  // <<<< !!!! THIS LABEL PLACE IS WRONG !!! It should locate out of loop

                if (i < (this.$$$oal___com_dragome_tests_CallMethodTest$ObjectArrayList.$size$int())) {
                 // ^^^^ !!!! THIS CHECK IS WRONG !!! Need replace "<" to ">="

                    break L2;
                }
            }
            L3: {
                colObj = this.$$$oal___com_dragome_tests_CallMethodTest$ObjectArrayList.$get___int$java_lang_Object(i);
                if (colObj == null) {
                    break L3;
                }
                temp = colObj.$intValue$int();
                temp += 1;
            }
            i += 1;
        }
    } catch(_EX_) {
        if (true){
            //...
        } else throw dragomeJs.nullSaveException(_EX_); 
    }
}

And we have infinity loop or IndexOutOfBoundsException if used "i" for access in array.

Maybe it relate with near "try" and "for".

@fpetrola, I think it is a critical bug.

@fpetrola, What about this bug?

I'm working on this one

I cannot reproduce this bug. This is the output of compiling your test:

$predictUnconstraintMotion$void : function()
    {
       var __ex, __r0, __r1, __r2, __r3, __r4, __r5;
        __r5 = this;
        var __next_label = -1;
        while (1) {
          switch (__next_label) {
            case -1:
            __r1 = 0;
         case 1:
            var __ex;
            try {

            __r3 = __r5.$$$oal___com_dragome_tests_bugs_CallMethodTest$ObjectArrayList;
            __r3 = __r3.$size$int();
            if (__r1 >= __r3){ __next_label = 28; break; }
            __r3 = __r5.$$$oal___com_dragome_tests_bugs_CallMethodTest$ObjectArrayList;
            __r0 = __r3.$get___int$java_lang_Object(__r1);
            __r0 = __r0;
            if (_isNull(__r0)) { __next_label = 25; break; }
            __r2 = __r0.$intValue$int();
            } catch(ex) {
            if (false) {}
            else if (dragomeJs.isInstanceof(ex, java_lang_Object)) {
              __ex = ex;
              __next_label = 34;
              break;
            }else throw dragomeJs.nullSaveException(ex);  }
            __r2 = __r2 + 1;
         case 25:
            __r1 = __r1 + 1;
            __next_label = 1; break;
         case 28:
            __r3 = __r5.$$$oal___com_dragome_tests_bugs_CallMethodTest$ObjectArrayList;
            __r3.$size$int();
            return this;
         case 34:     __r3 = __ex;

            __r4 = __r5.$$$oal___com_dragome_tests_bugs_CallMethodTest$ObjectArrayList;
            __r4.$size$int();
            throw dragomeJs.nullSaveException(__r3);
            default:
              alert("XMLVM internal error: reached default of switch");
          }
        }
    }
}

Are you forcing compilation to Standard compiler? Cause it's selecting Strict compiler for this method.

Are you forcing compilation to Standard compiler? Cause it's selecting Strict compiler for this method.

I do not know how internal compiler work. I use default config options from gdx-shadertoy.
I got it the wrong generate code in my build environment, cut code so that it still existed, and then copy-past it in test.

@fpetrola: Where is the approximate location in the code where generate js code for "for-loop"?

@fpetrola: In your code break without label. There are all break with label in js-code that i have.

@xpenatan: Could this bug be related with the gdx-shadertoy build configuration?

There are two compilers involved, for j2js classes are Parser and Pass1, and for xmlvm it's just about the xslt file.
Are you compiling with eclipse compiler or javac? can you send me your CallMethodTest.class file?

Are you able to find the wrong javascript inside webapp.js?

@nicolaichuk

I also cannot reproduce.

public void test() {
		ArrayList<Integer> oal= new ArrayList<Integer>();
		oal.add(1);
		oal.add(2);
		oal.add(3);

		try {
			for (int i = 0; i < oal.size(); i++) {
				final Integer colObj = oal.get(i);
				if (colObj != null) {
					int temp = colObj;
					temp++;
				}
			}
		} catch (Exception e) {

		} finally {
		}
	}
$test$void: function ()
{
var _0,oal,i,colObj,temp,l2;
	_0 = new java_util_ArrayList();
	_0.$$init_$void();
	oal = _0;
	oal.$add___java_lang_Object$boolean(java_lang_Integer.$valueOf___int$java_lang_Integer(1));
	oal.$add___java_lang_Object$boolean(java_lang_Integer.$valueOf___int$java_lang_Integer(2));
	oal.$add___java_lang_Object$boolean(java_lang_Integer.$valueOf___int$java_lang_Integer(3));
	L1: {
		try {
			i = 0;
			while (true) {
				L2: {
					if (i < (oal.$size$int())) {
						break L2;
					}
					break L1;
				}
				L3: {
					colObj = oal.$get___int$java_lang_Object(i);
					if (colObj == null) {
						break L3;
					}
					temp = colObj.$intValue$int();
					temp += 1;
				}
				i += 1;
			}
		} catch(_EX_) {
			if (dragomeJs.isInstanceof(_EX_, java_lang_Exception)) {
				l2 = _EX_;
			} else throw dragomeJs.nullSaveException(_EX_); 
		}
	}
},

I dont get no infinite loop, can you test it and makes changes to this code to make it happen?

Are you able to find the wrong javascript inside webapp.js?

this code from my app:

java:

    public static class DiscreteDynamicsWorld extends DynamicsWorld {
        public void predictUnconstraintMotion() {
            try {
                for (int i = 0; i < oal.size(); i++) {
                    final Integer colObj = oal.get(i);
                    if (colObj != null) {
                        int temp = colObj;
                        temp++;
                    }
                }
            } finally {
                oal.size();
            }
        }
    }

javascript:

qx.Class.define("com_nalanga_core_bdx_BdxApp$DiscreteDynamicsWorld", 
{
extend: com_nalanga_core_bdx_BdxApp$DynamicsWorld,
construct: function(){},
members:
{
$$init_$void: function ()
{
	arguments.callee.self.superclass.prototype.$$init_$void.call(this);
return this;
},
$predictUnconstraintMotion$void: function ()
{
var i,colObj,temp,l4;
	L1: {
		try {
			i = 0;
			while (true) {
				L2: {
					if (i < (this.$$$oal___com_nalanga_core_bdx_BdxApp$ObjectArrayList.$size$int())) {
						break L2;
					}
				}
				L3: {
					colObj = this.$$$oal___com_nalanga_core_bdx_BdxApp$ObjectArrayList.$get___int$java_lang_Object(i);
					if (colObj == null) {
						break L3;
					}
					temp = colObj.$intValue$int();
					temp += 1;
				}
				i += 1;
			}
		} catch(_EX_) {
			if (true){
				l4 = _EX_;
				this.$$$oal___com_nalanga_core_bdx_BdxApp$ObjectArrayList.$size$int();
				throw dragomeJs.nullSaveException(l4);
			} else throw dragomeJs.nullSaveException(_EX_); 
		}
	}
	this.$$$oal___com_nalanga_core_bdx_BdxApp$ObjectArrayList.$size$int();
}
},
statics:
{
$$clinit_: function(){this.$$clinit_=function(){return this};
 return this;}

}

}

RemoveUnusedCode: true
isObfuscateCode: false
isCheckingCast: false
isCaching: false

I still have not figured out how to build and launch dragome test for web.
I copy my app code in test and hope that this bug reproduced. But no... (

can you send me your CallMethodTest.class file?

@fpetrola, see my BdxApp$DiscreteDynamicsWorld.class by http://tempaster.com/f/f713db688ab928c3e5a8d8f2fe90d465 (The link is valid for a week)

Are you forcing compilation to Standard compiler? Cause it's selecting Strict compiler for this method.
Are you compiling with eclipse compiler or javac?

@fpetrola, Can you patch logging process for collect all need you information for reproduce my build environment? I open issue #169

I still have not figured out how to build and launch dragome test for web.

you mean jre-tests that is built with junit?

if you want I can upload the eclipse project I created that execute tests for web

@xpenatan

if you want I can upload the eclipse project I created that execute tests for web

it will be good.

DragomeWebTest.zip

url: http://localhost:8080/DragomeWebTest/index.html?test

depending of which plugin you use, jre test class may not be marked to compile when running with jetty and they wont compile. You will need to change jetty run config (something like "webapp classpath" ) to include dragome-js-jre\targer\test-classes

@xpenatan, thanks.

@fpetrola, thanks.
Can you briefly tell me what was the bug?

There are some compiler corner cases that j2js cannot handle and they are derived to xmlvm. There was a missing case in your class that j2js tried to process by itself.