aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
diff options
context:
space:
mode:
authorGravatar Ashcon Partovi <ashcon@partovi.net> 2023-08-03 15:31:55 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-03 15:31:55 -0700
commit08cf0d562ae81b4fb30aa5e599ca76056582ac5f (patch)
tree8385fce04c9bf7b4138ae3c3545aa330f388f456 /src/bun.js/bindings/sqlite/JSSQLStatement.cpp
parent9a2c3dea88b22351ecc85126b0c225bfefea71bf (diff)
downloadbun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.tar.gz
bun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.tar.zst
bun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.zip
Bunch of fixes (#3516)
* Fix #3497 * Fix #3497 * Run prettier * Fix package.json * remove this too * yeah * Fix missing tests * Use native for utf-8-validate * Add module ID names to builtins * Defer evaluation of ESM & CJS modules until link time * Use builtin name for exports in plugins * Add module IDs to builtins * Update JSC build with new flag * WebKit upgrade fixes * Update WebKit * prettier * Upgrade WebKit * bump * Update once again * Add visitAdditionalChildren, remove .fill() usage * Update process.test.js * Update fs.test.ts --------- Co-authored-by: dave caruso <me@paperdave.net> Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/sqlite/JSSQLStatement.cpp')
-rw-r--r--src/bun.js/bindings/sqlite/JSSQLStatement.cpp137
1 files changed, 73 insertions, 64 deletions
diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
index b177a1b6f..d42f01019 100644
--- a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
+++ b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
@@ -175,6 +175,8 @@ public:
}
DECLARE_VISIT_CHILDREN;
DECLARE_EXPORT_INFO;
+ template<typename Visitor> void visitAdditionalChildren(Visitor&);
+ template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
// static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
@@ -263,6 +265,8 @@ static void initializeColumnNames(JSC::JSGlobalObject* lexicalGlobalObject, JSSQ
if (LIKELY(!anyHoles)) {
Structure* structure = globalObject.structureCache().emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), columnNames->size());
+ vm.writeBarrier(castedThis, structure);
+
for (const auto& propertyName : *columnNames) {
structure = Structure::addPropertyTransition(vm, structure, propertyName, 0, offset);
}
@@ -423,8 +427,10 @@ static JSC::JSValue rebindObject(JSC::JSGlobalObject* globalObject, JSC::JSValue
JSValue value;
if (LIKELY(!slot.isTaintedByOpaqueObject()))
value = slot.getValue(globalObject, propertyName);
- else
+ else {
value = target->get(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, JSValue());
+ }
// Ensure this gets freed on scope clear
auto utf8 = WTF::String(propertyName.string()).utf8();
@@ -1075,76 +1081,57 @@ static inline JSC::JSValue constructResultObject(JSC::JSGlobalObject* lexicalGlo
auto* stmt = castedThis->stmt;
if (auto* structure = castedThis->_structure.get()) {
- RELEASE_ASSERT(count <= 64);
- // It looks a little silly doing these two loops right?
- //
- // The code that does putDirectOffset has to be very careful about time between GC allocations
- // while the object is not fully initialized.
- //
- // So we do two loops
- // 1. The first loop to fill all the values from SQLite into a MarkedVector.
- // 2. The second loop to actually put them into the object.
-
- // This rowBuffer is a stack allocation.
- MarkedVector<JSValue, 64> rowBuffer;
-
- rowBuffer.fill(count, [&](JSValue* value) -> void {
- // Loop 1. Fill the rowBuffer with values from SQLite
- for (int i = 0; i < count; i++, value++) {
- switch (sqlite3_column_type(stmt, i)) {
- case SQLITE_INTEGER: {
- // https://github.com/oven-sh/bun/issues/1536
- *value = jsNumber(sqlite3_column_int64(stmt, i));
- break;
- }
- case SQLITE_FLOAT: {
- *value = jsNumber(sqlite3_column_double(stmt, i));
- break;
- }
- // > Note that the SQLITE_TEXT constant was also used in SQLite version
- // > 2 for a completely different meaning. Software that links against
- // > both SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT,
- // > not SQLITE_TEXT.
- case SQLITE3_TEXT: {
- size_t len = sqlite3_column_bytes(stmt, i);
- const unsigned char* text = len > 0 ? sqlite3_column_text(stmt, i) : nullptr;
-
- if (len > 64) {
- *value = JSC::JSValue::decode(Bun__encoding__toStringUTF8(text, len, lexicalGlobalObject));
- continue;
- }
-
- *value = jsString(vm, WTF::String::fromUTF8(text, len));
- break;
- }
- case SQLITE_BLOB: {
- size_t len = sqlite3_column_bytes(stmt, i);
- const void* blob = len > 0 ? sqlite3_column_blob(stmt, i) : nullptr;
- JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), len);
+ result = JSC::constructEmptyObject(vm, structure);
- if (LIKELY(blob && len))
- memcpy(array->vector(), blob, len);
+ for (unsigned int i = 0; i < count; i++) {
+ JSValue value;
- *value = array;
- break;
- }
- default: {
- *value = jsNull();
- break;
- }
+ // Loop 1. Fill the rowBuffer with values from SQLite
+ switch (sqlite3_column_type(stmt, i)) {
+ case SQLITE_INTEGER: {
+ // https://github.com/oven-sh/bun/issues/1536
+ value = jsNumber(sqlite3_column_int64(stmt, i));
+ break;
+ }
+ case SQLITE_FLOAT: {
+ value = jsNumber(sqlite3_column_double(stmt, i));
+ break;
+ }
+ // > Note that the SQLITE_TEXT constant was also used in SQLite version
+ // > 2 for a completely different meaning. Software that links against
+ // > both SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT,
+ // > not SQLITE_TEXT.
+ case SQLITE3_TEXT: {
+ size_t len = sqlite3_column_bytes(stmt, i);
+ const unsigned char* text = len > 0 ? sqlite3_column_text(stmt, i) : nullptr;
+
+ if (len > 64) {
+ value = JSC::JSValue::decode(Bun__encoding__toStringUTF8(text, len, lexicalGlobalObject));
+ continue;
}
+
+ value = jsString(vm, WTF::String::fromUTF8(text, len));
+ break;
}
- });
+ case SQLITE_BLOB: {
+ size_t len = sqlite3_column_bytes(stmt, i);
+ const void* blob = len > 0 ? sqlite3_column_blob(stmt, i) : nullptr;
+ JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), len);
- result = JSC::constructEmptyObject(vm, structure);
+ if (LIKELY(blob && len))
+ memcpy(array->vector(), blob, len);
- // TODO: Add .forEach to MarkedVector<>. When JSC assertions are enabled, this function will fail.
- rowBuffer.fill(count, [&](JSValue* value) -> void {
- // Loop 2. fill the rowBuffer with values from SQLite
- for (unsigned int i = 0; i < count; i++, value++) {
- result->putDirectOffset(vm, i, *value);
+ value = array;
+ break;
+ }
+ default: {
+ value = jsNull();
+ break;
}
- });
+ }
+
+ result->putDirectOffset(vm, i, value);
+ }
} else {
if (count <= 64) {
@@ -1697,4 +1684,26 @@ void JSSQLStatement::visitChildrenImpl(JSCell* cell, Visitor& visitor)
}
DEFINE_VISIT_CHILDREN(JSSQLStatement);
+
+template<typename Visitor>
+void JSSQLStatement::visitAdditionalChildren(Visitor& visitor)
+{
+ JSSQLStatement* thisObject = this;
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ visitor.append(thisObject->_structure);
+ visitor.append(thisObject->_prototype);
+}
+
+template<typename Visitor>
+void JSSQLStatement::visitOutputConstraints(JSCell* cell, Visitor& visitor)
+{
+ auto* thisObject = jsCast<JSSQLStatement*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitOutputConstraints(thisObject, visitor);
+ thisObject->visitAdditionalChildren(visitor);
+}
+
+template void JSSQLStatement::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
+template void JSSQLStatement::visitOutputConstraints(JSCell*, SlotVisitor&);
}