emojicode / emojicode

๐Ÿ˜€๐Ÿ˜œ๐Ÿ”‚ Worldโ€™s only programming language thatโ€™s bursting with emojis

Home Page:https://emojicode.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem writing a native HTTP server package

MagnificentPako opened this issue ยท comments

commented

Because my native implementation wasn't yielding the results and consistency I need for my next project I tried to write a small package adding bindings for a C++ library. For some reason, it seems to mess up the arguments (namely host and port) leading to ``hostbeing completely empty andport` being a random number.

Do you have any idea what I'm doing wrong?

https://github.com/MagnificentPako/emojicode/blob/emojicode-0.5/DefaultPackages/http/http.cpp

The code I tested it with is here:
https://github.com/MagnificentPako/emojicode/blob/emojicode-0.5/tests/http/simple.emojic

Here's what Valgrind told me:
https://gist.github.com/MagnificentPako/c18e5b8360e5392eeed5a5194828abe4

commented
    ๐Ÿˆ ๐Ÿ†• host๐Ÿ”ก port๐Ÿš‚ ๐Ÿ“ป 1
    ๐Ÿ– ๐Ÿƒ ๐Ÿ“ป 2

You declared the initializer to take parameters, not serverRun. By accessing variable(0) etc. you're causing undefined behavior, thus a "random number".

Then you seem not to be initializing the Server object. Unless the Server instance does not need to be initialized you should do something like

new (thread->thisObject()->val<Server>()) Server;

in the initializer.

commented

Ohh, thanks for spotting that! I was searching for the problem everywhere but my header file.

However it seems like initializing the Server in the initializer isn't enough; I'm still getting this
https://gist.github.com/MagnificentPako/e2750c6e0d19013b83f78eca6e5fbba8

Guess I'll actually have to learn C++ now ๐Ÿ˜…

commented

I canโ€™t really try it myself right now, but some suggestions:

  • Try *thread->thisObject()->val<Server>() = Server(); instead of the new...
  • Check that prepareClass is actually called for your class.
commented

Thanks! I'm not entirely sure what I changed but now it seems to work!

This leads me to another problem though: I'm trying to use callables.
Do you have any idea how I can make the callable output to str, then use the string in C++?

void serverRun(Emojicode::Thread *thread) {
    const char *host = Emojicode::stringToCString(thread->variable(0).object);
    Emojicode::EmojicodeInteger port = thread->variable(1).raw;
    auto callable = thread->variable(2).object;
    std::cout << host << "\n";
    std::cout << port << "\n";
    thread->thisObject()->val<Server>()->get(R"(.+)", [&](const Request& req, Response& res) {
        Emojicode::Object* str = Emojicode::stringPool[0];
        auto a = Emojicode::stringFromChar(req.path.c_str());
        auto c = Emojicode::Value(a);
        Emojicode::executeCallableExtern(callable,
            &c,
            sizeof(Emojicode::stringFromChar(req.path.c_str())),
            thread,
            str->val<Emojicode::String>()); // <--- THIS
        res.set_content(Emojicode::stringToCString(str), "text/plain");
    });
    thread->thisObject()->val<Server>()->listen(host, port);
}
commented
auto a = Emojicode::stringFromChar(req.path.c_str());
auto c = Emojicode::Value(a);
Value str;
Emojicode::executeCallableExtern(callable,
            &c,
            sizeof(Emojicode::stringFromChar(req.path.c_str())),
            thread,
            &str); // <--- THIS
res.set_content(Emojicode::stringToCString(str.object), "text/plain");

should work.

That said, have you read this?

stringFromChar as well as stringToCString are potentially garbage collector invoking. stringFromChar allocates memory, if this allocation causes a GC cycle, callable is no longer a valid pointer. You're code is relying on undefined behavior as of now.

Registering callables as callback with this get method could get really complicated, as you somehow need to store the callable in a way that you can bring to the garbage collectors attention. One possible solution that pops into my head now: Let the objects of your class not store a Server directly, but a wrapper structure (e.g. ServerWrapper). Make ServerWrapper also store an array of callables and capture the index at which the callable was stored in the closure passed to get. This list can be marked by the garbage collector by providing a custom mark function.

One last thing, you should probably deinitialize the Server instance before it is deallocated: http://www.emojicode.org/docs/guides/packageAPI.html#deinitialization

(I know it's complicated, but everything is getting better when 0.6 is released one day...)