diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..1284123
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/glkote"]
+ path = src/glkote
+ url = https://github.com/erkyrath/glkote.git
diff --git a/build.py b/build.py
index 4cdb3b5..d2a5535 100755
--- a/build.py
+++ b/build.py
@@ -11,30 +11,32 @@
# jQuery, but we don't try to include it -- that makes it hard to integrate
# Quixe with other web services. We assume that the host page already has
# jQuery available (version 1.9 or later).
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
-import sys
import re
import subprocess
+import sys
+
+regex_debug = re.compile(b';;;.+$', re.M)
-regex_debug = re.compile(';;;.+$', re.M)
def compress_source(target, srcls):
- print 'Writing', target
- targetfl = open(target, 'w')
- proc = subprocess.Popen(['python', 'tools/rjsmin.py'],
- stdin=subprocess.PIPE,
- stdout=targetfl)
- for src in srcls:
- fl = open(src)
- dat = fl.read()
- dat = regex_debug.sub('', dat)
- fl.close()
- proc.stdin.write(dat)
- proc.stdin.close()
- ret = proc.wait()
- if (ret):
- raise Exception('Process result code %d' % (ret,))
- targetfl.close()
+ print('Writing', target)
+ with open(target, 'wb') as targetfl:
+ proc = subprocess.Popen([sys.executable, 'tools/rjsmin.py'],
+ stdin=subprocess.PIPE,
+ stdout=targetfl)
+ for src in srcls:
+ with open(src, 'rb') as fl:
+ dat = fl.read()
+ dat = regex_debug.sub(b'', dat)
+ proc.stdin.write(dat)
+ proc.stdin.close()
+ ret = proc.wait()
+ if (ret):
+ raise Exception('Process result code %d' % (ret,))
compress_source(
'lib/glkote.min.js', [
@@ -49,4 +51,3 @@ def compress_source(target, srcls):
'src/quixe/gi_dispa.js',
'src/quixe/gi_load.js',
])
-
diff --git a/lib/glkote.min.js b/lib/glkote.min.js
index 8a5f053..36318d0 100644
--- a/lib/glkote.min.js
+++ b/lib/glkote.min.js
@@ -21,12 +21,8 @@ recording_state.label=iface.recording_label;if(iface.recording_format=='simple')
recording_state.format='simple';else
recording_state.format='glkote';glkote_log('Transcript recording active: session '+recording_state.sessionId+' "'+recording_state.label+'", destination '+recording_handler_url);}}
send_response('init',null,current_metrics);}
-function measure_window(){var metrics={};var el,linesize,winsize,line1size,line2size,spansize;el=$('#'+gameport_id);if(!el.length)
-return'Cannot find gameport element #'+gameport_id+' in this document.';metrics.width=el.width();metrics.height=el.height();el=$('#layouttest_grid');if(!el.length)
-return'Cannot find layouttest_grid element for window measurement.';winsize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridspan');spansize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridline');line1size={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridline2');line2size={width:el.outerWidth(),height:el.outerHeight()};metrics.gridcharheight=($('#layouttest_gridline2').position().top
--$('#layouttest_gridline').position().top);metrics.gridcharwidth=($('#layouttest_gridspan').width()/8);metrics.gridmarginx=winsize.width-spansize.width;metrics.gridmarginy=winsize.height-(line1size.height+line2size.height);el=$('#layouttest_buffer');if(!el.length)
-return'Cannot find layouttest_buffer element for window measurement.';winsize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferspan');spansize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferline');line1size={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferline2');line2size={width:el.outerWidth(),height:el.outerHeight()};metrics.buffercharheight=($('#layouttest_bufferline2').position().top
--$('#layouttest_bufferline').position().top);metrics.buffercharwidth=($('#layouttest_bufferspan').width()/8);metrics.buffermarginx=winsize.width-spansize.width;metrics.buffermarginy=winsize.height-(line1size.height+line2size.height);metrics.outspacingx=0;metrics.outspacingy=0;metrics.inspacingx=0;metrics.inspacingy=0;if(game_interface.spacing!=undefined){metrics.outspacingx=game_interface.spacing;metrics.outspacingy=game_interface.spacing;metrics.inspacingx=game_interface.spacing;metrics.inspacingy=game_interface.spacing;}
+function measure_window(){var metrics={};var linesize,winsize,line1size,line2size,spansize;var gameport=$('#'+gameport_id);if(!gameport.length)
+return'Cannot find gameport element #'+gameport_id+' in this document.';metrics.width=gameport.width();metrics.height=gameport.height();var layout_test_pane=$('
');layout_test_pane.css({position:'absolute',visibility:'hidden',left:'-1000px'});var line=$('
');$('
',{'class':"Style_normal"}).text('12345678').appendTo(line);var gridwin=$('',{'class':"WindowFrame GridWindow"});var gridline1=line.clone().addClass('GridLine').appendTo(gridwin);var gridline2=line.clone().addClass('GridLine').appendTo(gridwin);var gridspan=gridline1.children('span');layout_test_pane.append(gridwin);var bufwin=$('
',{'class':"WindowFrame BufferWindow"});var bufline1=line.clone().addClass('BufferLine').appendTo(bufwin);var bufline2=line.clone().addClass('BufferLine').appendTo(bufwin);var bufspan=bufline1.children('span');layout_test_pane.append(bufwin);layout_test_pane.appendTo(gameport);console.log(layout_test_pane);var get_size=function(element){return{width:element.outerWidth(),height:element.outerHeight()};};winsize=get_size(gridwin);spansize=get_size(gridspan);line1size=get_size(gridline1);line2size=get_size(gridline2);metrics.gridcharheight=gridline2.position().top-gridline1.position().top;metrics.gridcharwidth=gridspan.width()/8;metrics.gridmarginx=winsize.width-spansize.width;metrics.gridmarginy=winsize.height-(line1size.height+line2size.height);winsize=get_size(bufwin);spansize=get_size(bufspan);line1size=get_size(bufline1);line2size=get_size(bufline2);metrics.buffercharheight=bufline2.position().top-bufline1.position().top;metrics.buffercharwidth=bufspan.width()/8;metrics.buffermarginx=winsize.width-spansize.width;metrics.buffermarginy=winsize.height-(line1size.height+line2size.height);layout_test_pane.remove();metrics.outspacingx=0;metrics.outspacingy=0;metrics.inspacingx=0;metrics.inspacingy=0;if(game_interface.spacing!=undefined){metrics.outspacingx=game_interface.spacing;metrics.outspacingy=game_interface.spacing;metrics.inspacingx=game_interface.spacing;metrics.inspacingy=game_interface.spacing;}
if(game_interface.outspacing!=undefined){metrics.outspacingx=game_interface.outspacing;metrics.outspacingy=game_interface.outspacing;}
if(game_interface.inspacing!=undefined){metrics.inspacingx=game_interface.inspacing;metrics.inspacingy=game_interface.inspacing;}
if(game_interface.inspacingx!=undefined)
@@ -906,10 +902,12 @@ str.bufeof=0;else
str.bufeof=str.buflen;if(window.GiDispa)
GiDispa.retain_array(buf);}
return str;}
-function glk_stream_open_resource(filenum,rock){var str;var el=GiLoad.find_data_chunk(filenum);if(!el)
+function glk_stream_open_resource(filenum,rock){var str;if(!window.GiLoad||!GiLoad.find_data_chunk)
+return null;var el=GiLoad.find_data_chunk(filenum);if(!el)
return null;var buf=el.data;var isbinary=(el.type=='BINA');str=gli_new_stream(strtype_Resource,true,false,rock);str.unicode=false;str.isbinary=isbinary;if(buf){str.buf=buf;str.buflen=buf.length;str.bufpos=0;str.bufeof=str.buflen;}
return str;}
-function glk_stream_open_resource_uni(filenum,rock){var str;var el=GiLoad.find_data_chunk(filenum);if(!el)
+function glk_stream_open_resource_uni(filenum,rock){var str;if(!window.GiLoad||!GiLoad.find_data_chunk)
+return null;var el=GiLoad.find_data_chunk(filenum);if(!el)
return null;var buf=el.data;var isbinary=(el.type=='BINA');str=gli_new_stream(strtype_Resource,true,false,rock);str.unicode=true;str.isbinary=isbinary;if(buf){str.buf=buf;str.buflen=buf.length;str.bufpos=0;str.bufeof=str.buflen;}
return str;}
function glk_stream_close(str,result){if(!str)
diff --git a/lib/quixe.min.js b/lib/quixe.min.js
index f727c37..1177108 100644
--- a/lib/quixe.min.js
+++ b/lib/quixe.min.js
@@ -9,7 +9,7 @@ throw ex;}}
function quixe_resume(){try{done_executing=vm_stopped;execute_loop();}
catch(ex){qstackdump();Glk.fatal_error("Quixe run: "+show_exception(ex));if(opt_rethrow_exceptions)
throw ex;}}
-function show_exception(ex){if(typeof(ex)=='string')
+function show_exception(ex){if(typeof(ex)==='string')
return ex;var res=ex.toString();if(ex.message)
res=res+' '+ex.message;if(ex.fileName)
res=res+' '+ex.fileName;if(ex.lineNumber)
@@ -32,10 +32,10 @@ val=val+(" \""+debugfunc.name+"\"");ls.push(val);}
qlog("VM stack dump: "+ls.join(", "));}
var bytestring_table=Array(256);var quotechar_table=Array(256);function setup_bytestring_table(){var ix,val;for(ix=0;ix<0x100;ix++){val=ix.toString(16);if(ix<0x10)
val="0"+val;bytestring_table[ix]=val;}
-for(ix=0;ix<0x100;ix++){if(ix>=0x20&&ix<0x7f){if(ix==0x22||ix==0x27||ix==0x5c)
+for(ix=0;ix<0x100;ix++){if(ix>=0x20&&ix<0x7f){if(ix===0x22||ix===0x27||ix===0x5c)
val="\\"+String.fromCharCode(ix);else
val=String.fromCharCode(ix);}
-else if(ix==0x0a){val="\\n";}
+else if(ix===0x0a){val="\\n";}
else{val="\\x"+bytestring_table[ix];}
quotechar_table[ix]=val;}}
function ByteRead4(arr,addr){return(arr[addr]*0x1000000)+(arr[addr+1]*0x10000)
@@ -64,22 +64,22 @@ function QuoteMem4(addr){if(memmap[addr])
return"0x"+bytestring_table[memmap[addr]]+bytestring_table[memmap[addr+1]]+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];if(memmap[addr+1])
return"0x"+bytestring_table[memmap[addr+1]]+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];if(memmap[addr+2])
return"0x"+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];return"0x"+bytestring_table[memmap[addr+3]];}
-function ReadArgByte(addr){if(addr==0xffffffff)
+function ReadArgByte(addr){if(addr===0xffffffff)
return frame.valstack.pop()&0xFF;else
return Mem1(addr);}
-function WriteArgByte(addr,val){if(addr==0xffffffff)
+function WriteArgByte(addr,val){if(addr===0xffffffff)
frame.valstack.push(val&0xFF);else
MemW1(addr,val);}
-function ReadArgWord(addr){if(addr==0xffffffff)
+function ReadArgWord(addr){if(addr===0xffffffff)
return frame.valstack.pop();else
return Mem4(addr);}
-function WriteArgWord(addr,val){if(addr==0xffffffff)
+function WriteArgWord(addr,val){if(addr===0xffffffff)
frame.valstack.push(val);else
MemW4(addr,val);}
-function ReadStructField(addr,fieldnum){if(addr==0xffffffff)
+function ReadStructField(addr,fieldnum){if(addr===0xffffffff)
return frame.valstack.pop();else
return Mem4(addr+4*fieldnum);}
-function WriteStructField(addr,fieldnum,val){if(addr==0xffffffff)
+function WriteStructField(addr,fieldnum,val){if(addr===0xffffffff)
frame.valstack.push(val);else
MemW4(addr+4*fieldnum,val);}
function SetResumeStore(val){resumevalue=val;}
@@ -91,9 +91,9 @@ val="0"+val;return("\\u"+val);}
else{var val2;val-=0x10000;val2=0xD800+(val>>10);val=0xDC00+(val&0x3FF);return("\\u"+val2.toString(16)+"\\u"+val.toString(16));}}
function QuoteStr1ToString(val){return QuoteCharToString(val.charCodeAt(0));}
var regexp_string_unsafe=/[^a-zA-Z0-9 .,;:?!=_+()-]/g;function QuoteEscapeString(val){val=val.replace(regexp_string_unsafe,QuoteStr1ToString);return'"'+val+'"';}
-function fatal_error(msg){var ix,val;if(arguments.length>1){msg+=" (";for(ix=1;ix
1){msg+=" (";for(ix=1;ix=arr.length){qlog("Bad frameptr in serialized stack frame");return undefined;}
-arr=arr.splice(frameptr,arr.length);var framelen=ByteRead4(arr,0);var localspos=ByteRead4(arr,4);var rawformat=arr.slice(8,localspos);var localsformat=[];var addr=8;while(1){var loctype=ByteRead1(arr,addr);addr++;var locnum=ByteRead1(arr,addr);addr++;if(loctype==0){break;}
-if(loctype!=1&&loctype!=2&&loctype!=4){fatal_error("Invalid local variable size in function header.",loctype);}
+arr=arr.splice(frameptr,arr.length);var framelen=ByteRead4(arr,0);var localspos=ByteRead4(arr,4);var rawformat=arr.slice(8,localspos);var localsformat=[];var addr=8;while(1){var loctype=ByteRead1(arr,addr);addr++;var locnum=ByteRead1(arr,addr);addr++;if(loctype===0){break;}
+if(loctype!==1&&loctype!==2&&loctype!==4){fatal_error("Invalid local variable size in function header.",loctype);}
localsformat.push({size:loctype,count:locnum});}
-var vmfunc=new VMFunc(null,null,localsformat,rawformat);var frame=new StackFrame(vmfunc);frame.framestart=frameptr;for(var i=0;i>>0;context.code.push("pc = "+newpc+";");context.vmfunc.pathaddrs[newpc]=true;}}
-else{oputil_unload_offstate(context,!unconditional);context.code.push("if (("+operand+")==0 || ("+operand+")==1) {");context.code.push("leave_function();");context.code.push("pop_callstub("+operand+");");context.code.push("}");context.code.push("else {");context.code.push("pc = ("+context.cp+"+("+operand+")-2) >>>0;");context.code.push("}");}
+else{oputil_unload_offstate(context,!unconditional);context.code.push("if (("+operand+")===0 || ("+operand+")===1) {");context.code.push("leave_function();");context.code.push("pop_callstub("+operand+");");context.code.push("}");context.code.push("else {");context.code.push("pc = ("+context.cp+"+("+operand+")-2) >>>0;");context.code.push("}");}
context.code.push("return;");}
var opcode_table={0x0:function(context,operands){},0x10:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")+("+operands[1]+")) >>>0);");},0x11:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")-("+operands[1]+")) >>>0);");},0x12:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push(operands[2]+"(("+sign0+")*("+sign1+")) >>>0);");},0x13:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);var holdvar=alloc_holdvar(context);context.code.push(holdvar+"=(("+sign0+")/("+sign1+"));");context.code.push("if (!isFinite("+holdvar+")) fatal_error('Division by zero.');");context.code.push(operands[2]+"("+holdvar+">=0)?Math.floor("+holdvar+"):(-Math.floor(-"+holdvar+") >>>0));");},0x14:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);var holdvar=alloc_holdvar(context);context.code.push(holdvar+"=(("+sign0+")%("+sign1+"));");context.code.push("if (!isFinite("+holdvar+")) fatal_error('Modulo division by zero.');");context.code.push(operands[2]+holdvar+" >>>0);");},0x15:function(context,operands){context.code.push(operands[1]+"(-("+operands[0]+")) >>>0);");},0x18:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")&("+operands[1]+")) >>>0);");},0x19:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")|("+operands[1]+")) >>>0);");},0x1a:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")^("+operands[1]+")) >>>0);");},0x1b:function(context,operands){context.code.push(operands[1]+"(~("+operands[0]+")) >>>0);");},0x1c:function(context,operands){if(quot_isconstant(operands[1])){var val=Number(operands[1]);if(val<32)
context.code.push(operands[2]+"(("+operands[0]+")<<"+val+") >>>0);");else
@@ -190,7 +190,7 @@ context.code.push(operands[2]+"("+operands[0]+")>>>"+val+");");else
context.code.push(operands[2]+"0);");}
else{context.code.push(operands[2]+"("+operands[1]+"<32) ? ("+operands[0]+">>>"+operands[1]+") : 0);");}},0x20:function(context,operands){oputil_perform_jump(context,operands[0],true);context.path_ends=true;},0x104:function(context,operands){if(quot_isconstant(operands[0])){var newpc=Number(operands[0]);context.code.push("pc = "+newpc+";");context.vmfunc.pathaddrs[newpc]=true;}
else{context.code.push("pc = "+operands[0]+";");}
-oputil_unload_offstate(context);context.code.push("return;");context.path_ends=true;},0x22:function(context,operands){context.code.push("if (("+operands[0]+")==0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x23:function(context,operands){context.code.push("if (("+operands[0]+")!=0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x24:function(context,operands){context.code.push("if (("+operands[0]+")==("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x25:function(context,operands){context.code.push("if (("+operands[0]+")!=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x26:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x27:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x28:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x29:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2a:function(context,operands){context.code.push("if (("+operands[0]+")<("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2b:function(context,operands){context.code.push("if (("+operands[0]+")>=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2c:function(context,operands){context.code.push("if (("+operands[0]+")>("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2d:function(context,operands){context.code.push("if (("+operands[0]+")<=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x30:function(context,operands){if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x28:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x29:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2a:function(context,operands){context.code.push("if (("+operands[0]+")<("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2b:function(context,operands){context.code.push("if (("+operands[0]+")>=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2c:function(context,operands){context.code.push("if (("+operands[0]+")>("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2d:function(context,operands){context.code.push("if (("+operands[0]+")<=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x30:function(context,operands){if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix 0) {");context.code.push("if ("+sign1+" > 0) {");context.code.push("vals1 = "+sign1+" % "+sign0+";");context.code.push("} else {");context.code.push("vals1 = "+sign0+" - (-("+sign1+")) % "+sign0+";");context.code.push("}");context.code.push("if (vals1) {");context.code.push("pos = frame.valstack.length - "+sign0+";");context.code.push("roll = frame.valstack.slice(frame.valstack.length-vals1, frame.valstack.length).concat(frame.valstack.slice(pos, frame.valstack.length-vals1));");context.code.push("for (ix=0; ix<"+sign0+"; ix++) { frame.valstack[pos+ix] = roll[ix]; }");context.code.push("roll = undefined;");context.code.push("}");context.code.push("}");},0x54:function(context,operands){oputil_unload_offstate(context);if(quot_isconstant(operands[0])){var ix,holdvar;var pos=Number(operands[0]);for(ix=0;ix0)
expr="Math.floor(random_func() * "+val+")";else
expr="-Math.floor(random_func() * "+(-val)+")";}
else{var sign0=oputil_signify_operand(context,operands[0],true);var holdvar=alloc_holdvar(context);expr=holdvar;context.code.push("if ("+sign0+" > 0)");context.code.push(holdvar+" = Math.floor(random_func() * "+sign0+");");context.code.push("else if ("+sign0+" < 0)");context.code.push(holdvar+" = -Math.floor(random_func() * -"+sign0+");");context.code.push("else");context.code.push(holdvar+" = (Math.floor(random_func() * 0x10000) | (Math.floor(random_func() * 0x10000) << 16)) >>>0;");}
-context.code.push(operands[1]+expr+");");},0x111:function(context,operands){context.code.push("set_random("+operands[0]+");");},0x120:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("done_executing = true; vm_stopped = true;");context.code.push("return;");context.path_ends=true;},0x121:function(context,operands){context.code.push(operands[0]+"perform_verify());");},0x122:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("vm_restart();");context.code.push("return;");context.path_ends=true;},0x123:function(context,operands){oputil_unload_offstate(context);context.varsused["ix"]=true;oputil_push_callstub(context,operands[1]);context.code.push("ix = vm_save("+operands[0]+");");context.code.push("pop_callstub(ix ? 0 : 1);");context.code.push("return;");context.path_ends=true;},0x124:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restore("+operands[0]+")) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[1],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x125:function(context,operands){oputil_unload_offstate(context);oputil_push_callstub(context,operands[0]);context.code.push("vm_saveundo();");context.code.push("pop_callstub(0);");context.code.push("return;");context.path_ends=true;},0x126:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restoreundo()) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[0],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x127:function(context,operands){context.code.push("protectstart="+operands[0]+";");context.code.push("protectend=protectstart+("+operands[1]+");");context.code.push("if (protectstart==protectend) {")
+context.code.push(operands[1]+expr+");");},0x111:function(context,operands){context.code.push("set_random("+operands[0]+");");},0x120:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("done_executing = true; vm_stopped = true;");context.code.push("return;");context.path_ends=true;},0x121:function(context,operands){context.code.push(operands[0]+"perform_verify());");},0x122:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("vm_restart();");context.code.push("return;");context.path_ends=true;},0x123:function(context,operands){oputil_unload_offstate(context);context.varsused["ix"]=true;oputil_push_callstub(context,operands[1]);context.code.push("ix = vm_save("+operands[0]+");");context.code.push("pop_callstub(ix ? 0 : 1);");context.code.push("return;");context.path_ends=true;},0x124:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restore("+operands[0]+")) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[1],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x125:function(context,operands){oputil_unload_offstate(context);oputil_push_callstub(context,operands[0]);context.code.push("vm_saveundo();");context.code.push("pop_callstub(0);");context.code.push("return;");context.path_ends=true;},0x126:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restoreundo()) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[0],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x127:function(context,operands){context.code.push("protectstart="+operands[0]+";");context.code.push("protectend=protectstart+("+operands[1]+");");context.code.push("if (protectstart===protectend) {")
context.code.push(" protectstart=0; protectend=0;");context.code.push("}");},0x170:function(context,operands){context.varsused["maddr"]=true;context.varsused["mlen"]=true;context.varsused["ix"]=true;context.code.push("mlen="+operands[0]+";");context.code.push("maddr="+operands[1]+";");context.code.push("for (ix=0; ix 0x7fffffff))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.floor(valf);");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf < -0x80000000))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.ceil(valf);");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x192:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res > 0x7fffffff) res = 0x7fffffff;");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res < -0x80000000) res = -0x80000000;");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x198:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.ceil("+valf+")));");},0x199:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.floor("+valf+")));");},0x1A0:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" + "+valf1+"));");},0x1A1:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" - "+valf1+"));");},0x1A2:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" * "+valf1+"));");},0x1A3:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" / "+valf1+"));");},0x1A4:function(context,operands){var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.varsused["modv"]=true;context.varsused["quov"]=true;context.code.push("modv=("+valf0+" % "+valf1+");");context.code.push("quov=encode_float(("+valf0+" - modv) / "+valf1+");");context.code.push("if (quov == 0x0 || quov == 0x80000000) {");context.code.push(" quov = (("+operands[0]+" ^ "+operands[1]+") & 0x80000000) >>>0;");context.code.push("}");context.code.push(operands[2]+"encode_float(modv));");context.code.push(operands[3]+"quov);");},0x1A8:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sqrt("+valf+")));");},0x1A9:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.exp("+valf+")));");},0x1AA:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.log("+valf+")));");},0x1AB:function(context,operands){context.varsused["valf"]=true;var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.code.push("if ("+operands[0]+" == 0x3f800000) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else if ("+operands[0]+" == 0xbf800000 && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else {");context.code.push(" valf=encode_float(Math.pow("+valf0+", "+valf1+"));");context.code.push("}");context.code.push(operands[2]+"valf);");},0x1B0:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sin("+valf+")));");},0x1B1:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.cos("+valf+")));");},0x1B2:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.tan("+valf+")));");},0x1B3:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.asin("+valf+")));");},0x1B4:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.acos("+valf+")));");},0x1B5:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.atan("+valf+")));");},0x1B6:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float(Math.atan2("+valf0+", "+valf1+")));");},0x1C0:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) == 0x7f800000 && ("+operands[2]+" & 0x007fffff) != 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" == "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);}
+else{context.code.push(operands[1]+"encode_float("+sign0+"));");}},0x191:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf > 0x7fffffff))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.floor(valf);");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf < -0x80000000))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.ceil(valf);");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x192:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res > 0x7fffffff) res = 0x7fffffff;");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res < -0x80000000) res = -0x80000000;");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x198:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.ceil("+valf+")));");},0x199:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.floor("+valf+")));");},0x1A0:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" + "+valf1+"));");},0x1A1:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" - "+valf1+"));");},0x1A2:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" * "+valf1+"));");},0x1A3:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" / "+valf1+"));");},0x1A4:function(context,operands){var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.varsused["modv"]=true;context.varsused["quov"]=true;context.code.push("modv=("+valf0+" % "+valf1+");");context.code.push("quov=encode_float(("+valf0+" - modv) / "+valf1+");");context.code.push("if (quov === 0x0 || quov === 0x80000000) {");context.code.push(" quov = (("+operands[0]+" ^ "+operands[1]+") & 0x80000000) >>>0;");context.code.push("}");context.code.push(operands[2]+"encode_float(modv));");context.code.push(operands[3]+"quov);");},0x1A8:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sqrt("+valf+")));");},0x1A9:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.exp("+valf+")));");},0x1AA:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.log("+valf+")));");},0x1AB:function(context,operands){context.varsused["valf"]=true;var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.code.push("if ("+operands[0]+" === 0x3f800000) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else if ("+operands[0]+" === 0xbf800000 && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else {");context.code.push(" valf=encode_float(Math.pow("+valf0+", "+valf1+"));");context.code.push("}");context.code.push(operands[2]+"valf);");},0x1B0:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sin("+valf+")));");},0x1B1:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.cos("+valf+")));");},0x1B2:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.tan("+valf+")));");},0x1B3:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.asin("+valf+")));");},0x1B4:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.acos("+valf+")));");},0x1B5:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.atan("+valf+")));");},0x1B6:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float(Math.atan2("+valf0+", "+valf1+")));");},0x1C0:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) === 0x7f800000 && ("+operands[2]+" & 0x007fffff) !== 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" === "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);}
else{val="decode_float(("+operands[2]+") & 0x7fffffff)";valf2=alloc_holdvar(context);context.code.push(valf2+"="+val+";");}
-valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C1:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) == 0x7f800000 && ("+operands[2]+" & 0x007fffff) != 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" == "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);}
+valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C1:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) === 0x7f800000 && ("+operands[2]+" & 0x007fffff) !== 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" === "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);}
else{val="decode_float(("+operands[2]+") & 0x7fffffff)";valf2=alloc_holdvar(context);context.code.push(valf2+"="+val+";");}
-valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (!fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C2:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" < "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C3:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" <= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C4:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" > "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C5:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" >= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C8:function(context,operands){context.code.push("if (("+operands[0]+" & 0x7f800000) == 0x7f800000 && ("+operands[0]+" & 0x007fffff) != 0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x1C9:function(context,operands){context.code.push("if ("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x130:function(context,operands){var mayblock;if(quot_isconstant(operands[0]))
+valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (!fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C2:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" < "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C3:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" <= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C4:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" > "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C5:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" >= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C8:function(context,operands){context.code.push("if (("+operands[0]+" & 0x7f800000) === 0x7f800000 && ("+operands[0]+" & 0x007fffff) !== 0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x1C9:function(context,operands){context.code.push("if ("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x130:function(context,operands){var mayblock;if(quot_isconstant(operands[0]))
mayblock=Glk.call_may_not_return(Number(operands[0]));else
mayblock=true;context.code.push("tempglkargs.length = "+operands[1]+";");if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix>1);for(ix=0;ix>1);for(ix=0;ix>4)&0x0F);modeaddr++;}
-var optype=oplist.formlist[ix];if(optype=="L"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);}
+var optype=oplist.formlist[ix];if(optype==="L"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);}
else{holdvar=alloc_holdvar(context);context.code.push(holdvar+"=frame.valstack.pop();");operands[ix]=holdvar;}
continue;case 0:operands[ix]="0";continue;case 1:value=QuoteMem1(cp);cp++;operands[ix]=value;continue;case 2:value=QuoteMem2(cp);cp+=2;operands[ix]=value;continue;case 3:value=QuoteMem4(cp);cp+=4;operands[ix]=value;continue;}
-if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;}
-else if(mode==10){addr=Mem2(cp);cp+=2;}
-else if(mode==11){addr=Mem4(cp);cp+=4;}
+if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;}
+else if(mode===10){addr=Mem2(cp);cp+=2;}
+else if(mode===11){addr=Mem4(cp);cp+=4;}
if(context.offloc[addr]!==undefined){operands[ix]=context.offloc[addr];continue;}
-if(oplist.argsize==4){value="frame.locals["+addr+"]";}
-else if(oplist.argsize==2){value="frame.locals["+addr+"] & 0xffff";}
+if(oplist.argsize===4){value="frame.locals["+addr+"]";}
+else if(oplist.argsize===2){value="frame.locals["+addr+"] & 0xffff";}
else{value="frame.locals["+addr+"] & 0xff";}
holdvar=alloc_holdvar(context,true);context.code.push(holdvar+"=("+value+");");context.offloc[addr]=holdvar;context.offlocdirty[addr]=false;operands[ix]=holdvar;continue;}
switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in load operand.");}
-if(oplist.argsize==4){value="Mem4("+addr+")";}
-else if(oplist.argsize==2){value="Mem2("+addr+")";}
+if(oplist.argsize===4){value="Mem4("+addr+")";}
+else if(oplist.argsize===2){value="Mem2("+addr+")";}
else{value="Mem1("+addr+")";}
holdvar=alloc_holdvar(context);context.code.push(holdvar+"=("+value+");");operands[ix]=holdvar;continue;}
-else if(optype=="E"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);}
+else if(optype==="E"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);}
else{operands[ix]="frame.valstack.pop()";}
continue;case 0:operands[ix]="0";continue;case 1:value=QuoteMem1(cp);cp++;operands[ix]=value;continue;case 2:value=QuoteMem2(cp);cp+=2;operands[ix]=value;continue;case 3:value=QuoteMem4(cp);cp+=4;operands[ix]=value;continue;}
-if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;}
-else if(mode==10){addr=Mem2(cp);cp+=2;}
-else if(mode==11){addr=Mem4(cp);cp+=4;}
+if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;}
+else if(mode===10){addr=Mem2(cp);cp+=2;}
+else if(mode===11){addr=Mem4(cp);cp+=4;}
if(context.offloc[addr]!==undefined){operands[ix]=context.offloc[addr];continue;}
-if(oplist.argsize==4){value="frame.locals["+addr+"]";}
-else if(oplist.argsize==2){value="frame.locals["+addr+"] & 0xffff";}
+if(oplist.argsize===4){value="frame.locals["+addr+"]";}
+else if(oplist.argsize===2){value="frame.locals["+addr+"] & 0xffff";}
else{value="frame.locals["+addr+"] & 0xff";}
holdvar=alloc_holdvar(context,true);context.code.push(holdvar+"=("+value+");");context.offloc[addr]=holdvar;context.offlocdirty[addr]=false;operands[ix]=holdvar;continue;}
switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in load operand.");}
-if(oplist.argsize==4){value="Mem4("+addr+")";}
-else if(oplist.argsize==2){value="Mem2("+addr+")";}
+if(oplist.argsize===4){value="Mem4("+addr+")";}
+else if(oplist.argsize===2){value="Mem2("+addr+")";}
else{value="Mem1("+addr+")";}
operands[ix]=value;continue;}
-else if(optype=="S"){switch(mode){case 8:holdvar=alloc_holdvar(context,true);context.offstack.push(holdvar);operands[ix]=holdvar+"=(";continue;case 0:operands[ix]="(";continue;}
-if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;}
-else if(mode==10){addr=Mem2(cp);cp+=2;}
-else if(mode==11){addr=Mem4(cp);cp+=4;}
-if(oplist.argsize==4){holdvar=alloc_holdvar(context,true);store_offloc_value(context,addr,holdvar,false);operands[ix]=holdvar+"=(";}
-else if(oplist.argsize==2){store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xffff &";}
+else if(optype==="S"){switch(mode){case 8:holdvar=alloc_holdvar(context,true);context.offstack.push(holdvar);operands[ix]=holdvar+"=(";continue;case 0:operands[ix]="(";continue;}
+if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;}
+else if(mode===10){addr=Mem2(cp);cp+=2;}
+else if(mode===11){addr=Mem4(cp);cp+=4;}
+if(oplist.argsize===4){holdvar=alloc_holdvar(context,true);store_offloc_value(context,addr,holdvar,false);operands[ix]=holdvar+"=(";}
+else if(oplist.argsize===2){store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xffff &";}
else{store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xff &";}
continue;}
switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");}
-if(oplist.argsize==4){value="MemW4("+addr+",";}
-else if(oplist.argsize==2){value="MemW2("+addr+",";}
+if(oplist.argsize===4){value="MemW4("+addr+",";}
+else if(oplist.argsize===2){value="MemW2("+addr+",";}
else{value="MemW1("+addr+",";}
operands[ix]=value;continue;}
-else if(optype=="F"){var funcop=operands.func_store;switch(mode){case 8:funcop.mode=8;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;case 0:funcop.mode=0;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;}
-if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;}
-else if(mode==10){addr=Mem2(cp);cp+=2;}
-else if(mode==11){addr=Mem4(cp);cp+=4;}
+else if(optype==="F"){var funcop=operands.func_store;switch(mode){case 8:funcop.mode=8;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;case 0:funcop.mode=0;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;}
+if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;}
+else if(mode===10){addr=Mem2(cp);cp+=2;}
+else if(mode===11){addr=Mem4(cp);cp+=4;}
funcop.mode=11;funcop.addr=addr;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;}
switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");}
funcop.mode=15;funcop.addr=addr;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;}
-else if(optype=="C"){switch(mode){case 8:operands[ix]="3,0";continue;case 0:operands[ix]="0,0";continue;}
-if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;}
-else if(mode==10){addr=Mem2(cp);cp+=2;}
-else if(mode==11){addr=Mem4(cp);cp+=4;}
+else if(optype==="C"){switch(mode){case 8:operands[ix]="3,0";continue;case 0:operands[ix]="0,0";continue;}
+if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;}
+else if(mode===10){addr=Mem2(cp);cp+=2;}
+else if(mode===11){addr=Mem4(cp);cp+=4;}
operands[ix]="2,"+addr;continue;}
switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");}
operands[ix]="1,"+addr;continue;}
else{fatal_error("Unknown operand type.",optype);}}
return cp;}
-function compile_func(funcaddr){var addr=funcaddr;var functype=Mem1(addr);if(functype!=0xC0&&functype!=0xC1){if(functype>=0xC0&&functype<=0xDF)
+function compile_func(funcaddr){var addr=funcaddr;var functype=Mem1(addr);if(functype!==0xC0&&functype!==0xC1){if(functype>=0xC0&&functype<=0xDF)
fatal_error("Call to unknown type of function.",addr);else
fatal_error("Call to non-function.",addr);}
-addr++;var localsformat=[];var rawstart=addr;var ix=0;while(1){var loctype=Mem1(addr);addr++;var locnum=Mem1(addr);addr++;if(loctype==0){break;}
-if(loctype!=1&&loctype!=2&&loctype!=4){fatal_error("Invalid local variable size in function header.",loctype);}
+addr++;var localsformat=[];var rawstart=addr;var ix=0;while(1){var loctype=Mem1(addr);addr++;var locnum=Mem1(addr);addr++;if(loctype===0){break;}
+if(loctype!==1&&loctype!==2&&loctype!==4){fatal_error("Invalid local variable size in function header.",loctype);}
localsformat.push({size:loctype,count:locnum});}
var rawformat=memmap.slice(rawstart,addr);while(rawformat.length%4)
rawformat.push(0);return new VMFunc(funcaddr,addr,localsformat,rawformat);}
@@ -389,37 +389,37 @@ return make_code(context.code.join("\n"));}
function enter_function(addr,argcount){var ix;total_function_calls++;var accelfunc=accel_address_map[addr];if(accelfunc!==undefined){accel_function_calls++;var val=accelfunc(argcount,tempcallargs);pop_callstub(val);return;}
var vmfunc=vmfunc_table[addr];if(vmfunc===undefined){vmfunc=compile_func(addr);if(addr=0;ix--)
+newframe.framestart=frame.framestart+frame.framelen+4*frame.valstack.length;stack.push(newframe);frame=newframe;if(vmfunc.functype===0xC0){for(ix=argcount-1;ix>=0;ix--)
frame.valstack.push(tempcallargs[ix]);frame.valstack.push(argcount);}
else{for(ix=0;ixval)
-stack.pop();if(stack.length==0)
+stack.pop();if(stack.length===0)
fatal_error("Stack evaporated during throw.");frame=stack[stack.length-1];val-=(frame.framestart+frame.framelen);if(val<0)
fatal_error("Attempted to throw below the frame value stack.");if(val&3)
fatal_error("Attempted to throw to an unaligned address.");val>>>=2;if(val>frame.valstack.length)
fatal_error("Attempted to throw beyond the frame value stack.");frame.valstack.length=val;}
function pop_callstub(val){var destaddr,desttype;if(isNaN(val))
-fatal_error("Function returned undefined value.");var framestart=frame.valstack.pop();if(framestart!=frame.framestart)
+fatal_error("Function returned undefined value.");var framestart=frame.valstack.pop();if(framestart!==frame.framestart)
fatal_error("Call stub frameptr ("+framestart+") "+"does not match frame ("+frame.framestart+")");pc=frame.valstack.pop();destaddr=frame.valstack.pop();desttype=frame.valstack.pop();switch(desttype){case 0:return;case 1:MemW4(destaddr,val);return;case 2:frame.locals[destaddr]=val;return;case 3:frame.valstack.push(val);return;case 0x11:fatal_error("String-terminator call stub at end of function call.");return;case 0x10:stream_string(0,pc,0xE1,destaddr);return;case 0x12:stream_num(0,pc,true,destaddr);return;case 0x13:stream_string(0,pc,0xE0,destaddr);return;case 0x14:stream_string(0,pc,0xE2,destaddr);return;default:fatal_error("Unrecognized desttype in callstub.",desttype);}}
function store_operand(desttype,destaddr,val){switch(desttype){case 0:return;case 1:MemW4(destaddr,val);return;case 2:frame.locals[destaddr]=val;return;case 3:frame.valstack.push(val);return;default:fatal_error("Unrecognized desttype in callstub.",desttype);}}
function store_operand_by_funcop(funcop,val){if(!funcop)
-return;switch(funcop.mode){case 8:frame.valstack.push(val);return;case 0:return;case 11:if(funcop.argsize==4){frame.locals[funcop.addr]=(val);}
-else if(funcop.argsize==2){frame.locals[funcop.addr]=(0xffff&val);}
+return;switch(funcop.mode){case 8:frame.valstack.push(val);return;case 0:return;case 11:if(funcop.argsize===4){frame.locals[funcop.addr]=(val);}
+else if(funcop.argsize===2){frame.locals[funcop.addr]=(0xffff&val);}
else{frame.locals[funcop.addr]=(0xff&val);}
-return;case 15:if(funcop.argsize==4){MemW4(funcop.addr,val);}
-else if(funcop.argsize==2){MemW2(funcop.addr,val);}
+return;case 15:if(funcop.argsize===4){MemW4(funcop.addr,val);}
+else if(funcop.argsize===2){MemW2(funcop.addr,val);}
else{MemW1(funcop.addr,val);}
return;default:fatal_error("Unknown addressing mode in store func by operand.");}}
-function set_random(val){if(val==0){random_func=Math.random;}
+function set_random(val){if(val===0){random_func=Math.random;}
else{srand_set_seed(val);random_func=srand_get_random;}}
var srand_table=undefined;var srand_index1,srand_index2;function srand_set_seed(seed){var i,ii,k,val,loop;if(srand_table===undefined)
srand_table=Array(55);srand_table[54]=seed;srand_index1=0;srand_index2=31;k=1;for(i=0;i<55;i++){ii=(21*i)%55;srand_table[ii]=k;k=(seed-k)>>>0;seed=srand_table[ii];}
@@ -431,96 +431,96 @@ return 0;if(addr>=endmem)
return 0;var tb=Mem1(addr);if(tb>=0xE0){return 3;}
if(tb>=0xC0){return 2;}
if(tb>=0x70&&tb<=0x7F&&addr>=ramstart){return 1;}
-return 0;},2:function func_2_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!=1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;}
+return 0;},2:function func_2_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!==1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;}
var otab=Mem4(obj+16);if(!otab)
-return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},3:function func_3_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop==0)
-return 0;return Mem4(prop+4);},4:function func_4_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop==0)
-return 0;return 4*Mem2(prop+2);},5:function func_5_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr==3)
-return(cla==accel_params[5])?1:0;if(zr==2)
-return(cla==accel_params[4])?1:0;if(zr!=1)
-return 0;if(cla==accel_params[2]){if(accel_helper_obj_in_class(obj))
-return 1;if(obj==accel_params[2])
-return 1;if(obj==accel_params[5])
-return 1;if(obj==accel_params[4])
-return 1;if(obj==accel_params[3])
+return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},3:function func_3_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop===0)
+return 0;return Mem4(prop+4);},4:function func_4_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop===0)
+return 0;return 4*Mem2(prop+2);},5:function func_5_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr===3)
+return(cla===accel_params[5])?1:0;if(zr===2)
+return(cla===accel_params[4])?1:0;if(zr!==1)
+return 0;if(cla===accel_params[2]){if(accel_helper_obj_in_class(obj))
+return 1;if(obj===accel_params[2])
+return 1;if(obj===accel_params[5])
+return 1;if(obj===accel_params[4])
+return 1;if(obj===accel_params[3])
return 1;return 0;}
-if(cla==accel_params[3]){if(accel_helper_obj_in_class(obj))
-return 0;if(obj==accel_params[2])
-return 0;if(obj==accel_params[5])
-return 0;if(obj==accel_params[4])
-return 0;if(obj==accel_params[3])
+if(cla===accel_params[3]){if(accel_helper_obj_in_class(obj))
+return 0;if(obj===accel_params[2])
+return 0;if(obj===accel_params[5])
+return 0;if(obj===accel_params[4])
+return 0;if(obj===accel_params[3])
return 0;return 1;}
-if((cla==accel_params[5])||(cla==accel_params[4]))
+if((cla===accel_params[5])||(cla===accel_params[4]))
return 0;if(!accel_helper_obj_in_class(cla)){Glk.glk_put_jstring("\n[** Programming error: tried to apply 'ofclass' with non-class **]\n");return 0;}
-prop=accel_helper_get_prop(obj,2);if(prop==0)
-return 0;inlist=Mem4(prop+4);if(inlist==0)
-return 0;inlistlen=Mem2(prop+2);for(jx=0;jx1)?argv[1]:0);var addr;addr=accel_func_map[3](argc,argv);if(addr==0){if((id>0)&&(id1)?argv[1]:0);var addr;addr=accel_func_map[3](argc,argv);if(addr===0){if((id>0)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr==3){if(id==indiv_prop_start+6)
-return 1;if(id==indiv_prop_start+7)
+return Mem4(addr);},7:function func_7_op__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr===3){if(id===indiv_prop_start+6)
+return 1;if(id===indiv_prop_start+7)
return 1;return 0;}
-if(zr==2){return((id==indiv_prop_start+5)?1:0);}
-if(zr!=1)
+if(zr===2){return((id===indiv_prop_start+5)?1:0);}
+if(zr!==1)
return 0;if((id>=indiv_prop_start)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!=1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;}
+return((accel_func_map[3](argc,argv))?1:0);},8:function func_8_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!==1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;}
var otab=Mem4(obj+4*(3+(accel_params[7]>>2)));if(!otab)
-return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},9:function func_9_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop==0)
-return 0;return Mem4(prop+4);},10:function func_10_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop==0)
-return 0;return 4*Mem2(prop+2);},11:function func_11_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr==3)
-return(cla==accel_params[5])?1:0;if(zr==2)
-return(cla==accel_params[4])?1:0;if(zr!=1)
-return 0;if(cla==accel_params[2]){if(accel_helper_obj_in_class(obj))
-return 1;if(obj==accel_params[2])
-return 1;if(obj==accel_params[5])
-return 1;if(obj==accel_params[4])
-return 1;if(obj==accel_params[3])
+return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},9:function func_9_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop===0)
+return 0;return Mem4(prop+4);},10:function func_10_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop===0)
+return 0;return 4*Mem2(prop+2);},11:function func_11_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr===3)
+return(cla===accel_params[5])?1:0;if(zr===2)
+return(cla===accel_params[4])?1:0;if(zr!==1)
+return 0;if(cla===accel_params[2]){if(accel_helper_obj_in_class(obj))
+return 1;if(obj===accel_params[2])
+return 1;if(obj===accel_params[5])
+return 1;if(obj===accel_params[4])
+return 1;if(obj===accel_params[3])
return 1;return 0;}
-if(cla==accel_params[3]){if(accel_helper_obj_in_class(obj))
-return 0;if(obj==accel_params[2])
-return 0;if(obj==accel_params[5])
-return 0;if(obj==accel_params[4])
-return 0;if(obj==accel_params[3])
+if(cla===accel_params[3]){if(accel_helper_obj_in_class(obj))
+return 0;if(obj===accel_params[2])
+return 0;if(obj===accel_params[5])
+return 0;if(obj===accel_params[4])
+return 0;if(obj===accel_params[3])
return 0;return 1;}
-if((cla==accel_params[5])||(cla==accel_params[4]))
+if((cla===accel_params[5])||(cla===accel_params[4]))
return 0;if(!accel_helper_obj_in_class(cla)){Glk.glk_put_jstring("\n[** Programming error: tried to apply 'ofclass' with non-class **]\n");return 0;}
-prop=accel_helper_get_prop_new(obj,2);if(prop==0)
-return 0;inlist=Mem4(prop+4);if(inlist==0)
-return 0;inlistlen=Mem2(prop+2);for(jx=0;jx1)?argv[1]:0);var addr;addr=accel_func_map[9](argc,argv);if(addr==0){if((id>0)&&(id1)?argv[1]:0);var addr;addr=accel_func_map[9](argc,argv);if(addr===0){if((id>0)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr==3){if(id==indiv_prop_start+6)
-return 1;if(id==indiv_prop_start+7)
+return Mem4(addr);},13:function func_13_op__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr===3){if(id===indiv_prop_start+6)
+return 1;if(id===indiv_prop_start+7)
return 1;return 0;}
-if(zr==2){return((id==indiv_prop_start+5)?1:0);}
-if(zr!=1)
+if(zr===2){return((id===indiv_prop_start+5)?1:0);}
+if(zr!==1)
return 0;if((id>=indiv_prop_start)&&(id>16;obj=cla;}
-accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[2](2,accel_helper_temp_args);if(prop==0)
-return 0;if(accel_helper_obj_in_class(obj)&&(cla==0)){if((id=accel_params[1]+8))
+accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[2](2,accel_helper_temp_args);if(prop===0)
+return 0;if(accel_helper_obj_in_class(obj)&&(cla===0)){if((id=accel_params[1]+8))
return 0;}
-if(Mem4(accel_params[6])!=obj){if(Mem1(prop+9)&1)
+if(Mem4(accel_params[6])!==obj){if(Mem1(prop+9)&1)
return 0;}
return prop;}
function accel_helper_get_prop_new(obj,id)
-{var cla=0;var prop;if(id&0xFFFF0000){cla=Mem4(accel_params[0]+((id&0xFFFF)*4));accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=cla;if(accel_func_map[11](2,accel_helper_temp_args)==0)
+{var cla=0;var prop;if(id&0xFFFF0000){cla=Mem4(accel_params[0]+((id&0xFFFF)*4));accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=cla;if(accel_func_map[11](2,accel_helper_temp_args)===0)
return 0;id=id>>16;obj=cla;}
-accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[8](2,accel_helper_temp_args);if(prop==0)
-return 0;if(accel_helper_obj_in_class(obj)&&(cla==0)){if((id=accel_params[1]+8))
+accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[8](2,accel_helper_temp_args);if(prop===0)
+return 0;if(accel_helper_obj_in_class(obj)&&(cla===0)){if((id=accel_params[1]+8))
return 0;}
-if(Mem4(accel_params[6])!=obj){if(Mem1(prop+9)&1)
+if(Mem4(accel_params[6])!==obj){if(Mem1(prop+9)&1)
return 0;}
return prop;}
-function set_string_table(addr){if(stringtable==addr)
-return;decoding_tree=undefined;vmstring_table=undefined;stringtable=addr;if(stringtable==0){return;}
+function set_string_table(addr){if(stringtable===addr)
+return;decoding_tree=undefined;vmstring_table=undefined;stringtable=addr;if(stringtable===0){return;}
var textenv=vmtextenv_table[stringtable];if(textenv===undefined){var dectab=undefined;var tablelen=Mem4(stringtable);var rootaddr=Mem4(stringtable+8);var cache_stringtable=(stringtable+tablelen<=ramstart);if(cache_stringtable){var tmparray=Array(1);build_decoding_tree(tmparray,rootaddr,4,0);dectab=tmparray[0];if(dectab===undefined)
fatal_error("Failed to create decoding tree.");}
textenv=new VMTextEnv(stringtable,dectab);vmtextenv_table[stringtable]=textenv;}
@@ -529,18 +529,18 @@ function set_iosys(mode,rock){switch(mode){case 0:rock=0;break;case 1:break;case
iosysmode=mode;iosysrock=rock;var textenv=vmtextenv_table[stringtable];if(textenv===undefined)
vmstring_table=undefined;else
vmstring_table=textenv.vmstring_tables[iosysmode];}
-function build_decoding_tree(cablist,nodeaddr,depth,mask){var ix,type,cab;var depthbit;type=Mem1(nodeaddr);if(type==0&&depth==4){cab=Array(16);cab.type=0;cab.depth=4;cablist[mask]=cab;build_decoding_tree(cab,nodeaddr,0,0);return;}
-if(type==0){var leftaddr=Mem4(nodeaddr+1);var rightaddr=Mem4(nodeaddr+5);build_decoding_tree(cablist,leftaddr,depth+1,mask);build_decoding_tree(cablist,rightaddr,depth+1,(mask|(1<>=bitnum;numbits=(8-bitnum);readahead=false;if(!(decoding_tree instanceof Array)){done=true;}
cablist=decoding_tree;while(!done){if(numbits<4){var newbyte=Mem1(addr+1);bits|=(newbyte<>=cab.depth;bitnum+=cab.depth;if(bitnum>=8){addr+=1;bitnum-=8;if(readahead){readahead=false;}
else{var newbyte=Mem1(addr);bits|=(newbyte<=0x09)
-context.code.push("oaddr = Mem4(oaddr);");if(cab.type==0x0B)
-context.code.push("oaddr = Mem4(oaddr);");context.code.push("otype = Mem1(oaddr);");retval="retval";done=true;oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("if (otype >= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(cab.type==0x0A||cab.type==0x0B){argc=Mem4(cab.addr+4);for(var ix=0;ix= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(cab.type===0x0A||cab.type===0x0B){argc=Mem4(cab.addr+4);for(var ix=0;ix>=bitnum;node=Mem4(stringtable+8);while(!done){nodetype=Mem1(node);node++;switch(nodetype){case 0x00:if(byt&1)
node=Mem4(node+4);else
-node=Mem4(node+0);if(bitnum==7){bitnum=0;addr++;byt=Mem1(addr);}
+node=Mem4(node+0);if(bitnum===7){bitnum=0;addr++;byt=Mem1(addr);}
else{bitnum++;byt>>=1;}
break;case 0x01:retval=false;done=true;break;case 0x02:ch=Mem1(node);switch(curiosys){case 2:context.buffer.push(CharToString(ch));break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("tempcallargs[0]="+ch+";");context.code.push("enter_function(iosysrock, 1);");retval=true;done=true;break;}
node=Mem4(stringtable+8);break;case 0x04:ch=Mem4(node);switch(curiosys){case 2:context.buffer.push(CharToString(ch));break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("tempcallargs[0]="+ch+";");context.code.push("enter_function(iosysrock, 1);");retval=true;done=true;break;}
-node=Mem4(stringtable+8);break;case 0x03:switch(curiosys){case 2:while(true){ch=Mem1(node);if(ch==0)
+node=Mem4(stringtable+8);break;case 0x03:switch(curiosys){case 2:while(true){ch=Mem1(node);if(ch===0)
break;context.buffer.push(CharToString(ch));node++;}
break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);retval="["+node+", 0xE0, 0]";done=true;break;}
-node=Mem4(stringtable+8);break;case 0x05:switch(curiosys){case 2:while(true){ch=Mem4(node);if(ch==0)
+node=Mem4(stringtable+8);break;case 0x05:switch(curiosys){case 2:while(true){ch=Mem4(node);if(ch===0)
break;context.buffer.push(CharToString(ch));node+=4;}
break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);retval="["+node+", 0xE2, 0]";done=true;break;}
-node=Mem4(stringtable+8);break;case 0x08:case 0x09:case 0x0A:case 0x0B:oputil_flush_string(context);oputil_push_substring_callstub(context);context.code.push("var otype, retval;");context.code.push("var oaddr = "+Mem4(node)+";");if(nodetype==0x09||nodetype==0x0B)
-context.code.push("oaddr = Mem4(oaddr);");context.code.push("otype = Mem1(oaddr);");retval="retval";done=true;oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("if (otype >= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(nodetype==0x0A||nodetype==0x0B){argc=Mem4(node+4);for(var ix=0;ix= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(nodetype===0x0A||nodetype===0x0B){argc=Mem4(node+4);for(var ix=0;ix=0xE0&&type<=0xFF){fatal_error("Attempt to print unknown type of string.");}
@@ -616,18 +616,18 @@ var tempsearchkey=[];function fetch_search_key(addr,len,options){var ix;tempsear
tempsearchkey[ix]=Mem1(addr+ix);}
else{switch(len){case 4:tempsearchkey[0]=(addr>>24)&0xFF;tempsearchkey[1]=(addr>>16)&0xFF;tempsearchkey[2]=(addr>>8)&0xFF;tempsearchkey[3]=addr&0xFF;break;case 2:tempsearchkey[0]=(addr>>8)&0xFF;tempsearchkey[1]=addr&0xFF;break;case 1:tempsearchkey[0]=addr&0xFF;break;default:throw('Direct search key must hold one, two, or four bytes.');}}
return tempsearchkey;}
-function linear_search(key,keysize,start,structsize,numstructs,keyoffset,options){var ix,count,match,byt;var retindex=((options&4)!=0);var zeroterm=((options&2)!=0);var keybuf=fetch_search_key(key,keysize,options);for(count=0;count>1;addr=start+val*structsize;for(ix=0;(!cmp)&&ix>1;addr=start+val*structsize;for(ix=0;(!cmp)&&ixbyt2)
cmp=1;}
if(!cmp){if(retindex)
@@ -638,18 +638,18 @@ else{top=val;}}
if(retindex)
return 0xFFFFFFFF;else
return 0;}
-function linked_search(key,keysize,start,keyoffset,nextoffset,options){var ix,byt,match;var zeroterm=((options&2)!=0);var keybuf=fetch_search_key(key,keysize,options);while(start!=0){match=true;for(ix=0;match&&ix>23&0xff);if(expo){res=((val&0x7fffff|0x800000)/8388608*Math.pow(2,(expo-127)));}
else{res=((val&0x7fffff)/8388608*Math.pow(2,-126));}
@@ -660,35 +660,35 @@ function encode_float(val){var absval,fbits;var mant,expo,sign;if(isNaN(val)){re
if(!isFinite(val)){if(val<0)
return 0xff800000;else
return 0x7f800000;}
-if(val==0){if(1/val<0)
+if(val===0){if(1/val<0)
return 0x80000000;else
return 0x0;}
if(val<0){sign=true;absval=-val;}
else{sign=false;absval=val;}
expo=Math.floor(Math.log(absval)/Math.log(2));mant=absval/Math.pow(2,expo);if(expo>=128){return(sign?0xff800000:0x7f800000);}
else if(expo<-126){mant=mant*Math.pow(2,126+expo);expo=0;}
-else if(!(expo==0&&mant==0.0)){expo+=127;mant-=1.0;}
+else if(!(expo===0&&mant===0.0)){expo+=127;mant-=1.0;}
mant=mant*8388608.0;fbits=(mant+0.4999999999999999)<<0;if(fbits>=8388608){fbits=0;expo++;if(expo>=255){return(sign?0xff800000:0x7f800000);}}
if(sign)
return((0x80000000)|(expo<<23)|(fbits))>>>0;else
return(expo<<23)|(fbits);}
var game_image=null;var game_signature=null;var opt_rethrow_exceptions=null;var memmap;var stack;var frame;var vm_started=false;var vm_stopped=false;var tempcallargs;var tempglkargs;var done_executing;var vmfunc_table;var vmtextenv_table;var decoding_tree;var vmstring_table;var random_func;var ramstart;var endgamefile;var origendmem;var stacksize;var startfuncaddr;var origstringtable;var checksum;var pc;var stringtable;var endmem;var protectstart,protectend;var iosysmode,iosysrock;var undostack;var resumefuncop,resumevalue;var heapstart;var usedlist;var freelist;var total_execution_time=0;var total_function_calls=0;var accel_function_calls=0;var total_path_calls=0;var paths_cached=0;var paths_compiled=0;var strings_cached=0;var strings_compiled=0;function setup_vm(){var val,version;if(!game_image)
fatal_error("There is no Glulx game file loaded.");vm_started=true;resumefuncop=null;resumevalue=0;memmap=null;stack=[];frame=null;pc=0;if(game_image.length<36)
-fatal_error("This is too short to be a valid Glulx file.");val=ByteRead4(game_image,0);if(val!=0x476c756c)
+fatal_error("This is too short to be a valid Glulx file.");val=ByteRead4(game_image,0);if(val!==0x476c756c)
fatal_error("This is not a valid Glulx file.");version=ByteRead4(game_image,4);if(version<0x20000)
fatal_error("This Glulx file is too old a version to execute.");if(version>=0x30200)
fatal_error("This Glulx file is too new a version to execute.");ramstart=ByteRead4(game_image,8);endgamefile=ByteRead4(game_image,12);origendmem=ByteRead4(game_image,16);stacksize=ByteRead4(game_image,20);startfuncaddr=ByteRead4(game_image,24);origstringtable=ByteRead4(game_image,28);checksum=ByteRead4(game_image,32);protectstart=0;protectend=0;if(ramstart<0x100||endgamefile0){result.push(0);result.push(zeroes-1);}
-while(i0){count=Glk.glk_get_buffer_stream(str,buffer);quetzal=quetzal.concat(buffer.slice(0,count));}
quetzal=unpack_iff_chunks(quetzal);if(!quetzal){qlog("vm_restore failed: file is not Quetzal");return false;}
-quetzal=quetzal["FORM"];if(!quetzal||ByteReadString(quetzal,0,4)!="IFZS"){qlog("vm_restore failed: file doesn't start with FORM/IFZS header");return false;}
+quetzal=quetzal["FORM"];if(!quetzal||ByteReadString(quetzal,0,4)!=="IFZS"){qlog("vm_restore failed: file doesn't start with FORM/IFZS header");return false;}
var chunks=unpack_iff_chunks(quetzal.slice(4));if(!chunks["IFhd"]){qlog("vm_restore failed: missing required IFhd chunk");return false;}
-for(var i=0;i<128;i++){if(chunks["IFhd"][i]!=game_image[i]){qlog("vm_restore failed: this save image is for a different game");return false;}}
+for(var i=0;i<128;i++){if(chunks["IFhd"][i]!==game_image[i]){qlog("vm_restore failed: this save image is for a different game");return false;}}
if(!chunks["CMem"]){qlog("vm_restore failed: missing required CMem chunk");return false;}
if(!chunks["Stks"]){qlog("vm_restore failed: missing required Stks chunk");return false;}
var protect=copy_protected_range();heap_clear();var newendmem=ByteRead4(chunks["CMem"],0);var ram_xor=chunks["CMem"].slice(4);ram_xor=decompress_bytes(ram_xor);while(ram_xor.length10){undostack.shift();}}
-function vm_restoreundo(){if(undostack.length==0){return false;}
+function vm_restoreundo(){if(undostack.length===0){return false;}
var snapshot=undostack.pop();var protect=copy_protected_range();memmap=memmap.slice(0,ramstart).concat(snapshot.ram);endmem=snapshot.endmem;stack=snapshot.stack;frame=stack[stack.length-1];pc=snapshot.pc;heapstart=snapshot.heapstart;usedlist=snapshot.usedlist;freelist=snapshot.freelist;paste_protected_range(protect);return true;}
-function change_memsize(newlen,internal){var lx;if(newlen==endmem)
+function change_memsize(newlen,internal){var lx;if(newlen===endmem)
return;if((!internal)&&heap_is_active())
fatal_error("Cannot resize Glulx memory space while heap is active.");if(newlenendmem)
end=endmem;for(ix=0,addr=start;addr>>0;for(ix=0;ix>>0;}
-if(newsum!=checksum)
+if(newsum!==checksum)
return 1;return 0;}
function quixe_get_signature(){return game_signature;}
function quixe_get_statistics(){var stat={game_image_length:game_image.length,total_execution_time:total_execution_time,total_function_calls:total_function_calls,accel_function_calls:accel_function_calls,total_path_calls:total_path_calls,paths_cached:paths_cached,paths_compiled:paths_compiled,strings_cached:strings_cached,strings_compiled:strings_compiled};return stat;}
@@ -759,22 +759,22 @@ for(var i=0,max=freelist.length;isize){freelist.push(new HeapBlock(addr+size,rounded_up_size-size));}
usedlist.push(new HeapBlock(addr,size));return addr;}
-function heap_free(addr){var pos=heap_binary_search(usedlist,addr);var block=usedlist[pos];if(!block||block.addr!=addr){fatal_error("Tried to free non-existent block");}
-usedlist.splice(pos,1);if(usedlist.length==0){change_memsize(heapstart,true);heap_clear();return;}
-pos=heap_binary_search(freelist,addr);var next=freelist[pos];if(next&&next.addr==block.end){block=new HeapBlock(addr,block.size+next.size);freelist.splice(pos,1);}
-var prev=freelist[pos-1];if(prev&&prev.end==block.addr){block=new HeapBlock(prev.addr,prev.size+block.size);freelist.splice(pos-1,1);pos-=1;}
+function heap_free(addr){var pos=heap_binary_search(usedlist,addr);var block=usedlist[pos];if(!block||block.addr!==addr){fatal_error("Tried to free non-existent block");}
+usedlist.splice(pos,1);if(usedlist.length===0){change_memsize(heapstart,true);heap_clear();return;}
+pos=heap_binary_search(freelist,addr);var next=freelist[pos];if(next&&next.addr===block.end){block=new HeapBlock(addr,block.size+next.size);freelist.splice(pos,1);}
+var prev=freelist[pos-1];if(prev&&prev.end===block.addr){block=new HeapBlock(prev.addr,prev.size+block.size);freelist.splice(pos-1,1);pos-=1;}
freelist.splice(pos,0,block);}
-function assert_heap_valid(){if(!heap_is_active()){if(heapstart!=0)
+function assert_heap_valid(){if(!heap_is_active()){if(heapstart!==0)
fatal_error("Heap inconsistency: heapstart nonzero");if(usedlist.length>0)
fatal_error("Heap inconsistency: usedlist nonempty");if(freelist.length>0)
fatal_error("Heap inconsistency: usedlist nonempty");return;}
-if(heapstart==0)
-fatal_error("Heap inconsistency: heapstart is zero");var addr=heapstart;var upos=0,fpos=0;while(upos Loading...
-
-This should not be visible
-
-
-
[]
! The following footnote is added to the small print about how to play IF
diff --git a/play-full.html b/play-full.html
index d62a43b..b4c4a9f 100644
--- a/play-full.html
+++ b/play-full.html
@@ -57,11 +57,6 @@
Loading...
-
-This should not be visible
-
-
-