• So I'm trying to use compiled JS for the animation code for my PingPong lights. I decided to try compiled JS to see if I can get enough performance to animate a longer string of lights without having to abandon Espruino and reimplement this in C on an AVR co-processor or something.

    So I put "compiled"; as the first line of the function. I connect to my Espruino Pico, and click "send to Espruino". I am given the warning that a function arrived on the Espruino board with "compiled" as the first line.

    No errors pop up in the IDE.

    What am I doing wrong?

    
    I2C1.setup({scl:B6,sda:B7});
    
    var eeprom=require("AT24").connect(I2C1, 128, 512);
    
    numleds=10;
    
    //global functions
    function animate() {
      setTimeout("animate()",20);
      var x;
      if (leds.animode) {x=getTime();}
      leds.flip();
      leds.dotwinkle();
      if (leds.animode) {console.log(getTime()-x);}
    }
    
     //512kbit
    var memmap={
    	slen:32,
    	rlen:40,
    	statOff:0x2000,
    	statMax:192,
    	sEep:eeprom,
    	oEep:eeprom,
    	oOff:0x8000,
    	oMax:1024,
    	oIEE:eeprom,
    	oIOF:0,
    	scEE:eeprom,
    	scOF:0x1000,
    	scMX:64
    };
    
    // LEDS
    gtab=new Uint16Array(256); //snip to make fit in forums
    var leds = {};
    leds.map=memmap;
    leds.spi=SPI1;
    leds.num=numleds;
    leds.afr=0;
    leds.ison=1;
    leds.animode=0;
    leds.aniframe=0;
    leds.anilast=0;
    leds.aniaddr=0;
    leds.zz="\x00\x00";
    leds.sceneid=0;
    leds.lastscene=0;
    leds.scenetime=0;
    
    /* 
    Animation functions, dotwinkle and flip, are located here. 
    */
    
    
    leds.dotwinkle = function () {
    	"compiled";
    	var t=this.t;
    	var tm= this.tm;
    	var ta=this.ta;
    	var ti=this.ti;
    	var b=this.buff;
    	var z=this.tbuf;
    	var o=this.overlay;
    	if (this.animode) {
    		if (this.aniframe > this.anilast) {
    			this.animode=0;
    			this.anilast=0;
    			this.aniframe=0;
    			leds.aniaddr=0;
    			this.overlay.fill(0);
    		} else {
    			this.overlay=this.map.oEep.read(this.ani­addr+this.map.slen*this.aniframe++,this.­num*3);
    		}
    	}
    	if (this.animode & 4 ){
    		leds.tclb.set(o);
        } else if (this.animode & 2){
            for (var i=0;i<30;i++){
              leds.tclb[i]=b[i]+t[i]+o[i];
            }
    	} else {
    		for (var i=0;i<30;i++){
    			var mode=tm[i];
    			var mo=mode&0x03;
    			var s=1+((mode&12)>>2);
    			var pr=mode>>4;
    			if (!(this.animode&2)) {
    				if (mo==1) { //0x01 - high nybble is chance to change, from 0 (1/16) to 15 (16/16 chance to change)
    					var n=Math.random(); //3ms
    					var th=(pr+1)/32;
    	      				if (n<0.5+th){ //8ms
    	      					if(n<=(0.5-th) && t[i]>ti[i]){t[i]-=s;}
    		      			} else {
    	      					if (t[i]<ta[i]){t[i]+=s;}
    	      				}
    				} else if (mo==2) { //fade/pulse. 
    	          			if (this.afr%((1+pr)&7)==0){
    	            				t[i]=E.clip(t[i]+pr&8?s:-1*s,ti[i],ta[i]­);
    						if (t[i] == ti[i] || t[i] == ta[i]) {
    							tm[i]=mode^128;
    						}
    	        			}
    				} else {
    					if (t[i]!==0){if(t[i]>0){t[i]--;} else {t[i]++;}}
    				}
    			}
    			var c=b[i];
    			if (mo || this.afr%((1+pr)&7)==0) {
    				b[i]+=E.clip(z[i]-c,-1,1);
    			}
    			leds.tclb[i]=c+(c?t[i]:0)+o[i]; //10ms
    		}
    	}
    	this.afr=this.afr==255?0:this.afr+1;
    };
    
    leds.flip = function () {
    	var j=0;
    	var i=0;
    	var z=leds.num*3;
    	while (i<z) {
          var rch=gtab[leds.tclb[i++]];
    		var gch=gtab[leds.tclb[i++]];
    		var bch=gtab[leds.tclb[i++]];
    		
    		var ma = Math.max(rch,gch,bch);
    		var mult=1;
            var gdim=31;
    		
    			if (ma <390) {
    				gdim=3;
    				mult=10.33;
    			} else if (ma <700) {
    				gdim=7;
    				mult=4.4;
    			} else if (ma <1700) {
    				gdim=15;
    				mult=2.06;
    			} 
    		
    		this.fbuf[j++]=(this.ison?(gdim|224):224­);
    		this.fbuf[j++]=(bch?Math.max((bch*mult)>­>4,1):0);
    		this.fbuf[j++]=(gch?Math.max((gch*mult)>­>4,1):0);
    		this.fbuf[j++]=(rch?Math.max((rch*mult)>­>4,1):0);
    
    	}
    
    	this.spi.write(0,0,0,0,this.fbuf,0xFF,0x­FF,0xFF,0xFF);
    };
    
    //snip - a whole bunch of functions that set values in these arrays
    
    

    How do I know if the problem is with the IDE failing to recognize that the thing should be compiled (for example, it thinks it's not running on a Pico, but rather some other board that doesn't support compiled JS?) or a problem with my code (something in it that prevents it from being compiled)?

  • It's because it only recognizes basic function declarations (not function expressions). Try:

    function dotwinkle(ths) {
        "compiled";
      // replace 'this' with 'ths'
    }
    
    leds.dotwinkle = function() {
      dotwinkle(this);
    }
    

    You'll also have to pass in 'this' as an argument, as it doesn't handle it properly otherwise.

  • Oh!
    Duh!

    Okay, I'll give that a try tonight :-)

  • Don't abandon espuruino - you code make a custom firmware with your function that needs to be fast.

    @Gordon - have you thought about a binary style of require that takes a char array and loads that at run time, not sure how this could work?

    Take the contents of a .o file and load that as address independent code? I know I'm simplifying here....

  • I think that's effectively what the compiled JS is doing...?
    I remember Gordon went through a number of ideas before settleing on this...

  • Yes, if you look at what happens it actually converts the function into E.nativeCall, which takes a simple string which contains the binary data.

    Also, have you seen http://www.espruino.com/Assembler ?

    You could even point it at a position in flash that contains your code. The trick is setting up the compiler so it compiles to either position independent code, or a specific address - and then you might also need to try and link in Espruino's built-in functions.

    Basically it's actually more hassle to do than just compiling an extra file into Espruino itself. Perhaps if we could get GCC running in JavaScript in the Web IDE then it might make sense, but at the moment I don't think it does.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Debugging compiled JS. "compiled"; on first line, but board warns that it's not compiled

Posted by Avatar for DrAzzy @DrAzzy

Actions