Idea: New scriptengine replacement "XetaScript"

Discussion in 'Development General' started by ArchZombie, Mar 11, 2014.

  1. ArchZombie

    ArchZombie Member

    Joined:
    Aug 1, 2012
    Messages:
    65
    Likes Received:
    0
    PO Trainer Name:
    ArchZombie0x
    Looking for feedback on the idea of adding a new (optional) script engine for PO, using the engine I'm working on called "XetaScript" (or something else, not decided yet.) This would be a compile option.

    It'll require C++11, and unless someone helps me port the new engine I'm working on, Linux.

    This new language isn't nearly done, but I already have some of the runtime implemented.

    Some of the weird stuff it will do includes dynamic class generation (which already works to some degree at least, although I'm sure it's painfully slow.) for regular objects.

    Right now you can't run any code (you can only call the functions in the runtime.)

    http://pastebin.com/gSXSNZ6T

    Comments on the idea?

    What I have so far is here: https://github.com/ArchZombie/xetascript
     
    Last edited by a moderator: Mar 27, 2014
  2. TheUnknownOne

    TheUnknownOne Member

    Joined:
    Mar 28, 2011
    Messages:
    988
    Likes Received:
    3
    Do you have any idea what the interpreted language will look like? Will there be a complication process (to bytecode)? How extensive will the standard library be?
     
  3. ArchZombie

    ArchZombie Member

    Joined:
    Aug 1, 2012
    Messages:
    65
    Likes Received:
    0
    PO Trainer Name:
    ArchZombie0x
    There may be a bytecode, but there wouldn't be much point, since runtime templating (possibly jit) compilation would be required based on my design so far.

    It will probably have multiple "high level" formats, and one "low level" format in appearance.

    The function call interface should also be much simpler when calling functions from C++ code, you can call them as std::functions or anything else. :)

    Code (text):
    1.  
    2.   engine e;
    3.   zsys::parser<> pars("-> %aio int16, %q string, %te int32");
    4.   args_signatures sig;
    5.   e.parse_args(pars, sig);
    6.   xev_function f(&e, sig);
    7.   f(98, std::string("testing"), 83);
    8.   f(48, "hello world!", "eee"); // errors here, since we are assigning a const char * to %te int32 :)
    9.  
    Code (text):
    1.  
    2. terminate called after throwing an instance of 'std::runtime_error'
    3.   what():  translate_metacast: can't convert property of type char const* to type int in assignment.
    4. Aborted
    The following features will likely be supported:

    • Runtime generation of new classes and datatypes.
    • JIT compilation via LLVM,
    • Logical function merging optimizations. (e.g., doing array.findfirst('a') and array.findfirst('b') could be merged into one function that returns both.)
    • "Schrödinger Scheduling" optimizations, this is something evil I thought of. The idea is to be able to execute the "true" and "false" paths of an if/else statement at the same time, as "read memory only" threads, before the boolean condition is known, then discard the incorrect thread and set the correct one to "read/write".
    • Reactive programming.
    • Runtime code and template generation.
    • Runtime binding of templates to arbitrary types.
    • Automatic multithreading.

    Code (text):
    1.  
    2. #include <cxxabi.h>
    3. #include <assert.h>
    4. #include "xs.hh"
    5. #include "dynobject.hh"
    6. #include "engine.hh"
    7. #include "function.h"
    8. #include "../zsysutils/time.hh"
    9.  
    10. using namespace xetascript;
    11.  
    12. static void f2(volatile int16_t i, volatile std::string s, volatile int32_t i2)
    13. {
    14.   asm("");
    15. };
    16.  
    17. int main (void)
    18. {
    19.  
    20.   engine e;
    21.   zsys::parser<> pars("-> %aio int16, %q string, %te int32");
    22.   args_signatures sig;
    23.   e.parse_args(pars, sig);
    24.   xev_function f(&e, sig);
    25.   /*f(98, std::string("testing"), 83);
    26.   f(48, "hello world!", "eee"); // errors here, since we are assigning a const char * to %te int32 :)
    27. */
    28.   zsys::time t = zsys::time::now();
    29.  
    30.   for (int i = 0; i < 200000; i++)
    31.     {
    32.       f(1, std::string("test"), 2);
    33.     };
    34.  
    35.   zsys::time took = zsys::time::now() - t;
    36.  
    37.   fprintf(stderr, "[benchmark] XetaScript calls from C++: %lu.%.9lu seconds.\n", took.secs(), took.nsecs());
    38.  
    39.   t = zsys::time::now();
    40.  
    41.   for (int i = 0; i < 200000; i++)
    42.     {
    43.       f2(1, std::string("test"), 2);
    44.     };
    45.  
    46.   zsys::time took2 = zsys::time::now() - t;
    47.  
    48.   fprintf(stderr, "[benchmark] C++ calls from C++: %lu.%.9lu seconds.\n", took2.secs(), took2.nsecs());
    49.  
    50.   double d(1), d2(1);
    51.  
    52.  
    53.   // Since on my laptop seconds always returns 0, skipping the seconds code...
    54.   assert(took.secs() == 0 && took2.secs() == 0);
    55.   d *= took2.nsecs();
    56.   d /= took.nsecs();  
    57.  
    58.   d2 /= took2.nsecs();
    59.   d2 *= took.nsecs();
    60.  
    61.   //d *= 100;
    62.  
    63.   fprintf(stderr, "[benchmark] Was %lf times as fast, %lf times slower, than C++.\n", d, d2);
    64.  
    65.   return 0;
    66. };
    67.  
    68.  
    Code (text):
    1.  
    2. g++ -g -O4 -std=gnu++11 -pthread ../zsysutils/*.o ./*.cc -Wall -Wfatal-errors -g && ./a.out
    3. [benchmark] XetaScript calls from C++: 0.272183470 seconds.
    4. [benchmark] C++ calls from C++: 0.009985378 seconds.
    5. [benchmark] Was 0.036686 times as fast, 27.258204 times slower, than C++.
    6.  
    That's not bad, but I'll definitely need to get rid of the std::vectors used to manage the call stack, haha.

    I wasn't being very smart... there's a lot of overhead involved with... type casting... The C++ version optimized the type coversions at the call site, instead of in the function body. .-.

    In addition to other optimizations, I now have it down to:

    Code (text):
    1. [benchmark] XetaScript calls from C++: 16.869461138 seconds.
    2. [benchmark] C++ calls from C++: 1.092881945 seconds.
    3. [benchmark] Was 0.064785 times as fast, 15.435758 times slower, than C++.
    4.  
    On my PC after functor generators were added:

    Code (text):
    1.  
    2. [benchmark] 10000000 XetaScript calls from C++: 15.235540869 seconds.
    3. [benchmark] 10000000 C++ calls from C++: 1.234443197 seconds.
    4. [benchmark] Was 0.081024 times as fast, 12.342035 times slower, than C++.
    5.  
    Still wondering if there's any interest in this...
     
    Last edited by a moderator: Mar 27, 2014