Skip to main content

News

Topic: Sphere 5.5.2 (miniSphere) (Read 416368 times) previous topic - next topic

0 Members and 3 Guests are viewing this topic.
  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1890
I've found another bug:
If you create an object with a function but omit a parameter it needs miniSphere hard crashes if you try and access that field later
e.g.:
Code: [Select]
function CoolObject(a, b, c)
{
  this.a = a;
  this.b = b;
  this.c = c;
}

var fun = new CoolObject(5, 6);

throw fun.c;//results in a hard crash

Obviously this is bad code that would always cause problems - but ideally it would trigger miniSPhere's error handling to make it easier to debug OR it should give you a "undefined" value rather than

Code: [Select]
Crashed Thread:        9

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Thread 9 Crashed:
0   libsystem_kernel.dylib        0x00007fff9a1bbd42 __pthread_kill + 10
1   libsystem_pthread.dylib       0x00007fff9a2a9457 pthread_kill + 90
2   libsystem_c.dylib             0x00007fff9a121420 abort + 129
3   spheredev.miniSphere          0x0000000106bb2bfc duk_default_fatal_handler + 9 (duk_api_heap.c:68)
4   spheredev.miniSphere          0x0000000106bbc027 duk_fatal_raw + 15 (duk_api_stack.c:5428)
5   spheredev.miniSphere          0x0000000106bbc00e duk_err_longjmp + 102 (duk_error_longjmp.c:102)
6   spheredev.miniSphere          0x0000000106bbdd23 duk_err_create_and_throw + 300 (duk_api_bytecode.c:48)
7   spheredev.miniSphere          0x0000000106bb0e96 duk_err_handle_error_fmt + 187 (duk_api_stack.c:5801)
8   spheredev.miniSphere          0x0000000106bb45ed duk_hobject_getprop + 2391 (duk_api_stack.c:3886)
9   spheredev.miniSphere          0x0000000106bb3c7e duk_get_prop + 45 (duk_api_object.c:30)
10  spheredev.miniSphere          0x0000000106bf742a _al_mangled_main + 2922 (main.c:316)
11  spheredev.miniSphere          0x0000000106d7b8da +[AllegroAppDelegate app_main:] + 23
12  com.apple.Foundation          0x00007fff863308ad __NSThread__start__ + 1243
13  libsystem_pthread.dylib       0x00007fff9a2a693b _pthread_body + 180
14  libsystem_pthread.dylib       0x00007fff9a2a6887 _pthread_start + 286
15  libsystem_pthread.dylib       0x00007fff9a2a608d thread_start + 13
  • Last Edit: August 19, 2017, 09:01:57 am by Rhuan

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1891
And another one I've seen a few times but I don't think I've mentioned before.

If I attempt to access a negative indexed property of an array, e.g.
Code: [Select]
var arr = [0,1,2,5];
throw arr[-1];

I get a bizarrely distorted error handling screen, see attachment.

EDIT: trying to get ~1000 sprites to collide with each other and hitting error after error :(
  • Last Edit: August 19, 2017, 09:33:48 am by Rhuan

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1892
The root cause of the segfault is:

Code: [Select]
throw undefined;  // CRASH! *BOOM* :pig_nose: *MUNCH*

You always find the weirdest crashes.  It's not the access itself that crashes it, it's that you're throwing undefined instead of an exception object and I apparently didn't account for that possibility.  If I change your first example instead to:

Code: [Select]
function CoolObject(a, b, c)
{
  this.a = a;
  this.b = b;
  this.c = c;
}

var fun = new CoolObject(5, 6);

SSj.log(fun.c);

Then it works fine.

As for the distorted error screen, did you happen to have a transformation matrix active at the time?  If so, I fixed that in 4.8.3.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1893
Thanks for looking at these.

A couple more notes, for the first issue, I get the same effect (that is a segfault) if I do this:
Code: [Select]
function CoolObject(a, b, c)
{
  this.a = a;
  this.b = b;
  this.c = c;
}

var fun = new CoolObject(5, 6);
var bob = [];
bob[fun.c];
i.e. I try and use that undefined property as a reference.


For the second issue, I don't believe there was a screen transformation set, also I can't reproduce it now, so I'll revert to you next time I see it.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1894
It also crashes if you throw null;.  I tested throw with a bunch of stuff originally--numbers, objects, strings, etc.  It works for everything except null and undefined, because the uncaught error handler tries to read a filename and line number from the thrown value and those are the only two values that are not object coercible.  So the property read throws ANOTHER error, which causes Duktape to panic and call abort().  I'm fixing it as we speak.

I couldn't reproduce any crash with bob[fun.c]; though.  I pasted that at the top of my script and nothing happened, it just proceeded as usual.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1895
I couldn't reproduce any crash with bob[fun.c]; though.  I pasted that at the top of my script and nothing happened, it just proceeded as usual.
That's weird, I also now can't reproduce the error so it must have been something else, unfortunately my first segfault was with no "throw"s anywhere, I added throws to try and catch it, so there definitely is another error but now I don't know what it actually was :(

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1896
https://github.com/fatcerberus/minisphere/issues/153

I've spent some time staring at JS engines recently, looking at compatibility, performance, and usability.

In addition to Spidermonkey (SM) and V8 I've also looked at Apple's Javascriptcore (JSC_ and I've taken a quick look at Microsoft's Chakracore (CC).

As far as I can see none of them run TypeScript natively (suggestion from your issue log above) that is unless I'm missing something the TypeScript benchmark some of them show is the speed of compiling typescript with the javascript typescript compiler.

Performance
Different ones are better for different things. V8 seems to get the best results out of javascript that's written for readability not speed, whilst javascriptcore gets the worst results from such code. Spidermonkey comes out in the middle. flipping to code that has been written for speed and uses optimisation tricks javascriptcore jumps to the lead, outperforming V8 and spidermonkey by significant margins in some cases. Microsoft's ChakraCore seems to generally get the worst results on most benchmarks though there are a few outlying positives. I note that even bad results on the benchmarks = 10 * faster than miniSphere's current performance; the good results on the benchmarks are 70 * faster or more.

I note that from the tests I did it looks like far more effort has gone into optimising V8 and JSC performance than CC and SM, presumably as JSC is now used in a lot of IOS games and V* is used in node.js and probably android apps.

Compatibility with ES6
They're all pretty good JSC gets 99%, SM and v8 both get 97% and CC gets 96. http://kangax.github.io/compat-table/es6/

Garbage Collection
CC: uses parallel processing to have garbage collection always happening rather than pausing for it
V8: incremental garbage collection but stops code execution when doing it
SM: no idea what it does - only documentation on GC in SM I can find says at the top that it (the documentation) is out of date and wrong
JSC: uses parallel processing to avoid stopping main thread for GC


APIs:
JSC and CC both appear to have pure C apis available. (JSC also has an objective C api but it's a wrapper around the C api and can be safely ignored).
V8 and Spidermonkey both have C++ apis as the only option.

Documentation:
V8: good documentation
CC: good documentation
SM: mixed documentation - wiki with loads of out of date content, though the key information for how to use it is there
JSC: mixed documentation - lots of focus on the objective C wrapper api rather than C, also most articles assume that any developer using it is targeting IOS

Licenses:
V8: BSD
CC: MIT
SM: MPL2
JSC: LGPL
All of these seem ok to me as long as the source is kept separate from the miniSphere source.

Conclusion
Considering the potential to avoid needing a C wrapper around C++ I think that CC or JSC would be nicer options than V8 or SM, then based on benchmark performance I think that JSC just wins.

Anyway comparing these was a nice bit of fun, now I need to finish my collision detection...

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1897
Documentation:
V8: good documentation
CC: good documentation
SM: mixed documentation - wiki with loads of out of date content, though the key information for how to use it is there
JSC: mixed documentation - lots of focus on the objective C wrapper api rather than C, also most articles assume that any developer using it is targeting IOS

That's what I found with SM, too, the wiki is not very well maintained at all.  For example, the release notes for SM 45, emphasis is mine:
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Releases/45

Quote
This page is not complete.

These release notes are an incomplete draft and will remain so well after SpiderMonkey 45 is released.

[...]

-- Apr 14, 2016

That, um, doesn't exactly inspire confidence.  Not to mention the fact that SpiderMonkey 52 is still listed as a "future release" and doesn't even have a wiki page yet--despite the fact that Firefox is already up to v55.  Out-of-date documentation is worse than no documentation at all.  I honestly get the sense that Mozilla really doesn't care about embedders anymore.\

It *does* surprise me that you say V8 has good documentation, since I think I remember FJ saying their documentation was very poor.  Even so, from what I've heard people say, V8's garbage collector is apparently very lazy and almost never runs at all, which isn't ideal when you have native resources tied to the lifetime of a JS object.  This is one nice thing about Duktape's GC: it's refcounted backed by a stop-the-world mark-and-sweep collector, so barring a circular reference, things tend to get finalized the minute they go out of scope, which is nice.

The one that interests me most is ChakraCore.  MS's documentation has always been second-to-none, and it's MIT-licensed which would be a great fit for miniSphere.  I can navigate around the LGPL, but I'd prefer not to have to deal with it.  And I don't really want to have to deal with spotty documentation if I can avoid it, either.

Re: TypeScript: I don't really expect any JS engine to support it natively, that's not what I meant by the TypeScript comment.  It's just that, right now I'm using TS as a gloried ES6 transpiler because Duktape (remember, Cell uses Duktape too) is way too slow to use the full type system.  I tried it, it was ridiculously slow.  And type-checking requires all sources to be compiled together, which made it even worse.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1898
I'm experimenting with ChakraCore, the pure C API is really nice and doesn't seem overly bloated.  I'm trying to see if I can get it to run some code passed in as a string and return the value it returns to C.  Then I can see about getting some test bindings going.

A big mistake I made with duktape was, because it was so easy to get a functioning engine off the ground with, I just used it directly without wrapping it with any kind of abstraction (especially since the stack-based API makes a generic abstraction difficult).  Not an exaggeration, I had my Spectacles battle engine running within weeks of starting development:
http://forums.spheredev.org/index.php/topic,1215.msg5428.html#msg5428

One thing that's inconvenient that I also had to deal with when I experimented with V8 is that the API expects strings to be widechar (`wchar_t`), but miniSphere uses UTF-8 internally.  Luckily there's a function to create string values from a UTF-8 string which I can get the `wchar_t*` for.  So it's an extra step but isn't too much of a hassle in practice, especially since I can abstract around it.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1899
I've had a quick read and it seems relatively simple to work with, I look forward to seeing how you get on, I'd love to have my sprite update code and collision code run with a JIT - performance is ok under duktape but it's a struggle to keep a steady 60 FPS whilst handling 100+ entities now I've added collisions.

I'd still also like to try a JSC version of sphere at some point, maybe when you're done with CC I'll see if I can swap it to JSC in a test build; from reading both APIs they seem functionally quite similar - same sorts of calls to make just different names for them, tbh I don't know which will actually be better - CC has far less test results available for it as it's so much newer and the only browser that uses it is windows only.

A couple of notes on my points above:
V8 documentation: a lot of content on their wiki has been written this year, so it may have been a lot worse before.

General state of the different engines: V8, JSC and CC have all been undergoing rapid development over the last year for different reasons with much effort spent optimising each and even replacing core elements of their architecture (e.g. JSC got a whole new GC system in January, CC only got non-windows support a year ago and non-windows JIT support in October)
SM on the other hand seems to be slowly dying unless I'm missing something.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1900
CC apparently supports ES6 modules (.mjs) natively which is really nice to see:
https://github.com/Microsoft/ChakraCore/wiki/Roadmap

ES6 module syntax and semantics are much more elegant than CommonJS (which let's face it, CJS is a hack).  Plus they run in permanent strict-mode which helps catch bugs.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1901
CC on the whole does look very nice my only concerns with it were that:
a) it's a bit new and less thoroughly tested than the alternatives
b) it's unlikely to be the fastest (though they're working on that)
c) I couldn't benchmark it myself without building some as microsoft edge can't run on a mac
d) Any new low level features are added to windows first and take time to be ported to other platforms

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1902
One thing that's going to make this more challenging is, regardless of which JS engine I pick, exception handling differs from Duktape.  In Duktape, if an exception is thrown, it propogates via longjmp() all the way to the nearest catch or duk_pcall(), even cutting through C functions in the process.  CC, SM and probably V8 will throw an exception through JS code, but stop at a JS-C boundary where the error must be detected and handled manually, e.g. by rethrowing and returning from the C function.

Essentially in Duktape, any C code executed during script processing is just an extension of the normal JS environment.  This is very convenient, and there are a few spots in the miniSphere codebase that rely being able to immediately interrupt a C callback with a JS exception from any stack depth, e.g. argument validation:
https://github.com/fatcerberus/minisphere/blob/v4.8.3/src/minisphere/utility.c#L287

So those would need to be refactored, unless I could come up with some way to emulate it.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.8.3
Reply #1903
Could you simulate this error handling by doing the following

1. within the function that wants to generate an error the JsCreateError(message, out_error) function
2. an early return (to send sphere back into the JS)
3. wrap all JS execution commands in an error catching function that displays the message

PS I've built ChakraCore on MacOs and started doing some speed/functionality tests - it's close to parity with V8 and JSC for performance which is very nice to see, it seems to have a slightly higher threshold for triggering it's optimising JIT than JSC has which means you have to get to higher levels of recursion before its top speeds come out but those top speeds are pretty crazy.
  • Last Edit: August 21, 2017, 01:40:52 pm by Rhuan

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: miniSphere 4.8.3
Reply #1904
So far I've written a bunch of functions to abstract around the JS engine and fit in with the style of the rest of the codebase:
https://github.com/fatcerberus/minisphere/blob/chakra-js/src/shared/ecmunch.c

I've done some testing with it and I can successfully set object properties, create functions, eval code and get the result back, etc.  I haven't figured out how to get it to load a module yet, though.
Sphere 5.5.2 - miniSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub