aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-14 16:48:41 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-17 07:36:35 -0700
commit382be2cb46eac458e7f619ee1ee05c9efadcce51 (patch)
tree6b5038b0cf94c2f743ee6f5cc71d1e7cc86961db /src/bun.js/bindings/sqlite/JSSQLStatement.cpp
parent0aa3a0a5b04249f79b1b1bb1722ca2a38313c0d4 (diff)
downloadbun-382be2cb46eac458e7f619ee1ee05c9efadcce51.tar.gz
bun-382be2cb46eac458e7f619ee1ee05c9efadcce51.tar.zst
bun-382be2cb46eac458e7f619ee1ee05c9efadcce51.zip
[bun:sqlite] Add DOMJIT to get()
Diffstat (limited to 'src/bun.js/bindings/sqlite/JSSQLStatement.cpp')
-rw-r--r--src/bun.js/bindings/sqlite/JSSQLStatement.cpp186
1 files changed, 122 insertions, 64 deletions
diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
index 24d68cd57..30e6d3ddc 100644
--- a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
+++ b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
@@ -20,6 +20,13 @@
#include "GCDefferalContext.h"
#include "Buffer.h"
+#include <JavaScriptCore/DOMJITAbstractHeap.h>
+#include "DOMJITIDLConvert.h"
+#include "DOMJITIDLType.h"
+#include "DOMJITIDLTypeFilter.h"
+#include "DOMJITHelpers.h"
+#include <JavaScriptCore/DFGAbstractHeap.h>
+
/* ******************************************************************************** */
// Lazy Load SQLite on macOS
// This seemed to be about 3% faster on macOS
@@ -161,6 +168,69 @@ protected:
void finishCreation(JSC::VM&);
};
+static void initializeColumnNames(JSC::JSGlobalObject* lexicalGlobalObject, JSSQLStatement* castedThis)
+{
+ if (!castedThis->hasExecuted) {
+ castedThis->hasExecuted = true;
+ } else {
+ // reinitialize column
+ castedThis->columnNames.reset(new PropertyNameArray(
+ castedThis->columnNames->vm(),
+ castedThis->columnNames->propertyNameMode(),
+ castedThis->columnNames->privateSymbolMode()));
+ }
+ castedThis->update_version();
+
+ JSC::VM& vm = lexicalGlobalObject->vm();
+
+ auto* stmt = castedThis->stmt;
+
+ int count = sqlite3_column_count(stmt);
+ if (count == 0)
+ return;
+ JSC::ObjectInitializationScope initializationScope(vm);
+
+ // 64 is the maximum we can preallocate here
+ // see https://github.com/oven-sh/bun/issues/987
+ JSC::JSObject* object = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), std::min(count, 64));
+
+ for (int i = 0; i < count; i++) {
+ const char* name = sqlite3_column_name(stmt, i);
+
+ if (name == nullptr)
+ break;
+
+ size_t len = strlen(name);
+ if (len == 0)
+ break;
+
+ auto wtfString = WTF::String::fromUTF8(name, len);
+ auto str = JSValue(jsString(vm, wtfString));
+ auto key = str.toPropertyKey(lexicalGlobalObject);
+ JSC::JSValue primitive = JSC::jsUndefined();
+ auto decl = sqlite3_column_decltype(stmt, i);
+ if (decl != nullptr) {
+ switch (decl[0]) {
+ case 'F':
+ case 'D':
+ case 'I': {
+ primitive = jsNumber(0);
+ break;
+ }
+ case 'V':
+ case 'T': {
+ primitive = jsEmptyString(vm);
+ break;
+ }
+ }
+ }
+
+ object->putDirect(vm, key, primitive, 0);
+ castedThis->columnNames->add(key);
+ }
+ castedThis->_prototype.set(vm, castedThis, object);
+}
+
void JSSQLStatement::destroy(JSC::JSCell* cell)
{
JSSQLStatement* thisObject = static_cast<JSSQLStatement*>(cell);
@@ -1003,69 +1073,6 @@ static inline JSC::JSArray* constructResultRow(JSC::JSGlobalObject* lexicalGloba
return constructResultRow(lexicalGlobalObject, castedThis, scope, nullptr);
}
-static void initializeColumnNames(JSC::JSGlobalObject* lexicalGlobalObject, JSSQLStatement* castedThis)
-{
- if (!castedThis->hasExecuted) {
- castedThis->hasExecuted = true;
- } else {
- // reinitialize column
- castedThis->columnNames.reset(new PropertyNameArray(
- castedThis->columnNames->vm(),
- castedThis->columnNames->propertyNameMode(),
- castedThis->columnNames->privateSymbolMode()));
- }
- castedThis->update_version();
-
- JSC::VM& vm = lexicalGlobalObject->vm();
-
- auto* stmt = castedThis->stmt;
-
- int count = sqlite3_column_count(stmt);
- if (count == 0)
- return;
- JSC::ObjectInitializationScope initializationScope(vm);
-
- // 64 is the maximum we can preallocate here
- // see https://github.com/oven-sh/bun/issues/987
- JSC::JSObject* object = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), std::min(count, 64));
-
- for (int i = 0; i < count; i++) {
- const char* name = sqlite3_column_name(stmt, i);
-
- if (name == nullptr)
- break;
-
- size_t len = strlen(name);
- if (len == 0)
- break;
-
- auto wtfString = WTF::String::fromUTF8(name, len);
- auto str = JSValue(jsString(vm, wtfString));
- auto key = str.toPropertyKey(lexicalGlobalObject);
- JSC::JSValue primitive = JSC::jsUndefined();
- auto decl = sqlite3_column_decltype(stmt, i);
- if (decl != nullptr) {
- switch (decl[0]) {
- case 'F':
- case 'D':
- case 'I': {
- primitive = jsNumber(0);
- break;
- }
- case 'V':
- case 'T': {
- primitive = jsEmptyString(vm);
- break;
- }
- }
- }
-
- object->putDirect(vm, key, primitive, 0);
- castedThis->columnNames->add(key);
- }
- castedThis->_prototype.set(vm, castedThis, object);
-}
-
JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionAll, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
@@ -1185,6 +1192,57 @@ JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionGet, (JSC::JSGlob
}
}
+extern "C" {
+static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsSQLStatementExecuteStatementFunctionGetWithoutTypeChecking, JSC::EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, JSSQLStatement* castedThis));
+}
+
+JSC_DEFINE_JIT_OPERATION(jsSQLStatementExecuteStatementFunctionGetWithoutTypeChecking, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, JSSQLStatement* castedThis))
+{
+
+ JSC::VM& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* stmt = castedThis->stmt;
+ CHECK_PREPARED
+
+ int statusCode = sqlite3_reset(stmt);
+ if (UNLIKELY(statusCode != SQLITE_OK)) {
+ throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, WTF::String::fromUTF8(sqlite3_errstr(statusCode))));
+ return JSValue::encode(jsUndefined());
+ }
+
+ int status = sqlite3_step(stmt);
+ if (!sqlite3_stmt_readonly(stmt)) {
+ castedThis->version_db->version++;
+ }
+
+ if (!castedThis->hasExecuted || castedThis->need_update()) {
+ initializeColumnNames(lexicalGlobalObject, castedThis);
+ }
+
+ size_t columnCount = castedThis->columnNames->size();
+ int counter = 0;
+
+ if (status == SQLITE_ROW) {
+ RELEASE_AND_RETURN(scope, JSC::JSValue::encode(constructResultObject(lexicalGlobalObject, castedThis)));
+ } else if (status == SQLITE_DONE) {
+ RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsNull()));
+ } else {
+ throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, WTF::String::fromUTF8(sqlite3_errstr(status))));
+ sqlite3_reset(stmt);
+ return JSValue::encode(jsUndefined());
+ }
+}
+
+constexpr JSC::DFG::AbstractHeapKind readKinds[4] = { JSC::DFG::MiscFields, JSC::DFG::HeapObjectCount };
+constexpr JSC::DFG::AbstractHeapKind writeKinds[4] = { JSC::DFG::SideState, JSC::DFG::HeapObjectCount };
+
+static const JSC::DOMJIT::Signature DOMJITSignatureForjsSQLStatementExecuteStatementFunctionGet(
+ jsSQLStatementExecuteStatementFunctionGetWithoutTypeChecking,
+ JSSQLStatement::info(),
+ JSC::DOMJIT::Effect::forReadWriteKinds(readKinds, writeKinds),
+ JSC::SpecOther);
+
JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionRows, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
@@ -1384,7 +1442,7 @@ const ClassInfo JSSQLStatement::s_info = { "SQLStatement"_s, nullptr, nullptr, n
/* Hash table for prototype */
static const HashTableValue JSSQLStatementTableValues[] = {
{ "run"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementExecuteStatementFunctionRun), (intptr_t)(1) } },
- { "get"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementExecuteStatementFunctionGet), (intptr_t)(1) } },
+ { "get"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementExecuteStatementFunctionGet), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForjsSQLStatementExecuteStatementFunctionGet) } },
{ "all"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementExecuteStatementFunctionAll), (intptr_t)(1) } },
{ "values"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementExecuteStatementFunctionRows), (intptr_t)(1) } },
{ "finalize"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsSQLStatementFunctionFinalize), (intptr_t)(0) } },