/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/node_cjs_lexer.cc
115 строк
4 KB
Yagiz Nizipli
src: omit unconvertible names in cjs_lexer::Parse
20 июн 2026, 22:01
Не верифицирован
20 июн 2026, 22:01
7bdd50b
Код
Авторство
О чём код?
#include "env-inl.h" #include "node_external_reference.h" #include "simdutf.h" #include "util-inl.h" #include "v8.h" #include "merve.h" namespace node { namespace cjs_lexer { using v8::Array; using v8::Context; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::LocalVector; using v8::MaybeLocal; using v8::NewStringType; using v8::Object; using v8::Set; using v8::String; using v8::Value; // Create a V8 string from an export_string variant, using fast path for ASCII template <typename T> inline MaybeLocal<String> CreateString(Isolate* isolate, const T& str) { std::string_view sv = lexer::get_string_view(str); if (simdutf::validate_ascii(sv.data(), sv.size())) { return String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(sv.data()), NewStringType::kInternalized, static_cast<int>(sv.size())); } return String::NewFromUtf8(isolate, sv.data(), NewStringType::kInternalized, static_cast<int>(sv.size())); } void Parse(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); Local<Context> context = isolate->GetCurrentContext(); // Handle null, undefined, or missing argument by defaulting to empty string if (args.Length() < 1 || args[0]->IsNullOrUndefined()) { Local<Value> result_elements[] = {Set::New(isolate), Array::New(isolate, 0)}; args.GetReturnValue().Set(Array::New(isolate, result_elements, 2)); return; } CHECK(args[0]->IsString()); Utf8Value source(isolate, args[0]); auto result = lexer::parse_commonjs(source.ToStringView()); if (!result.has_value()) { Local<Value> result_elements[] = {Set::New(isolate), Array::New(isolate, 0)}; args.GetReturnValue().Set(Array::New(isolate, result_elements, 2)); return; } const auto& analysis = result.value(); // Convert exports to JS Set, omitting any name that cannot be turned into a // V8 string (e.g. on string allocation failure) instead of aborting. Local<Set> exports_set = Set::New(isolate); for (const auto& exp : analysis.exports) { Local<String> exp_str; if (CreateString(isolate, exp).ToLocal(&exp_str) && exports_set->Add(context, exp_str).IsEmpty()) { return; } } // Convert reexports to JS array, omitting any name that cannot be turned into // a V8 string. LocalVector<Value> reexports_vec(isolate); reexports_vec.reserve(analysis.re_exports.size()); for (const auto& reexp : analysis.re_exports) { Local<String> reexp_str; if (CreateString(isolate, reexp).ToLocal(&reexp_str)) { reexports_vec.push_back(reexp_str); } } // Create result array [exports (Set), reexports (Array)] Local<Value> result_elements[] = { exports_set, Array::New(isolate, reexports_vec.data(), reexports_vec.size())}; args.GetReturnValue().Set(Array::New(isolate, result_elements, 2)); } void Initialize(Local<Object> target, Local<Value> unused, Local<Context> context, void* priv) { SetMethodNoSideEffect(context, target, "parse", Parse); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(Parse); } } // namespace cjs_lexer } // namespace node NODE_BINDING_CONTEXT_AWARE_INTERNAL(cjs_lexer, node::cjs_lexer::Initialize) NODE_BINDING_EXTERNAL_REFERENCE(cjs_lexer, node::cjs_lexer::RegisterExternalReferences)