Skip to content

Commit

Permalink
WIP. Port to QuickJS-NG
Browse files Browse the repository at this point in the history
Change-Id: Ia6f7b2113743b832cff6b2b81e5b3027d0e09fda
  • Loading branch information
ABBAPOH committed Jan 26, 2025
1 parent 471650a commit 0293ef9
Show file tree
Hide file tree
Showing 29 changed files with 16,405 additions and 15,192 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_C_STANDARD 11)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

Expand Down
1 change: 1 addition & 0 deletions qbs-resources/imports/QbsProduct.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Product {
return res;
}
cpp.cxxLanguageVersion: "c++20"
cpp.cLanguageVersion: qbs.toolchain.contains("msvc") ? "c11" : "gnu11"
cpp.enableExceptions: true
cpp.rpaths: qbsbuildconfig.libRPaths
cpp.minimumMacosVersion: "11.0"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/corelib/buildgraph/rulecommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void AbstractCommand::applyCommandProperties(JSContext *ctx, const JSValue *scri
if (m_predefinedProperties.contains(name))
return;
// TODO: Use script class for command objects, don't allow setting random properties
if (!isSimpleValue(desc.value)) {
if (!JS_IsSimpleValue(ctx, desc.value)) {
throw ErrorInfo(Tr::tr("Property '%1' has a type unsuitable for storing in a command "
"object.").arg(name), m_codeLocation);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/corelib/buildgraph/rulesapplicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ class ArtifactBindingsExtractor

const JSValue value = desc.value;
if (JS_IsObject(value) && !JS_IsArray(m_ctx, value) && !JS_IsError(m_ctx, value)
&& !JS_IsRegExp(m_ctx, value)) {
&& !JS_IsRegExp(value)) {
QString newModuleName;
if (!moduleName.isEmpty())
newModuleName.append(moduleName + QLatin1Char('.'));
Expand Down
25 changes: 10 additions & 15 deletions src/lib/corelib/language/scriptengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,9 @@ void ScriptEngine::checkContext(const QString &operation,
QBS_ASSERT(false, continue);
break;
}
if (!m_evalPositions.empty()) {
const JSValue exVal = JS_NewObject(m_context);
const auto &[file, line] = m_evalPositions.top();
build_backtrace(m_context, exVal, file.toUtf8().constData(), line, 0);
const JsException ex(m_context, exVal, {});
m_logger.printWarning(ErrorInfo(warning, ex.stackTrace()));
} else {
m_logger.printWarning(ErrorInfo(warning));
}
const JSValue exVal = JS_NewError(m_context);
const JsException ex(m_context, exVal, JS_GetBacktrace(m_context), {});
m_logger.printWarning(ErrorInfo(warning, ex.stackTrace()));
return;
}
}
Expand Down Expand Up @@ -582,7 +576,7 @@ JSValue ScriptEngine::asJsValue(const QVariantMap &m, quintptr id, bool frozen)
for (auto it = m.begin(); it != m.end(); ++it)
setJsProperty(m_context, obj, it.key(), asJsValue(it.value(), 0, frozen));
if (frozen)
JS_ObjectSeal(m_context, obj, true);
JS_FreezeObject(m_context, obj);
if (!id)
return obj;
m_jsValueCache[id] = obj;
Expand All @@ -606,7 +600,7 @@ JSValue ScriptEngine::asJsValue(const QVariantList &l, quintptr id, bool frozen)
for (int i = 0; i < l.size(); ++i)
JS_SetPropertyUint32(m_context, array, i, asJsValue(l.at(i), 0, frozen));
if (frozen)
JS_ObjectSeal(m_context, array, true);
JS_FreezeObject(m_context, array);
if (!id)
return array;
m_jsValueCache[id] = array;
Expand Down Expand Up @@ -841,8 +835,9 @@ JSValue ScriptEngine::evaluate(
const QByteArray &codeStr = code.toUtf8();

m_evalPositions.emplace(filePath, line);
const JSValue v = JS_EvalThis(m_context, globalObject(), codeStr.constData(), codeStr.length(),
filePath.toUtf8().constData(), line, JS_EVAL_TYPE_GLOBAL);
JSEvalOptions evalOptions{1, JS_EVAL_TYPE_GLOBAL, filePath.toUtf8().constData(), line};
const JSValue v = JS_EvalThis2(
m_context, globalObject(), codeStr.constData(), codeStr.length(), &evalOptions);
m_evalPositions.pop();
m_scopeChains.pop_back();
if (resultOwner == JsValueOwner::ScriptEngine && JS_VALUE_HAS_REF_COUNT(v))
Expand Down Expand Up @@ -871,7 +866,7 @@ JSClassID ScriptEngine::registerClass(const char *name, JSClassCall *constructor
JSClassID id = 0;
const auto classIt = m_classes.constFind(QLatin1String(name));
if (classIt == m_classes.constEnd()) {
JS_NewClassID(&id);
JS_NewClassID(m_jsRuntime, &id);
const auto it = getProperty
? m_exoticMethods.insert(id, JSClassExoticMethods{getProperty, getPropertyNames})
: m_exoticMethods.end();
Expand Down Expand Up @@ -1083,7 +1078,7 @@ ScriptEngine::PropertyCacheKey::PropertyCacheKey(QString moduleName,

JsException ScriptEngine::checkAndClearException(const CodeLocation &fallbackLocation) const
{
return {m_context, JS_GetException(m_context), fallbackLocation};
return {m_context, JS_GetException(m_context), JS_GetBacktrace(m_context), fallbackLocation};
}

void ScriptEngine::clearRequestedProperties()
Expand Down
5 changes: 3 additions & 2 deletions src/lib/corelib/loader/dependenciesresolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,8 +1115,9 @@ QVariantMap safeToVariant(JSContext *ctx, const JSValue &v)
if (JS_IsError(ctx, u))
throw ErrorInfo(getJsString(ctx, u));
const QString name = getJsString(ctx, prop);
result[name] = (JS_IsObject(u) && !JS_IsArray(ctx, u) && !JS_IsRegExp(ctx, u))
? safeToVariant(ctx, u) : getJsVariant(ctx, u);
result[name] = (JS_IsObject(u) && !JS_IsArray(ctx, u) && !JS_IsRegExp(u))
? safeToVariant(ctx, u)
: getJsVariant(ctx, u);
});
return result;
}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/corelib/tools/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ ErrorInfo::ErrorInfo(const QString &description, const QStringList &backtrace)
for (const QString &traceLine : backtrace) {
if (traceLine.contains(QStringLiteral("<eval>")))
continue;
static const std::regex regexpWithFunc("^(.+) at [^(]*\\((.+):(\\-?[0-9]+)\\)$");
static const std::regex regexpWithoutFunc("^(.+) at (.+):(\\-?[0-9]+)$");
static const std::regex regexpWithFunc(
"^(.+) at [^(]*\\((.+):(\\-?[0-9]+):(\\-?[0-9]+)\\)$");
static const std::regex regexpWithoutFunc("^(.+) at (.+):(\\-?[0-9]+):(\\-?[0-9]+)$");
std::smatch match;
const std::string tl = traceLine.toStdString();
bool hasMatch = std::regex_match(tl, match, regexpWithFunc);
Expand Down
16 changes: 11 additions & 5 deletions src/lib/corelib/tools/scripttools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,20 @@ TemporaryGlobalObjectSetter::~TemporaryGlobalObjectSetter()
}

JsException::JsException(JsException &&other) noexcept
: m_ctx(other.m_ctx), m_exception(other.m_exception),
m_fallbackLocation(std::move(other.m_fallbackLocation))
: m_ctx(other.m_ctx)
, m_exception(other.m_exception)
, m_backtrace(other.m_exception)
, m_fallbackLocation(std::move(other.m_fallbackLocation))
{
other.m_exception = JS_NULL;
other.m_backtrace = JS_NULL;
}

JsException::~JsException() { JS_FreeValue(m_ctx, m_exception); }
JsException::~JsException()
{
JS_FreeValue(m_ctx, m_exception);
JS_FreeValue(m_ctx, m_backtrace);
}

QString JsException::message() const
{
Expand All @@ -113,8 +120,7 @@ QString JsException::message() const

const QStringList JsException::stackTrace() const
{
return getJsStringProperty(m_ctx, m_exception, QLatin1String("stack"))
.split(QLatin1Char('\n'), Qt::SkipEmptyParts);
return getJsString(m_ctx, m_backtrace).split(QLatin1Char('\n'), Qt::SkipEmptyParts);
}

ErrorInfo JsException::toErrorInfo() const
Expand Down
11 changes: 8 additions & 3 deletions src/lib/corelib/tools/scripttools.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,25 @@ class ScopedJsAtom
class QBS_AUTOTEST_EXPORT JsException
{
public:
JsException(JSContext *ctx, JSValue ex, const CodeLocation &fallbackLocation)
: m_ctx(ctx), m_exception(ex), m_fallbackLocation(fallbackLocation) {}
JsException(JSContext *ctx, JSValue ex, JSValue bt, const CodeLocation &fallbackLocation)
: m_ctx(ctx)
, m_exception(ex)
, m_backtrace(bt)
, m_fallbackLocation(fallbackLocation)
{}
JsException(JsException && other) noexcept;
~JsException();
JsException(const JsException &) = delete;
JsException &operator=(const JsException &) = delete;

operator bool() const { return !JS_IsNull(m_exception); }
operator bool() const { return m_exception.tag != JS_TAG_UNINITIALIZED; }
QString message() const;
const QStringList stackTrace() const;
ErrorInfo toErrorInfo() const;
private:
JSContext *m_ctx;
JSValue m_exception;
JSValue m_backtrace;
CodeLocation m_fallbackLocation;
};

Expand Down
1 change: 1 addition & 0 deletions src/shared/quickjs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_qbs_library(qbsquickjs
libunicode.c libunicode.h
list.h
quickjs-atom.h
quickjs-c-atomics.h
quickjs-opcode.h
quickjs.c quickjs.h
DEFINES
Expand Down
Loading

0 comments on commit 0293ef9

Please sign in to comment.