newLISP in a browser

Started by Lutz, January 02, 2014, 01:43:18 PM

Previous topic - Next topic

Lutz

#75
There will be an update based on the latest Emscripten later this year and based on newLISP v10.6.4/5.

HPW

#76
Hello,



when you do the update please add this line below the sample code in the editor:


;(module "qa-bench") ;This call let you benchmark your pc and browser

Then a user could outcomment the line when needed.



Thanks as always for the ongoing development.



Regards
Hans-Peter

HPW

#77
Hello,



I am expermenting with newlisp in a browser from a different web-enviroment.

(neoappbuilder from neosoft http://www.neosoftware.com/neoappbuilder.html">http://www.neosoftware.com/neoappbuilder.html )

I noticed a load-error from the lib.

I noticed that it makes a difference when the file newlisp-js-lib.html.mem is missing in the main path.

So what is that file for and must it be redistributed with the lib?



Edit: When the file is not present or renamed this error is shown in Firefox:

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied newlisp-js-lib.js:866:0



Can you add a more simple sample Html than app.html reduced to the steps to load only the lib?



Regards
Hans-Peter

HPW

#78
Hello,



A smaller Version of app.html.



<!doctype html>
<html lang="en-us">
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>newLISP in a browser example app.</title>
    <style type="text/css" media="screen">
    .emscripten {padding-right: 0; margin-left: auto; margin-right: auto; display: block;}
    .content { margin: 0 5%; max-width: 800px; padding: 6px; background-color: #EEF; border-radius: 5px;}
    .button { color: #000000; background-color: #A0A0D0; border: 0px; border-radius: 5px; }
    </style>
    <script language="Javascript">
      // put your applications java script functions in this area
      // this function executes newLISP code, triggered by a button
      function evallisp() {
            var source = document.getElementById('lispinput').value;
            var result = newlispEvalStr(source);
            var fieldName = document.getElementById('content');
            fieldName.innerHTML = result;
            }
    </script>
  </head>

   <body style="font-family: Helvetica; background-color: #FFF;">
   <div class="content">
    <div class="emscripten" id="status">Downloading...</div>
    <div class="emscripten">
      <progress value="0" max="100" id="progress" hidden=1></progress>
    </div>
    <!-- Put your newLISP function definitions in this textarea. Code
    gets preloaded from here when the page loads. Just for this app it
    also gets loaded from here for display purpose in id='content'. -->

    Lisp code: &nbsp;
    <input type="text" id="lispinput" value="(sys-info)" size="80" style="font-size: 1em; border-radius: 5px;"/>
    <input type="button" class="button" value="eval lisp" style="font-size: 1em;"
            onclick="evallisp();"/>
    &nbsp;
    Result: &nbsp;
    <span id="content"></span> <!-- code is copied from id='code' area into this -->

    <script type='text/javascript'>
<!--
      // ================== careful changing anything below ===================
      // EMSCRIPTEN loading newlisp-js-lib.js showing progress of downloading
      // importing newlispEvaklStr and defining preRun and postRun functions
      var Module = {
        preRun: [],
        postRun: [(function() {
          // import newlispEvalStr from newlisp-js-lib.js library
          newlispEvalStr = Module.cwrap('newlispEvalStr', 'string', ['string']);
          // preload newLISP functions from code textarea id='code'
//          newlispEvalStr(document.getElementById('code').value);
          // preload memoizing table
//          newlispEvalStr('(fibo 150)(fibo 300)(fibo 450)');
        })],
        print: (function() { return function(text) { }; })(),
        printErr: function(text) { },
        setStatus: function(text) {
          if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
          if (text === Module.setStatus.text) return;
          var m = text.match(/([^(]+)((d+(.d+)?)/(d+))/);
          var now = Date.now();
          if (m && now - Date.now() < 30) return; // if progress update, skip if too soon
          var statusElement = document.getElementById('status');
          var progressElement = document.getElementById('progress');
          if (m) {
            text = m[1];
            progressElement.value = parseInt(m[2])*100;
            progressElement.max = parseInt(m[4])*100;
            progressElement.hidden = false;
          } else {
            progressElement.value = null;
            progressElement.max = null;
            progressElement.hidden = true;
          }
          statusElement.innerHTML = text;
        },
        totalDependencies: 0,
        monitorRunDependencies: function(left) {
          this.totalDependencies = Math.max(this.totalDependencies, left);
          Module.setStatus(left ?'Preparing... (' + (this.totalDependencies-left) +
                        '/' + this.totalDependencies + ')' : 'All downloads complete.');
        }
      };
      Module.setStatus('Downloading...');
    // ========================================================================
-->
    </script>
    <script async type="text/javascript" src="newlisp-js-lib.js"></script>
  </div></body>
</html>
<!-- eof -->

Hans-Peter

Lutz

#79
From http://www.newlisp.org/newlisp-js/newlisp-js-10.6.3.zip">http://www.newlisp.org/newlisp-js/newlisp-js-10.6.3.zip you need the whole codemirror/ sub-directory and the files newlisp-js-lib.js (this is newLISP compiled to JavaScript) and newlisp-js-lib.html.mem (some kind of configuration file).



A Happy 2016 to everybody!!!



Ps: code mirror stuff is only necessary for the editor

HPW

#80
Hello Lutz,



Also a happy new year for you and the newlisp community.



Thanks for the Infos.



For now you have to know that the mem-file has to be in the main-path of the Html which has the include-code. In my tests all js-stuff was in a sub-Directory /js and the load fails when mem file is there.



By the way emscripten is now at 1.35.0

http://kripken.github.io/emscripten-site/index.html">http://kripken.github.io/emscripten-site/index.html



Regards
Hans-Peter

HPW

#81
Found an Explanation for the mem-file:

https://github.com/kripken/emscripten/issues/2537">https://github.com/kripken/emscripten/issues/2537


Quote
.....This is by design, .mem files are created in optimized builds to reduce size and improve startup speed. You can disable them  --memory-init-file 0  if you want, but it is not recommended. When they are emitted, they must be alongside the .js file so it can find it.


Regards
Hans-Peter

HPW

#82
Hello,



Currently there are News about WebAsembly and Emsripten.



WebAssembly was build into new Firefox 52.



Emsripten has released 1.37.3 (February 21, 2017).



Talk about both:

https://brendaneich.com/2015/06/from-asm-js-to-webassembly/">https://brendaneich.com/2015/06/from-as ... bassembly/">https://brendaneich.com/2015/06/from-asm-js-to-webassembly/


Quote
How: If you use Emscripten, then wasm support via a command-line flag will at first include and target the prototype polyfill. But as native wasm decoders appear in top engines (see the V8 native prototype decoder), Emscripten will auto-configure for best results. Another prototype: a JS AST compressor (encoder).



These prototypes will evolve and track draft specification changes as WebAssembly matures and receives progressively more developer testing. Other compilers than Emscripten, and other compiler frameworks than LLVM, will join the mix. I expect all engines will support fast native decoders. All these parts are means to the end of a common WebAssembly standard.


Not sure if this can be used for a new version of newlisp in a browser.



Regards
Hans-Peter

Lutz

#83
Probably a newlisp-js-lib.wasm will be substantially bigger than a newlisp-js-lib.js, which might be a problem on devices with less memory. Speedwise we don't know, the current JavaScript machine in FireFox is already pretty good.



For me, the main thing on this topic is, that the interest in 'newLISP in a browser' has been very poor and the getting the development environment right was pretty time consuming, even on Mac OS.



There are also a few things to be done in newlisp.c for the Emscripten interface.



At least at the moment, there are no plans to update to a newer version or to try the WebAsm way. Of course anybody trying to do that themselves is welcome.

Lutz

#84
After reading this: https://hacks.mozilla.org/2017/03/why-webassembly-is-faster-than-asm-js/">https://hacks.mozilla.org/2017/03/why-w ... an-asm-js/">https://hacks.mozilla.org/2017/03/why-webassembly-is-faster-than-asm-js/

I may change my mind. Perhaps WebAssembly is worth a try. Also does 64bit integers.

HPW

#85
Hello Lutz,



Interesting read. Keep us up to date when you have changed your mind.

When it would get widely supported on various platforms, the poor interest may change.

I could imagine to integrate the newlisp-engine for business-rules and data with other web-Standards for GUI and 3D.

Just my 2 Cents. ;-)



Regards
Hans-Peter

xytroxon

#86
Found this. Might be as simple as setting a flag!



http://webassembly.org/docs/faq/">//http://webassembly.org/docs/faq/


QuoteWhat's the story for Emscripten users?



Existing Emscripten users will get the option to build their projects to WebAssembly, by flipping a flag. Initially, Emscripten's asm.js output would be converted to WebAssembly, but eventually Emscripten would use WebAssembly throughout the pipeline. This painless transition is enabled by the high-level goal that WebAssembly integrate well with the Web platform (including allowing synchronous calls into and out of JavaScript) which makes WebAssembly compatible with Emscripten's current asm.js compilation model.


-- xytroxon
\"Many computers can print only capital letters, so we shall not use lowercase letters.\"

-- Let\'s Talk Lisp (c) 1976

fdb

#87
Hi,i'm experimenting a bit with new lisp in a browser and while trying to write a dedicated javascript function to import a textile i ran into the following. I was first trying this with jQuery.Get(Url) which returned "undefined". Eventually I found out that to make it work you'll have to make the request synchronous.So my javascript function now looks like this (i'm not passing the url a parameter):

function getwoordenlijst() {
var xmlHttp = new XMLHttpRequest();
            xmlHttp.open( "GET", "/newlisp/woordenlijst.txt", false ); // false for synchronous request
           xmlHttp.send( null );
           return xmlHttp.responseText;
}

This works ,but of course blocks the browser while importing, and in firefox you get a warning that synchronues requests are depreciated. Anybody knows if there is a way to do this asynchronously ?

fdb

#88
When trying to run/eval a new lisp program in the browser i got below error message:



too many setjmps in a function call, build with a higher value for MAX_SETJMPS



apparently due to the Emscripten toolkit, but what can be done about this? Program works fine in 'normal' new lisp.

fdb

#89
In answer to my own question above, i found out that the latest emscripten doesn't have the limitation on setjmps anymore. So i installed latest emscripten(1.37.14) and compiled new lisp (10.7.3) with it (using makefile_emscripten_lib_utf8) and it works!



Got a warning because there is the -s MAX_SETJMPS=100 setting in the makefile which isn't used/supported anymore with latest emscripten, so better to remove it in future versions.