libJerryScript 1.0 Windows/Linux 32/64-bit

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

libJerryScript 1.0 Windows/Linux 32/64-bit

Post by D.J.Peters »

Image
For advanced FreeBASIC users :-)

JerryScript a JavaScript engine for Internet of Things.
Full ECMAScript 5.1 standard compliance.
on github

Why JerryScript ?
I used JavaScript with FreeBASIC at my business more than once in the past.
For this job I compiled SpiderMonkey from Mozilla project for FreeBASIC.
But SpiderMonkey Version 1.8x was the last JavaScript engine with a C interface.
Today SpiderMonkey a part of Firefox has a pure C++ interface only.

latest verion from: Feb 26, 2020 I prever the static version !
download static build: jerryscript-static.zip
download dynamic build: jerryscript.zip
download source code: jerryscript-src.zip

API 1.0 reference
API examples

Joshy
Last edited by D.J.Peters on Oct 12, 2022 18:26, edited 12 times in total.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: JerryScript Windows/Linux 32/64-bit

Post by srvaldez »

hello D.J.Peters
what's the minimum version of windows that this would work on? (would it work on Windows 98)?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

srvaldez wrote:(would it work on Windows 98)?
Why not ?
There isn't any Windows code it's POSIX and C lib.
I can test it only on XP so download and try it out.

But never and I mean NEVER !!!
go online with a running WIN 98 version.

Joshy
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: JerryScript Windows/Linux 32/64-bit

Post by srvaldez »

D.J.Peters wrote: But never and I mean NEVER !!!
go online with a running WIN 98 version.
Joshy
I am not sure what you meant by that, am guessing that it would not be safe?
in my case it would be run offline, no internet connection.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

New version published the most important function "jerryx_handler_register_global" was missing in my first build :-(

By the way if you compile POSIX C99 stuff on Windows and Linux -std=C99 isn't the same as -std=gnu99

struct timezone tz;
if I compile with -std=C99 I get an error "size of timezone is unknow" !
I don't know why but If I use -std=gnu99 the error are gone.

How ever I added test02.bas and test03.bas

Joshy
Last edited by D.J.Peters on Feb 26, 2020 11:14, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

I build a static version of JerryScript also see first post.
No more run-time dependencies :-)

Joshy
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: JerryScript Windows/Linux 32/64-bit

Post by srvaldez »

thank you D.J.Peters :-)
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: JerryScript Windows/Linux 32/64-bit

Post by Iczer »

D.J.Peters
Do you think FB64@JerryScript can compile WanaKana from https://github.com/WaniKani/WanaKana - so I can use use it functions (.toRomaji etc...) in my windows dll?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

@Iczer JerryScript is a full ECMAScript 5.1 JavaScript compiler and Virtual Machine.
It comes with some predefined objects like Date, Math, JSON ...
If the lib you mean used only this standard objects you can run it with JerryScript.
But often JS libraries used objects from WEB Browser DOM, Window, Canvas ...
you have to implement this missing objects self.

You must be an advanced programmer to do this kind of heavy stuff.

Joshy
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: JerryScript Windows/Linux 32/64-bit

Post by Iczer »

Thanks!
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

After two years I found a bug in the jerryscript source code float vs double !

How ever I rebuld all static and dynamic libraries for Windows Linux 32/64-bit and added a more usefull example file: test04.bas

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

from: Openiot-summit-europe-2016-jerryscript.pdf

● JerryScript originally developed from scratch by Samsung !
● Released as open source in June 2015
● JerryScript passed 100% of the test262 conformance test suite in August 2015
● Rewritten compact byte code implementation landed in January 2016
● JerryScript 1.0 released in September 2016
● Extremely portable
● Self-contained
● Small C library
● Can run bare-metal
● Supports the STM32F4, Arduino 101, FRDM-K64F, ESP8266 boards
● OS support: NuttX, Zephyr, mbed OS, RIOT
● Runs on Windows, Linux, macOS as well.
...

"Samsung" that was new for me I worked for Samsung in the past also.

However I edit "jerryscrtipt.bi" (and all tests) replaced all jerry_script datatypes with FreeBASIC natives with one exeption
"jerry_value_t" is a ulong also but must be freed as a result of any jerryscript function !
(this ulong is internal a 32bit 'compressed' javascript VM pointer)
So if you read "jerry_value_t" as a function result remember to free it with jerry_release_value() !

I added more error checking in test04.bas also.

Joshy
file 'test04.bas'

Code: Select all

' #define JERRY_USE_FLOAT
' #define __JERRY_DYNAMIC__ 
#include once "jerryscript.bi"

' test of:
' jerry_eval()
' jerry_create_external_function()
' jerry_set_property()
' jerry_get_property()

sub ErrorValue(value as jerry_value_t, msg as const zstring ptr)
  if jerry_value_has_error_flag(value) then
    print "error: " & iif(msg<>0,*msg,"") & " has error flag !"
    jerry_cleanup()
    beep : sleep :end 1
  end if
end sub

' Add param to 'this.x'
function add_handler cdecl (func_value as const jerry_value_t , _ ' function object
                            this_val   as const jerry_value_t , _ ' this arg 
                            args_p     as const jerry_value_t ptr , _ 'function arguments
                            args_cnt   as const ulong) as jerry_value_t ' number of function arguments

  ' The the 'this_val' is the 'MyObject' from the JS code below

  ' Get 'this.x'
  var prop_name = jerry_create_string("x")
  ErrorValue(prop_name,"jerry_create_string")
  
  var x_val = jerry_get_property (this_val, prop_name)
  ErrorValue(x_val,"jerry_get_property")
  
  ' Convert Jerry API values to floating point number
  var x = jerry_get_number_value (x_val)
  var y = jerry_get_number_value (args_p[0])
  
  ' Add the parameter to 'x'
  var res_create_number = jerry_create_number(x + y)
  ErrorValue(res_create_number,"jerry_create_number")
  
  ' Set the new value of 'this.x' 
  var res_set_property = jerry_set_property(this_val, prop_name, res_create_number)
  ErrorValue(res_set_property,"jerry_set_property")
  ' Free JavaScript values 
  jerry_release_value(res_set_property)    
  jerry_release_value(res_create_number)
  jerry_release_value(x_val)
  jerry_release_value(prop_name)

  return jerry_create_undefined()
end function

'
' main
'
' Initialize engine
jerry_init()

' Register 'print' function from the C extensions
jerryx_handler_register_global ("print", @jerryx_handler_print)

' Create a JS object
var JS_Code=""
#define JS(aline) JS_Code &= aLine & !"\n"
JS("MyObject = {")
JS("  x: 12,")
JS("  foo: function () {")
JS("    return 'value x = ' + this.x;")
JS("  }")
JS("};")

' Evaluate script
var eval_val = jerry_eval(JS_Code, len(JS_Code), false)
ErrorValue(eval_val,"jerry_eval")

' Create a JS function object and wrap into a jerry value
var add_func_obj = jerry_create_external_function(@add_handler)
ErrorValue(add_func_obj,"jerry_create_external_function")

' Set the native function as a property of previously created MyObject
var prop_name = jerry_create_string("add")
ErrorValue(prop_name,"jerry_create_string")
var res_set_property = jerry_set_property(eval_val, prop_name, add_func_obj)
ErrorValue(res_set_property,"jerry_set_property")

' Free JavaScript values
jerry_release_value(res_set_property)
jerry_release_value(prop_name)
jerry_release_value(add_func_obj)
jerry_release_value(eval_val)

' test the native implemented object.add() property
JS_Code = ""
JS("var str = MyObject.foo();")
JS("print(str);")
JS("MyObject.add(30);")
JS("str = MyObject.foo();")
JS("print(str);")

' Evaluate script
eval_val = jerry_eval(JS_Code, len(JS_Code), false)
ErrorValue(eval_val,"jerry_eval")
' Free JavaScript value
jerry_release_value(eval_val)
' Cleanup engine
jerry_cleanup()
print "done ..."
sleep
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: JerryScript Windows/Linux 32/64-bit

Post by srvaldez »

Hi Joshy
I am not much into programming and am not familiar with JavaScript, nevertheless, I thought it would be interesting to find out how JerryScript performs, so I tried to run the n-body program from https://benchmarksgame-team.pages.debia ... ode-6.html
JerryScript doesn't like const or let so after commenting-out those keywords and replacing "const n = +process.argv[2];" with "/*const */n = 50000000/*+process.argv[2]*/;" it compiles OK, that is, there are no more parse errors but there's a run-time error.
so I give up for the time being
btw, it seems to me that JerryScript has similar interaction restrictions as Python DLL, that is, if I write a function in JerryScript, how do I call that function from FB passing and receiving a double?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: JerryScript Windows/Linux 32/64-bit

Post by D.J.Peters »

Do you implemted process.argv and console.log() ?

If not it can't work this way !

Joshy
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: JerryScript Windows/Linux 32/64-bit

Post by srvaldez »

I didn't want to clutter up your thread, I post the code for you to see, I can always clean up this post later.

Code: Select all

#include once "jerryscript.bi"

'
' main
'
jerry_init()

' register C lib printf() as 'print'
jerryx_handler_register_global ("print",@jerryx_handler_print)

var JSSourceCode = ""
#define JS(aline) JSSourceCode &= aLine & !"\n"

JS("/* The Computer Language Benchmarks Game")
JS("   https://salsa.debian.org/benchmarksgame-team/benchmarksgame/")
JS("   contributed by Isaac Gouy")
JS("   modified by Andrey Filatkin */")
JS("")
JS("/*const */PI = Math.PI;")
JS("/*const */SOLAR_MASS = 4 * PI * PI;")
JS("/*const */DAYS_PER_YEAR = 365.24;")
JS("")

JS("function Body(x, y, z, vx, vy, vz, mass) {")
JS("  this.x = x;")
JS("  this.y = y;")
JS("  this.z = z;")
JS("  this.vx = vx;")
JS("  this.vy = vy;")
JS("  this.vz = vz;")
JS("  this.mass = mass;")
JS("}")
JS("")
JS("function Jupiter() {")
JS("  return new Body(")
JS("    4.84143144246472090e+00,")
JS("    -1.16032004402742839e+00,")
JS("    -1.03622044471123109e-01,")
JS("    1.66007664274403694e-03 * DAYS_PER_YEAR,")
JS("    7.69901118419740425e-03 * DAYS_PER_YEAR,")
JS("    -6.90460016972063023e-05 * DAYS_PER_YEAR,")
JS("    9.54791938424326609e-04 * SOLAR_MASS")
JS("  );")
JS("}")
JS("")
JS("function Saturn() {")
JS("  return new Body(")
JS("    8.34336671824457987e+00,")
JS("    4.12479856412430479e+00,")
JS("    -4.03523417114321381e-01,")
JS("    -2.76742510726862411e-03 * DAYS_PER_YEAR,")
JS("    4.99852801234917238e-03 * DAYS_PER_YEAR,")
JS("    2.30417297573763929e-05 * DAYS_PER_YEAR,")
JS("    2.85885980666130812e-04 * SOLAR_MASS")
JS("  );")
JS("}")
JS("")
JS("function Uranus() {")
JS("  return new Body(")
JS("    1.28943695621391310e+01,")
JS("    -1.51111514016986312e+01,")
JS("    -2.23307578892655734e-01,")
JS("    2.96460137564761618e-03 * DAYS_PER_YEAR,")
JS("    2.37847173959480950e-03 * DAYS_PER_YEAR,")
JS("    -2.96589568540237556e-05 * DAYS_PER_YEAR,")
JS("    4.36624404335156298e-05 * SOLAR_MASS")
JS("  );")
JS("}")
JS("")
JS("function Neptune() {")
JS("  return new Body(")
JS("    1.53796971148509165e+01,")
JS("    -2.59193146099879641e+01,")
JS("    1.79258772950371181e-01,")
JS("    2.68067772490389322e-03 * DAYS_PER_YEAR,")
JS("    1.62824170038242295e-03 * DAYS_PER_YEAR,")
JS("    -9.51592254519715870e-05 * DAYS_PER_YEAR,")
JS("    5.15138902046611451e-05 * SOLAR_MASS")
JS("  );")
JS("}")
JS("")
JS("function Sun() {")
JS("  return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);")
JS("}")
JS("")

JS("/*const */bodies = Array(Sun(), Jupiter(), Saturn(), Uranus(), Neptune());")
JS("")

JS("function offsetMomentum() {")
JS("  /*let */var px = 0;")
JS("  /*let */var py = 0;")
JS("  /*let */var pz = 0;")
JS("  /*const */var size = bodies.length;")
JS("  for (/*let */var i = 0; i < size; i++) {")
JS("    /*const */var body = bodies[i];")
JS("    /*const */var mass = body.mass;")
JS("    px += body.vx * mass;")
JS("    py += body.vy * mass;")
JS("    pz += body.vz * mass;")
JS("  }")
JS("")
JS("  /*const */var body = bodies[0];")
JS("  body.vx = -px / SOLAR_MASS;")
JS("  body.vy = -py / SOLAR_MASS;")
JS("  body.vz = -pz / SOLAR_MASS;")
JS("}")
JS("")

JS("function advance(dt) {")
JS("  /*const */size = bodies.length;")
JS("")
JS("  for (/*let */i = 0; i < size; i++) {")
JS("    /*const */bodyi = bodies[i];")
JS("    /*let */vxi = bodyi.vx;")
JS("    /*let */vyi = bodyi.vy;")
JS("    /*let */vzi = bodyi.vz;")
JS("    for (/*let */j = i + 1; j < size; j++) {")
JS("      /*const */bodyj = bodies[j];")
JS("      /*const */dx = bodyi.x - bodyj.x;")
JS("      /*const */dy = bodyi.y - bodyj.y;")
JS("      /*const */dz = bodyi.z - bodyj.z;")
JS("")
JS("      /*const */d2 = dx * dx + dy * dy + dz * dz;")
JS("      /*const */mag = dt / (d2 * Math.sqrt(d2));")
JS("")
JS("      /*const */massj = bodyj.mass;")
JS("      vxi -= dx * massj * mag;")
JS("      vyi -= dy * massj * mag;")
JS("      vzi -= dz * massj * mag;")
JS("")
JS("      /*const */massi = bodyi.mass;")
JS("      bodyj.vx += dx * massi * mag;")
JS("      bodyj.vy += dy * massi * mag;")
JS("      bodyj.vz += dz * massi * mag;")
JS("    }")
JS("    bodyi.vx = vxi;")
JS("    bodyi.vy = vyi;")
JS("    bodyi.vz = vzi;")
JS("  }")
JS("")
JS("  for (/*let */i = 0; i < size; i++) {")
JS("    /*const */body = bodies[i];")
JS("    body.x += dt * body.vx;")
JS("    body.y += dt * body.vy;")
JS("    body.z += dt * body.vz;")
JS("  }")
JS("}")
JS("")

JS("function energy() {")
JS("  /*let */e = 0;")
JS("  /*const */size = bodies.length;")
JS("")
JS("  for (/*let */i = 0; i < size; i++) {")
JS("    /*const */bodyi = bodies[i];")
JS("")
JS("    e += 0.5 * bodyi.mass * ( bodyi.vx * bodyi.vx + bodyi.vy * bodyi.vy + bodyi.vz * bodyi.vz );")
JS("")
JS("    for (/*let */j = i + 1; j < size; j++) {")
JS("      /*const */bodyj = bodies[j];")
JS("      /*const */dx = bodyi.x - bodyj.x;")
JS("      /*const */dy = bodyi.y - bodyj.y;")
JS("      /*const */dz = bodyi.z - bodyj.z;")
JS("")
JS("      /*const */distance = Math.sqrt(dx * dx + dy * dy + dz * dz);")
JS("      e -= (bodyi.mass * bodyj.mass) / distance;")
JS("    }")
JS("  }")
JS("  return e;")
JS("}")
JS("")

JS("/*const */n = 50000000/*+process.argv[2]*/;")
JS("")
JS("offsetMomentum();")
JS("")
JS("console.log(energy().toFixed(9));")
JS("for (/*let */i = 0; i < n; i++) {")
JS("  advance(0.01);")
JS("}")
JS("console.log(energy().toFixed(9));")

' 'false' means no 'use_strict' mode 
' i = 2*2 and i.toString is allowed
var RuntimeCode = jerry_parse(JSSourceCode, len(JSSourceCode), false)
' "true' means 'use_strict'
' i.toString() produce an runtime error becourse 'var' i = 2*2; are missing !
'var RuntimeCode = jerry_parse(JSSourceCode, len(JSSourceCode), true)
var bErrorFlag = jerry_value_has_error_flag(RuntimeCode)
if bErrorFlag = false then
  ' Execute the parsed source code in the Global scope
  var ret_value = jerry_run(RuntimeCode)
  bErrorFlag = jerry_value_has_error_flag(ret_value)
  if bErrorFlag = true then
    beep : print "jery_run has_error_flag !"
  end if  
  jerry_release_value(ret_value)
else
  beep : print "jerry_parse has_error_flag !"
end if
jerry_release_value(RuntimeCode)
jerry_cleanup()
sleep
btw, if I comment-out the end of the JS code, like this, it still gives a runtime error

Code: Select all

'JS("/*const */n = 50000000/*+process.argv[2]*/;")
'JS("")
JS("offsetMomentum();")
'JS("")
'JS("console.log(energy().toFixed(9));")
'JS("for (/*let */i = 0; i < n; i++) {")
'JS("  advance(0.01);")
'JS("}")
'JS("console.log(energy().toFixed(9));")
Post Reply