Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 12 additions & 48 deletions src/env_properties.h

Large diffs are not rendered by default.

140 changes: 68 additions & 72 deletions src/node_sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ using v8::BigInt;
using v8::Boolean;
using v8::ConstructorBehavior;
using v8::Context;
using v8::DictionaryTemplate;
using v8::DontDelete;
using v8::Exception;
using v8::Function;
Expand Down Expand Up @@ -119,6 +120,18 @@ using v8::Value;
} \
} while (0)

namespace {
Local<DictionaryTemplate> getLazyIterTemplate(Environment* env) {
auto iter_template = env->iter_template();
if (iter_template.IsEmpty()) {
static constexpr std::string_view iter_keys[] = {"done", "value"};
iter_template = DictionaryTemplate::New(env->isolate(), iter_keys);
env->set_iter_template(iter_template);
}
return iter_template;
}
} // namespace

inline MaybeLocal<Object> CreateSQLiteError(Isolate* isolate,
const char* message) {
Local<String> js_msg;
Expand Down Expand Up @@ -2239,58 +2252,35 @@ void StatementSync::Columns(const FunctionCallbackInfo<Value>& args) {
int num_cols = sqlite3_column_count(stmt->statement_);
Isolate* isolate = env->isolate();
LocalVector<Value> cols(isolate);
LocalVector<Name> col_keys(isolate,
{env->column_string(),
env->database_string(),
env->name_string(),
env->table_string(),
env->type_string()});
Local<Value> value;
auto sqlite_column_template = env->sqlite_column_template();
if (sqlite_column_template.IsEmpty()) {
static constexpr std::string_view col_keys[] = {
"column", "database", "name", "table", "type"};
sqlite_column_template = DictionaryTemplate::New(isolate, col_keys);
env->set_sqlite_column_template(sqlite_column_template);
}

cols.reserve(num_cols);
for (int i = 0; i < num_cols; ++i) {
LocalVector<Value> col_values(isolate);
col_values.reserve(col_keys.size());

if (!NullableSQLiteStringToValue(
isolate, sqlite3_column_origin_name(stmt->statement_, i))
.ToLocal(&value)) {
return;
}
col_values.emplace_back(value);

if (!NullableSQLiteStringToValue(
isolate, sqlite3_column_database_name(stmt->statement_, i))
.ToLocal(&value)) {
return;
}
col_values.emplace_back(value);

if (!stmt->ColumnNameToName(i).ToLocal(&value)) {
return;
}
col_values.emplace_back(value);

if (!NullableSQLiteStringToValue(
isolate, sqlite3_column_table_name(stmt->statement_, i))
.ToLocal(&value)) {
return;
}
col_values.emplace_back(value);

if (!NullableSQLiteStringToValue(
isolate, sqlite3_column_decltype(stmt->statement_, i))
.ToLocal(&value)) {
MaybeLocal<Value> values[] = {
NullableSQLiteStringToValue(
isolate, sqlite3_column_origin_name(stmt->statement_, i)),
NullableSQLiteStringToValue(
isolate, sqlite3_column_database_name(stmt->statement_, i)),
stmt->ColumnNameToName(i),
NullableSQLiteStringToValue(
isolate, sqlite3_column_table_name(stmt->statement_, i)),
NullableSQLiteStringToValue(
isolate, sqlite3_column_decltype(stmt->statement_, i)),
};

Local<Object> col;
if (!NewDictionaryInstanceNullProto(
env->context(), sqlite_column_template, values)
.ToLocal(&col)) {
return;
}
col_values.emplace_back(value);

Local<Object> column = Object::New(isolate,
Null(isolate),
col_keys.data(),
col_values.data(),
col_keys.size());
cols.emplace_back(column);
cols.emplace_back(col);
}

args.GetReturnValue().Set(Array::New(isolate, cols.data(), cols.size()));
Expand Down Expand Up @@ -2522,15 +2512,19 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_ON_BAD_STATE(
env, iter->stmt_->IsFinalized(), "statement has been finalized");
Isolate* isolate = env->isolate();
LocalVector<Name> keys(isolate, {env->done_string(), env->value_string()});

auto iter_template = getLazyIterTemplate(env);

if (iter->done_) {
LocalVector<Value> values(isolate,
{Boolean::New(isolate, true), Null(isolate)});
DCHECK_EQ(values.size(), keys.size());
Local<Object> result = Object::New(
isolate, Null(isolate), keys.data(), values.data(), keys.size());
args.GetReturnValue().Set(result);
MaybeLocal<Value> values[]{
Boolean::New(isolate, true),
Null(isolate),
};
Local<Object> result;
if (NewDictionaryInstanceNullProto(env->context(), iter_template, values)
.ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
return;
}

Expand All @@ -2539,12 +2533,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
CHECK_ERROR_OR_THROW(
env->isolate(), iter->stmt_->db_.get(), r, SQLITE_DONE, void());
sqlite3_reset(iter->stmt_->statement_);
LocalVector<Value> values(isolate,
{Boolean::New(isolate, true), Null(isolate)});
DCHECK_EQ(values.size(), keys.size());
Local<Object> result = Object::New(
isolate, Null(isolate), keys.data(), values.data(), keys.size());
args.GetReturnValue().Set(result);
MaybeLocal<Value> values[] = {Boolean::New(isolate, true), Null(isolate)};
Local<Object> result;
if (NewDictionaryInstanceNullProto(env->context(), iter_template, values)
.ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
return;
}

Expand Down Expand Up @@ -2572,11 +2566,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
isolate, Null(isolate), row_keys.data(), row_values.data(), num_cols);
}

LocalVector<Value> values(isolate, {Boolean::New(isolate, false), row_value});
DCHECK_EQ(keys.size(), values.size());
Local<Object> result = Object::New(
isolate, Null(isolate), keys.data(), values.data(), keys.size());
args.GetReturnValue().Set(result);
MaybeLocal<Value> values[] = {Boolean::New(isolate, false), row_value};
Local<Object> result;
if (NewDictionaryInstanceNullProto(env->context(), iter_template, values)
.ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
}

void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
Expand All @@ -2589,14 +2584,15 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {

sqlite3_reset(iter->stmt_->statement_);
iter->done_ = true;
LocalVector<Name> keys(isolate, {env->done_string(), env->value_string()});
LocalVector<Value> values(isolate,
{Boolean::New(isolate, true), Null(isolate)});

DCHECK_EQ(keys.size(), values.size());
Local<Object> result = Object::New(
isolate, Null(isolate), keys.data(), values.data(), keys.size());
args.GetReturnValue().Set(result);
auto iter_template = getLazyIterTemplate(env);
MaybeLocal<Value> values[] = {Boolean::New(isolate, true), Null(isolate)};

Local<Object> result;
if (NewDictionaryInstanceNullProto(env->context(), iter_template, values)
.ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
}

Session::Session(Environment* env,
Expand Down
93 changes: 43 additions & 50 deletions src/node_url_pattern.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ namespace node::url_pattern {

using v8::Array;
using v8::Context;
using v8::DictionaryTemplate;
using v8::DontDelete;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
using v8::Isolate;
using v8::Local;
using v8::LocalVector;
using v8::MaybeLocal;
using v8::Name;
using v8::NewStringType;
Expand Down Expand Up @@ -396,56 +396,49 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue(
Environment* env, const ada::url_pattern_result& result) {
auto isolate = env->isolate();
Local<Name> names[] = {
env->inputs_string(),
env->protocol_string(),
env->username_string(),
env->password_string(),
env->hostname_string(),
env->port_string(),
env->pathname_string(),
env->search_string(),
env->hash_string(),
};
LocalVector<Value> inputs(isolate, result.inputs.size());
size_t index = 0;
for (auto& input : result.inputs) {
if (std::holds_alternative<std::string_view>(input)) {
auto input_str = std::get<std::string_view>(input);
if (!ToV8Value(env->context(), input_str).ToLocal(&inputs[index])) {
return {};
}
} else {
DCHECK(std::holds_alternative<ada::url_pattern_init>(input));
auto init = std::get<ada::url_pattern_init>(input);
if (!URLPatternInit::ToJsObject(env, init).ToLocal(&inputs[index])) {
return {};
}
}
index++;
}
LocalVector<Value> values(isolate, arraysize(names));
values[0] = Array::New(isolate, inputs.data(), inputs.size());
if (!URLPatternComponentResult::ToJSObject(env, result.protocol)
.ToLocal(&values[1]) ||
!URLPatternComponentResult::ToJSObject(env, result.username)
.ToLocal(&values[2]) ||
!URLPatternComponentResult::ToJSObject(env, result.password)
.ToLocal(&values[3]) ||
!URLPatternComponentResult::ToJSObject(env, result.hostname)
.ToLocal(&values[4]) ||
!URLPatternComponentResult::ToJSObject(env, result.port)
.ToLocal(&values[5]) ||
!URLPatternComponentResult::ToJSObject(env, result.pathname)
.ToLocal(&values[6]) ||
!URLPatternComponentResult::ToJSObject(env, result.search)
.ToLocal(&values[7]) ||
!URLPatternComponentResult::ToJSObject(env, result.hash)
.ToLocal(&values[8])) {
return {};

auto tmpl = env->urlpatternresult_template();
if (tmpl.IsEmpty()) {
static constexpr std::string_view namesVec[] = {
"inputs",
"protocol",
"username",
"password",
"hostname",
"port",
"pathname",
"search",
"hash",
};
tmpl = DictionaryTemplate::New(isolate, namesVec);
env->set_urlpatternresult_template(tmpl);
}
return Object::New(
isolate, Object::New(isolate), names, values.data(), values.size());

size_t index = 0;
MaybeLocal<Value> vals[] = {
Array::New(env->context(),
result.inputs.size(),
[&index, &inputs = result.inputs, env]() {
auto& input = inputs[index++];
if (std::holds_alternative<std::string_view>(input)) {
auto input_str = std::get<std::string_view>(input);
return ToV8Value(env->context(), input_str);
} else {
DCHECK(
std::holds_alternative<ada::url_pattern_init>(input));
auto init = std::get<ada::url_pattern_init>(input);
return URLPatternInit::ToJsObject(env, init);
}
}),
URLPatternComponentResult::ToJSObject(env, result.protocol),
URLPatternComponentResult::ToJSObject(env, result.username),
URLPatternComponentResult::ToJSObject(env, result.password),
URLPatternComponentResult::ToJSObject(env, result.hostname),
URLPatternComponentResult::ToJSObject(env, result.port),
URLPatternComponentResult::ToJSObject(env, result.pathname),
URLPatternComponentResult::ToJSObject(env, result.search),
URLPatternComponentResult::ToJSObject(env, result.hash)};
return NewDictionaryInstanceNullProto(env->context(), tmpl, vals);
}

std::optional<ada::url_pattern_options>
Expand Down
37 changes: 24 additions & 13 deletions src/node_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using v8::BigInt;
using v8::Boolean;
using v8::CFunction;
using v8::Context;
using v8::DictionaryTemplate;
using v8::External;
using v8::FunctionCallbackInfo;
using v8::IndexFilter;
Expand All @@ -23,6 +24,7 @@ using v8::Isolate;
using v8::KeyCollectionMode;
using v8::Local;
using v8::LocalVector;
using v8::MaybeLocal;
using v8::Name;
using v8::Object;
using v8::ObjectTemplate;
Expand Down Expand Up @@ -263,6 +265,20 @@ static void GetCallSites(const FunctionCallbackInfo<Value>& args) {
const int frame_count = stack->GetFrameCount();
LocalVector<Value> callsite_objects(isolate);

auto callsite_template = env->callsite_template();
if (callsite_template.IsEmpty()) {
static constexpr std::string_view names[] = {
"functionName",
"scriptId",
"scriptName",
"lineNumber",
"columnNumber",
// TODO(legendecas): deprecate CallSite.column.
"column"};
callsite_template = DictionaryTemplate::New(isolate, names);
env->set_callsite_template(callsite_template);
}

// Frame 0 is node:util. It should be skipped.
for (int i = 1; i < frame_count; ++i) {
Local<StackFrame> stack_frame = stack->GetFrame(isolate, i);
Expand All @@ -279,16 +295,7 @@ static void GetCallSites(const FunctionCallbackInfo<Value>& args) {

std::string script_id = std::to_string(stack_frame->GetScriptId());

Local<Name> names[] = {
env->function_name_string(),
env->script_id_string(),
env->script_name_string(),
env->line_number_string(),
env->column_number_string(),
// TODO(legendecas): deprecate CallSite.column.
env->column_string(),
};
Local<Value> values[] = {
MaybeLocal<Value> values[] = {
function_name,
OneByteString(isolate, script_id),
script_name,
Expand All @@ -297,10 +304,14 @@ static void GetCallSites(const FunctionCallbackInfo<Value>& args) {
// TODO(legendecas): deprecate CallSite.column.
Integer::NewFromUnsigned(isolate, stack_frame->GetColumn()),
};
Local<Object> obj = Object::New(
isolate, v8::Null(isolate), names, values, arraysize(names));

callsite_objects.push_back(obj);
Local<Object> callsite;
if (!NewDictionaryInstanceNullProto(
env->context(), callsite_template, values)
.ToLocal(&callsite)) {
return;
}
callsite_objects.push_back(callsite);
}

Local<Array> callsites =
Expand Down
Loading
Loading