Initial stab at reading Number constants from bytecode

Tue, 06 Apr 2010 19:27:28 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Tue, 06 Apr 2010 19:27:28 +0100
changeset 12
7d748aba47ab
parent 11
1b3267149cbd
child 13
f259da6951e8

Initial stab at reading Number constants from bytecode

lvm.js file | annotate | diff | comparison | revisions
--- a/lvm.js	Tue Apr 06 14:51:25 2010 +0100
+++ b/lvm.js	Tue Apr 06 19:27:28 2010 +0100
@@ -103,6 +103,7 @@
 			this.constants.push(new LValue("boolean", this.readByte()));
 			break;
 		case 3: // Number
+			this.constants.push(new LValue("number", this.readNumber()));
 			break;
 		case 4: // String
 			this.constants.push(LValueFromString(this.readString()));
@@ -135,6 +136,35 @@
 		var len = this.readInt();
 		return this.readBytes(len).substring(0,len-1);
 	},
+	readNumber: function ()
+	{
+		//FIXME: Endianness
+		var bytes = [this.readByte(),this.readByte(),this.readByte(),this.readByte(),
+		             this.readByte(),this.readByte(),this.readByte(),this.readByte()].reverse();
+		
+		var sign = (bytes[0]>>7)&0x1;
+		var exp = (bytes[0]&0x7F)<<4 | (bytes[1]&0xf0)>>4;
+		
+		var frac = ((bytes[1] & 0x0f) * Math.pow(2,48))
+		          + (bytes[2] * Math.pow(2,40))
+		          + (bytes[3] * Math.pow(2,32))
+		          + (bytes[4] * Math.pow(2,24))
+		          + (bytes[5] * Math.pow(2,16))
+		          + (bytes[6] * Math.pow(2,8))
+		          +  bytes[7];
+		
+		if(exp != 0x000 && exp != 0x7FF)
+		{
+			var n = (sign==1?-1:1)*Math.pow(2,exp-1023)*(1+(frac/0x10000000000000));
+			return n;
+		}
+		else if(exp == 0x000)
+		{
+			return sign*0;
+		}
+		else
+			return frac==0?sign*Infinity:NaN;
+	}
 };
 
 function INS_OPCODE(ins)

mercurial