<commit_before>#include "JSScriptTest.h"

#ifdef HAVE_SPIDERMONKEY
#include "JSScriptEngine.h"
#include "ScriptThreadBase.h"
#include "Object.h"
#include <thread>
#include <stdexcept>


struct MyObject : public metacpp::Object
{
    int xValue;
    metacpp::String stringValue;
    metacpp::Array<double> arrayValue;
    Nullable<float> optValue;
    metacpp::DateTime dateValue;

    MyObject(int x = 0) : xValue(x)
    {
    }

    int x() const { return xValue; }
    void setX(int newX) { xValue = newX; }

    static metacpp::String foo() { return "foo"; }
    static metacpp::String foo(const metacpp::String& arg) { return "foo" + arg; }

    static metacpp::String className() { return MyObject::staticMetaObject()->name(); }

    META_INFO_DECLARE(MyObject)
};

STRUCT_INFO_BEGIN(MyObject)
    FIELD(MyObject, xValue)
    FIELD(MyObject, stringValue)
    FIELD(MyObject, arrayValue)
    FIELD(MyObject, optValue)
    FIELD(MyObject, dateValue)
STRUCT_INFO_END(MyObject)

METHOD_INFO_BEGIN(MyObject)
    METHOD(MyObject, x)
    METHOD(MyObject, setX)
    METHOD(MyObject, className)
    SIGNATURE_METHOD(MyObject, foo, metacpp::String (*)())
    SIGNATURE_METHOD(MyObject, foo, metacpp::String (*)(const metacpp::String&))
METHOD_INFO_END(MyObject)

REFLECTIBLE_FM(MyObject)

META_INFO(MyObject)

void JSScriptTest::SetUp()
{
    m_engine.reset(new metacpp::scripting::js::JSScriptEngine());
    m_engine->registerClass(MyObject::staticMetaObject());
}

void JSScriptTest::TearDown()
{
    m_engine.reset();
}

void JSScriptTest::SetUpTestCase()
{

}

void JSScriptTest::TearDownTestCase()
{

}

TEST_F(JSScriptTest, testCompileSuccess)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("function f() { return 1; }");
    program->compile(ss, "filename");
}

TEST_F(JSScriptTest, testCompileFailure)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("invalid javascript program");
    EXPECT_THROW(program->compile(ss, "filename"), std::exception);
}

TEST_F(JSScriptTest, testSimpleRun)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("function f() { return 1; }");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    thread->run();
}

TEST_F(JSScriptTest, testThrow)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("throw 1;");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    EXPECT_THROW(thread->run(), metacpp::scripting::ScriptRuntimeError);
}

#if MOZJS_MAJOR_VERSION >= 38
TEST_F(JSScriptTest, testTerminate)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("while (1) { }");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    std::exception_ptr ex;
    std::thread th([&]{ try { thread->run();  } catch (...) { ex = std::current_exception(); } });
    while (!thread->running())
        std::this_thread::yield();
    thread->abort(0);
    if (th.joinable())
        th.join();
    ASSERT_TRUE((bool)ex);
    EXPECT_THROW(std::rethrow_exception(ex), metacpp::scripting::TerminationException);
}

TEST_F(JSScriptTest, testMultipleThreads)
{
    // test multiple threads in same script engine running simultenioulsy
    auto program = m_engine->createProgram();
    std::istringstream ss("while (1) { }");
    program->compile(ss, "filename");
    std::vector<std::thread> threads;
    std::vector<metacpp::SharedObjectPointer<metacpp::scripting::ScriptThreadBase>> scriptThreads;
    const size_t numThreads = 10;

    for (size_t i = 0; i < numThreads; ++i)
    {
        auto thread = program->createThread();
        scriptThreads.push_back(thread);
        threads.emplace_back([&]{ try { thread->run();  } catch (...) {  } });
        while (!thread->running())
            std::this_thread::yield();
    }

    for (size_t i = 0; i < numThreads; ++i)
    {
        scriptThreads[i]->abort(0);
        if (threads[i].joinable())
            threads[i].join();
    }
}
<commit_msg>abort thread with timeout<commit_after>#include "JSScriptTest.h"

#ifdef HAVE_SPIDERMONKEY
#include "JSScriptEngine.h"
#include "ScriptThreadBase.h"
#include "Object.h"
#include <thread>
#include <stdexcept>


struct MyObject : public metacpp::Object
{
    int xValue;
    metacpp::String stringValue;
    metacpp::Array<double> arrayValue;
    Nullable<float> optValue;
    metacpp::DateTime dateValue;

    MyObject(int x = 0) : xValue(x)
    {
    }

    int x() const { return xValue; }
    void setX(int newX) { xValue = newX; }

    static metacpp::String foo() { return "foo"; }
    static metacpp::String foo(const metacpp::String& arg) { return "foo" + arg; }

    static metacpp::String className() { return MyObject::staticMetaObject()->name(); }

    META_INFO_DECLARE(MyObject)
};

STRUCT_INFO_BEGIN(MyObject)
    FIELD(MyObject, xValue)
    FIELD(MyObject, stringValue)
    FIELD(MyObject, arrayValue)
    FIELD(MyObject, optValue)
    FIELD(MyObject, dateValue)
STRUCT_INFO_END(MyObject)

METHOD_INFO_BEGIN(MyObject)
    METHOD(MyObject, x)
    METHOD(MyObject, setX)
    METHOD(MyObject, className)
    SIGNATURE_METHOD(MyObject, foo, metacpp::String (*)())
    SIGNATURE_METHOD(MyObject, foo, metacpp::String (*)(const metacpp::String&))
METHOD_INFO_END(MyObject)

REFLECTIBLE_FM(MyObject)

META_INFO(MyObject)

void JSScriptTest::SetUp()
{
    m_engine.reset(new metacpp::scripting::js::JSScriptEngine());
    m_engine->registerClass(MyObject::staticMetaObject());
}

void JSScriptTest::TearDown()
{
    m_engine.reset();
}

void JSScriptTest::SetUpTestCase()
{

}

void JSScriptTest::TearDownTestCase()
{

}

TEST_F(JSScriptTest, testCompileSuccess)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("function f() { return 1; }");
    program->compile(ss, "filename");
}

TEST_F(JSScriptTest, testCompileFailure)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("invalid javascript program");
    EXPECT_THROW(program->compile(ss, "filename"), std::exception);
}

TEST_F(JSScriptTest, testSimpleRun)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("function f() { return 1; }");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    thread->run();
}

TEST_F(JSScriptTest, testThrow)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("throw 1;");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    EXPECT_THROW(thread->run(), metacpp::scripting::ScriptRuntimeError);
}

#if MOZJS_MAJOR_VERSION >= 38
TEST_F(JSScriptTest, testTerminate)
{
    auto program = m_engine->createProgram();
    std::istringstream ss("while (1) { }");
    program->compile(ss, "filename");
    auto thread = program->createThread();
    std::exception_ptr ex;
    std::thread th([&]{ try { thread->run();  } catch (...) { ex = std::current_exception(); } });
    while (!thread->running())
        std::this_thread::yield();
    thread->abort(0);
    if (th.joinable())
        th.join();
    ASSERT_TRUE((bool)ex);
    EXPECT_THROW(std::rethrow_exception(ex), metacpp::scripting::TerminationException);
}

TEST_F(JSScriptTest, testMultipleThreads)
{
    // test multiple threads in same script engine running simultenioulsy
    auto program = m_engine->createProgram();
    std::istringstream ss("while (1) { }");
    program->compile(ss, "filename");
    std::vector<std::thread> threads;
    std::vector<metacpp::SharedObjectPointer<metacpp::scripting::ScriptThreadBase>> scriptThreads;
    const size_t numThreads = 3;

    for (size_t i = 0; i < numThreads; ++i)
    {
        auto thread = program->createThread();
        scriptThreads.push_back(thread);
        threads.emplace_back([&]{ try { thread->run();  } catch (...) {  } });
        while (!thread->running())
            std::this_thread::yield();
    }

    for (size_t i = 0; i < numThreads; ++i)
    {
        scriptThreads[i]->abort(1000);
        if (threads[i].joinable())
            threads[i].join();
    }
}

{'fraction_non_alphanumeric': 0.15411298315163527, 'fraction_numerical': 0.0037165510406342913, 'mean_word_length': 4.283376963350785, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7519415', 'n_tokens_mistral': 2754, 'n_tokens_neox': 2682, 'n_words': 501}