aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/ImportMetaObject.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-06-24 06:02:16 -0700
committerGravatar GitHub <noreply@github.com> 2023-06-24 06:02:16 -0700
commitff635551436123022ba3980b39580d53973c80a2 (patch)
tree7eb5292a7157e70dd432518f185bc9c39345ae89 /src/bun.js/bindings/ImportMetaObject.cpp
parent069b42a7cc1275969859dc60e7c303528ca2dccb (diff)
downloadbun-ff635551436123022ba3980b39580d53973c80a2.tar.gz
bun-ff635551436123022ba3980b39580d53973c80a2.tar.zst
bun-ff635551436123022ba3980b39580d53973c80a2.zip
Rewrite Bun's runtime CommonJS loader (#3379)
* wip changes for CommonJS * this rewrite is almost complete * even more code * wip * Remove usages of `import.meta.require` from builtins * Remove usages of require * Regenerate * :scissors: builtin rewrite commonjs in printer * Use lazy custom getters for import.meta * fixups * Remove depd * ugh * still crashing * fixup undici * comment out import.meta.require.resolve temporarily not a real solution but it stops the crashes * Redo import.meta.primordials * Builtins now have a `builtin://` protocol in source origin * Seems to work? * Finsih getting rid of primordials * switcharoo * No more function * just one more bug * Update launch.json * Implement `require.main` * :scissors: * Bump WebKit * Fixup import cycles * Fixup improt cycles * export more things * Implement `createCommonJSModule` builtin * More exports * regenerate * i broke some stuff * some of these tests work now * We lost the encoding * Sort of fix zlib * Sort of fix util * Update events.js * bump * bump * bump * Fix missing export in fs * fix some bugs with builtin esm modules (stream, worker_threads, events). its not perfect yet. * fix some other internal module bugs * oops * fix some extra require default stuff * uncomment this file but it crsahes on my machine * tidy code here * fixup tls exports * make simdutf happier * Add hasPrefix binding * Add test for `require.main` * Fix CommonJS evaluation order race condition * Make node:http load faster * Add missing exports to tls.js * Use the getter * Regenerate builtins * Fix assertion failure in Bun.write() * revamp dotEnv parser (#3347) - fixes `strings.indexOfAny()` - fixes OOB array access fixes #411 fixes #2823 fixes #3042 * fix tests for `expect()` (#3384) - extend test job time-out for `darwin-aarch64` * `expect().resolves` and `expect().rejects` (#3318) * Move expect and snapshots to their own files * expect().resolves and expect().rejects * Fix promise being added to unhandled rejection list * Handle timeouts in expect(<promise>) * wip merge * Fix merge issue --------- Co-authored-by: Jarred Sumner <jarred@jarredsumner.com> Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> * fixup min/memcopy (#3388) * Fix crash in builtins * Don't attempt to evaluate modules with no source code * Update WebCoreJSBuiltins.cpp * Update WebCoreJSBuiltins.cpp * Update WebCoreJSBuiltins.cpp * Fix crash * cleanup * Fix test cc @paperdave * Fixup Undici * Fix issue in node:http * Create util-deprecate.mjs * Fix several bugs * Use the identifier * Support error.code in `util.deprecate` * make the CJs loader slightly more resilient * Update WebCoreJSBuiltins.cpp * Fix macros --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Co-authored-by: dave caruso <me@paperdave.net> Co-authored-by: Alex Lam S.L <alexlamsl@gmail.com> Co-authored-by: Ashcon Partovi <ashcon@partovi.net> Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
Diffstat (limited to 'src/bun.js/bindings/ImportMetaObject.cpp')
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp484
1 files changed, 317 insertions, 167 deletions
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index a53712823..d201dafca 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -38,6 +38,9 @@
#include "JSDOMURL.h"
#include "JavaScriptCore/JSNativeStdFunction.h"
#include "JavaScriptCore/GetterSetter.h"
+#include <JavaScriptCore/LazyProperty.h>
+#include <JavaScriptCore/LazyPropertyInlines.h>
+#include <JavaScriptCore/VMTrapsInlines.h>
namespace Zig {
using namespace JSC;
@@ -83,10 +86,12 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
// require.resolve also supports a paths array
// we only support a single path
if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
- if (JSValue pathsValue = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
- if (JSC::JSArray* array = JSC::jsDynamicCast<JSC::JSArray*>(pathsValue)) {
- if (array->length() > 0) {
- fromValue = array->getIndex(globalObject, 0);
+ if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
+ if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
+ auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
+ if (pathsArray->length() > 0) {
+ fromValue = pathsArray->getIndex(globalObject, 0);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
}
}
}
@@ -123,142 +128,135 @@ Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* global
}
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireResolve);
+JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ return functionRequireResolve(globalObject, callFrame, callFrame->thisValue().toWTFString(globalObject));
+}
-class JSRequireResolveFunctionPrototype final : public JSC::InternalFunction {
-public:
- using Base = JSC::InternalFunction;
+JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
+{
+ Zig::GlobalObject* thisObject = jsCast<Zig::GlobalObject*>(globalObject);
+ return JSValue::encode(thisObject->lazyRequireCacheObject());
+}
- static JSRequireResolveFunctionPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
- {
- auto* structure = createStructure(vm, globalObject, globalObject->functionPrototype());
- JSRequireResolveFunctionPrototype* function = new (NotNull, JSC::allocateCell<JSRequireResolveFunctionPrototype>(vm)) JSRequireResolveFunctionPrototype(vm, structure);
- function->finishCreation(vm);
- return function;
- }
+JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter,
+ (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
+ JSC::EncodedJSValue value, JSC::PropertyName propertyName))
+{
+ JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
+ if (!thisObject)
+ return false;
- static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
- {
- return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
- }
+ thisObject->putDirect(globalObject->vm(), propertyName, JSValue::decode(value), 0);
+ return true;
+}
- DECLARE_INFO;
+JSC_DEFINE_HOST_FUNCTION(requireResolvePathsFunction, (JSGlobalObject * globalObject, CallFrame* callframe))
+{
+ return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr, 0));
+}
- static JSC::EncodedJSValue pathsFunction(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+static const HashTableValue RequireResolveFunctionPrototypeValues[] = {
+ { "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } },
+};
+
+class RequireResolveFunctionPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static RequireResolveFunctionPrototype* create(
+ JSC::JSGlobalObject* globalObject)
{
- return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr));
+ auto& vm = globalObject->vm();
+
+ auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype());
+ RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure);
+ prototype->finishCreation(vm);
+ return prototype;
}
-private:
- JSRequireResolveFunctionPrototype(JSC::VM& vm, JSC::Structure* structure)
- : JSC::InternalFunction(vm, structure, jsFunctionRequireResolve, jsFunctionRequireResolve)
+ DECLARE_INFO;
+ RequireResolveFunctionPrototype(
+ JSC::VM& vm,
+ JSC::Structure* structure)
+ : Base(vm, structure)
{
}
- void finishCreation(JSC::VM& vm)
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
- this->putDirectNativeFunction(vm, globalObject(), Identifier::fromString(vm, "paths"_s), 0, pathsFunction, ImplementationVisibility::Public, NoIntrinsic, 0);
- Base::finishCreation(vm, 2, "resolve"_s, PropertyAdditionMode::WithoutStructureTransition);
+ return &vm.plainObjectSpace();
}
};
-const JSC::ClassInfo JSRequireResolveFunctionPrototype::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSRequireResolveFunctionPrototype) };
+class ResolveFunction final : public JSC::InternalFunction {
-class JSRequireResolveFunction final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
-
- static JSRequireResolveFunction* create(JSC::VM& vm, JSC::Structure* structure, const WTF::String& from)
- {
- JSRequireResolveFunction* function = new (NotNull, JSC::allocateCell<JSRequireResolveFunction>(vm)) JSRequireResolveFunction(vm, structure, from);
- function->finishCreation(vm);
- return function;
- }
-
- static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ static ResolveFunction* create(JSGlobalObject* globalObject)
{
- return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
+ JSObject* resolvePrototype = RequireResolveFunctionPrototype::create(globalObject);
+ Structure* structure = Structure::create(
+ globalObject->vm(),
+ globalObject,
+ resolvePrototype,
+ JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags),
+ ResolveFunction::info());
+ auto* resolveFunction = new (NotNull, JSC::allocateCell<ResolveFunction>(globalObject->vm())) ResolveFunction(globalObject->vm(), structure);
+ resolveFunction->finishCreation(globalObject->vm());
+ return resolveFunction;
}
DECLARE_INFO;
- WTF::String from;
-
- template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
- {
- if constexpr (mode == JSC::SubspaceAccess::Concurrently)
- return nullptr;
-
- return WebCore::subspaceForImpl<JSRequireResolveFunction, UseCustomHeapCellType::No>(
- vm,
- [](auto& spaces) { return spaces.m_clientSubspaceForRequireResolveFunction.get(); },
- [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForRequireResolveFunction = std::forward<decltype(space)>(space); },
- [](auto& spaces) { return spaces.m_subspaceForRequireResolveFunction.get(); },
- [](auto& spaces, auto&& space) { spaces.m_subspaceForRequireResolveFunction = std::forward<decltype(space)>(space); });
- }
-
-private:
- JSRequireResolveFunction(JSC::VM& vm, JSC::Structure* structure, const WTF::String& from_)
- : JSC::InternalFunction(vm, structure, jsFunctionRequireResolve, jsFunctionRequireResolve)
- , from(from_)
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ return &vm.internalFunctionSpace();
}
- void finishCreation(JSC::VM& vm)
+ ResolveFunction(
+ JSC::VM& vm,
+ JSC::Structure* structure)
+ : InternalFunction(vm, structure, jsFunctionRequireResolve, nullptr)
{
- Base::finishCreation(vm);
}
};
-const JSC::ClassInfo JSRequireResolveFunction::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSRequireResolveFunction) };
-
-JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+Structure* Zig::ImportMetaObject::createRequireFunctionStructure(VM& vm, JSGlobalObject* globalObject)
{
- JSRequireResolveFunction* thisObject = JSC::jsCast<JSRequireResolveFunction*>(callFrame->jsCallee());
- return functionRequireResolve(globalObject, callFrame, thisObject->from);
-}
-JSValue Zig::ImportMetaObject::createResolveFunctionPrototype(JSC::VM& vm, Zig::GlobalObject* globalObject)
-{
- return JSRequireResolveFunctionPrototype::create(vm, globalObject);
+ return nullptr;
}
-JSC::Structure* Zig::ImportMetaObject::createResolveFunctionStructure(JSC::VM& vm, Zig::GlobalObject* globalObject)
+JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
{
- JSValue prototype = globalObject->requireResolveFunctionPrototype();
- return JSRequireResolveFunction::createStructure(vm, globalObject, prototype);
-}
+ auto* globalObject = lexicalGlobalObject;
+ JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), lexicalGlobalObject);
-JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
-{
- Zig::GlobalObject* thisObject = jsCast<Zig::GlobalObject*>(globalObject);
- return JSValue::encode(thisObject->lazyRequireCacheObject());
-}
+ JSC::JSFunction* requireDotMainFunction = JSFunction::create(
+ vm,
+ moduleMainCodeGenerator(vm),
+ globalObject->globalScope());
-JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter,
- (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
- JSC::EncodedJSValue value, JSC::PropertyName propertyName))
-{
- JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
- if (!thisObject)
- return false;
+ requireFunction->putDirect(
+ vm,
+ JSC::Identifier::fromString(vm, "main"_s),
+ JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, JSValue()),
+ PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
- thisObject->putDirect(globalObject->vm(), propertyName, JSValue::decode(value), 0);
- return true;
-}
+ requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), JSC::constructEmptyObject(globalObject), 0);
+ requireFunction->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter), 0);
+ requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), ResolveFunction::create(globalObject), JSC::PropertyAttribute::Function | 0);
+ requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "path"_s), jsString(vm, pathString));
-JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
-{
- Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(lexicalGlobalObject);
- JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject);
- auto* resolveFunction = JSRequireResolveFunction::create(vm, globalObject->requireResolveFunctionStructure(), pathString);
- auto clientData = WebCore::clientData(vm);
- requireFunction->putDirect(vm, clientData->builtinNames().pathPublicName(), jsString(vm, pathString), PropertyAttribute::DontEnum | 0);
- requireFunction->putDirect(vm, clientData->builtinNames().resolvePublicName(), resolveFunction, PropertyAttribute::Function | PropertyAttribute::DontDelete | 0);
- requireFunction->putDirectCustomAccessor(vm, Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, jsRequireCacheGetter, jsRequireCacheSetter), 0);
return requireFunction;
}
+const JSC::ClassInfo RequireResolveFunctionPrototype::s_info = { "resolve"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RequireResolveFunctionPrototype) };
+const JSC::ClassInfo ResolveFunction::s_info = { "resolve"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ResolveFunction) };
+
extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
{
JSC::VM& vm = globalObject->vm();
@@ -268,7 +266,7 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
case 0: {
// not "requires" because "require" could be confusing
- JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync needs 1 argument (a string)"_s);
+ JSC::throwTypeError(globalObject, scope, "needs 1 argument (a string)"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -276,7 +274,7 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
JSC::JSValue moduleName = callFrame->argument(0);
if (moduleName.isUndefinedOrNull()) {
- JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync expects a string"_s);
+ JSC::throwTypeError(globalObject, scope, "expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -287,27 +285,34 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
if (callFrame->argumentCount() > 1) {
JSC::JSValue fromValue = callFrame->argument(1);
- // require.resolve also supports a paths array
- // we only support a single path
- if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
- if (JSC::JSArray* array = JSC::jsDynamicCast<JSC::JSArray*>(fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s)))) {
- if (array->length() > 0) {
- fromValue = array->getIndex(globalObject, 0);
- }
+ if (callFrame->argumentCount() > 2) {
+ JSC::JSValue isESMValue = callFrame->argument(2);
+ if (isESMValue.isBoolean()) {
+ isESM = isESMValue.toBoolean(globalObject);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
}
+ }
- if (callFrame->argumentCount() > 2) {
- JSC::JSValue isESMValue = callFrame->argument(2);
- if (isESMValue.isBoolean()) {
- isESM = isESMValue.toBoolean(globalObject);
- RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+ if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
+
+ if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
+ if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
+ auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
+ if (pathsArray->length() > 0) {
+ fromValue = pathsArray->getIndex(globalObject, 0);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+ }
}
}
+
} else if (fromValue.isBoolean()) {
isESM = fromValue.toBoolean(globalObject);
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
}
- from = JSC::JSValue::encode(fromValue);
+
+ if (fromValue.isString()) {
+ from = JSC::JSValue::encode(fromValue);
+ }
} else {
JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
@@ -318,8 +323,10 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
}
auto clientData = WebCore::clientData(vm);
+ JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
- from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName()));
+ if (pathProperty && pathProperty.isString())
+ from = JSC::JSValue::encode(pathProperty);
}
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
@@ -362,7 +369,7 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
JSC__JSValue from;
- if (callFrame->argumentCount() > 1) {
+ if (callFrame->argumentCount() > 1 && callFrame->argument(1).isString()) {
from = JSC::JSValue::encode(callFrame->argument(1));
} else {
JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
@@ -374,7 +381,7 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
auto clientData = WebCore::clientData(vm);
- from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName()));
+ from = JSC::JSValue::encode(thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName()));
}
return Bun__resolve(globalObject, JSC::JSValue::encode(moduleName), from, true);
@@ -382,89 +389,235 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
}
}
+enum class ImportMetaPropertyOffset : uint32_t {
+ url,
+ dir,
+ file,
+ path,
+ require,
+
+};
+static constexpr uint32_t numberOfImportMetaProperties = 5;
+
+Zig::ImportMetaObject* ImportMetaObject::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, const WTF::String& url)
+{
+ ImportMetaObject* ptr = new (NotNull, JSC::allocateCell<ImportMetaObject>(vm)) ImportMetaObject(vm, structure, url);
+ ptr->finishCreation(vm);
+ return ptr;
+}
+Zig::ImportMetaObject* ImportMetaObject::create(JSC::JSGlobalObject* jslobalObject, JSC::JSString* keyString)
+{
+ auto* globalObject = jsCast<Zig::GlobalObject*>(jslobalObject);
+ auto& vm = globalObject->vm();
+ auto view = keyString->value(globalObject);
+ JSC::Structure* structure = globalObject->ImportMetaObjectStructure();
+ return Zig::ImportMetaObject::create(vm, globalObject, structure, view);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_url, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+ ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject))
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(thisObject->urlProperty.getInitializedOnMainThread(thisObject));
+}
+JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_dir, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+ ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject))
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(thisObject->dirProperty.getInitializedOnMainThread(thisObject));
+}
+JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_file, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+ ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject))
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(thisObject->fileProperty.getInitializedOnMainThread(thisObject));
+}
+JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_path, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+ ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject))
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(thisObject->pathProperty.getInitializedOnMainThread(thisObject));
+}
+JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_require, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+ ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject))
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(thisObject->requireProperty.getInitializedOnMainThread(thisObject));
+}
+
+static const HashTableValue ImportMetaObjectPrototypeValues[] = {
+ { "resolve"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, functionImportMeta__resolve, 0 } },
+ { "resolveSync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, functionImportMeta__resolveSync, 0 } },
+ { "url"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_url, 0 } },
+ { "dir"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_dir, 0 } },
+ { "file"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_file, 0 } },
+ { "path"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_path, 0 } },
+ { "require"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_require, 0 } },
+};
+
class ImportMetaObjectPrototype final : public JSC::JSNonFinalObject {
public:
+ DECLARE_INFO;
using Base = JSC::JSNonFinalObject;
- static ImportMetaObjectPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
- ImportMetaObjectPrototype* ptr = new (NotNull, JSC::allocateCell<ImportMetaObjectPrototype>(vm)) ImportMetaObjectPrototype(vm, globalObject, structure);
- ptr->finishCreation(vm, globalObject);
- return ptr;
+ return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
+ }
+
+ static ImportMetaObjectPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ ImportMetaObjectPrototype* prototype = new (NotNull, JSC::allocateCell<ImportMetaObjectPrototype>(vm)) ImportMetaObjectPrototype(vm, structure);
+ prototype->finishCreation(vm, globalObject);
+ return prototype;
}
- DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.plainObjectSpace();
}
- static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+
+ void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
- return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ Base::finishCreation(vm);
+
+ auto* clientData = WebCore::clientData(vm);
+ auto& builtinNames = clientData->builtinNames();
+
+ reifyStaticProperties(vm, ImportMetaObject::info(), ImportMetaObjectPrototypeValues, *this);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+
+ this->putDirect(
+ vm,
+ builtinNames.mainPublicName(),
+ GetterSetter::create(vm, globalObject, JSFunction::create(vm, importMetaObjectMainCodeGenerator(vm), globalObject), nullptr),
+ JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin | 0);
}
-private:
- ImportMetaObjectPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ ImportMetaObjectPrototype(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure)
{
}
+};
- void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+const ClassInfo ImportMetaObjectPrototype::s_info = {
+ "ImportMeta"_s,
+
+ Base::info(), nullptr, nullptr, CREATE_METHOD_TABLE(ImportMetaObjectPrototype)
};
-STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ImportMetaObjectPrototype, ImportMetaObjectPrototype::Base);
-JSObject* ImportMetaObject::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+JSC::Structure* ImportMetaObject::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
- return ImportMetaObjectPrototype::create(vm, &globalObject, ImportMetaObjectPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
-}
+ ImportMetaObjectPrototype* prototype = ImportMetaObjectPrototype::create(vm,
+ globalObject,
+ ImportMetaObjectPrototype::createStructure(vm, globalObject));
-void ImportMetaObjectPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject_)
-{
- Base::finishCreation(vm);
- auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject_);
auto clientData = WebCore::clientData(vm);
-
auto& builtinNames = clientData->builtinNames();
- this->putDirect(vm, builtinNames.filePublicName(), jsEmptyString(vm), 0);
- this->putDirect(vm, builtinNames.dirPublicName(), jsEmptyString(vm), 0);
- this->putDirect(vm, builtinNames.pathPublicName(), jsEmptyString(vm), 0);
- this->putDirect(vm, builtinNames.urlPublicName(), jsEmptyString(vm), 0);
-
- this->putDirect(
- vm,
- builtinNames.mainPublicName(),
- GetterSetter::create(vm, globalObject, JSFunction::create(vm, importMetaObjectMainCodeGenerator(vm), globalObject), nullptr),
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin | 0);
-
- this->putDirect(vm, Identifier::fromString(vm, "primordials"_s), jsUndefined(), JSC::PropertyAttribute::DontEnum | 0);
-
- String requireString = "[[require]]"_s;
- this->putDirect(vm, builtinNames.requirePublicName(), Zig::ImportMetaObject::createRequireFunction(vm, globalObject, requireString), PropertyAttribute::Builtin | PropertyAttribute::Function | 0);
-
- this->putDirectNativeFunction(vm, globalObject, builtinNames.resolvePublicName(), 1,
- functionImportMeta__resolve,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::Function | 0);
- this->putDirectNativeFunction(
- vm, globalObject, builtinNames.resolveSyncPublicName(),
- 1,
- functionImportMeta__resolveSync,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::Function | 0);
-
- JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), ImportMetaObject::info());
}
void ImportMetaObject::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
+
+ this->requireProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSFunction>::Initializer& init) {
+ ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
+ JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), meta->url));
+ init.set(value);
+ });
+ this->urlProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
+ ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
+ WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
+
+ init.set(jsString(init.vm, url.string()));
+ });
+ this->dirProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
+ ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
+
+ WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
+ WTF::StringView dirname;
+
+ if (url.protocolIs("file"_s)) {
+ dirname = url.fileSystemPath();
+ } else {
+ dirname = url.path();
+ }
+
+ if (dirname.endsWith("/"_s)) {
+ dirname = dirname.substring(0, dirname.length() - 1);
+ } else if (dirname.contains('/')) {
+ dirname = dirname.substring(0, dirname.reverseFind('/'));
+ }
+
+ init.set(jsString(init.vm, dirname.toString()));
+ });
+ this->fileProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
+ ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
+
+ WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
+ WTF::StringView path;
+ if (url.protocolIs("file"_s)) {
+ path = url.fileSystemPath();
+ } else {
+ path = url.path();
+ }
+
+ WTF::StringView filename;
+
+ if (path.endsWith("/"_s)) {
+ filename = path.substring(path.reverseFind('/', path.length() - 2) + 1);
+ } else {
+ filename = path.substring(path.reverseFind('/') + 1);
+ }
+
+ init.set(jsString(init.vm, filename.toString()));
+ });
+ this->pathProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
+ ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
+
+ WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
+ WTF::StringView path;
+
+ if (url.protocolIs("file"_s)) {
+ path = url.fileSystemPath();
+ } else {
+ path = url.path();
+ }
+
+ init.set(jsString(init.vm, path.toString()));
+ });
}
+template<typename Visitor>
+void ImportMetaObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ ImportMetaObject* fn = jsCast<ImportMetaObject*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(fn, info());
+ Base::visitChildren(fn, visitor);
+
+ fn->requireProperty.visit(visitor);
+ fn->urlProperty.visit(visitor);
+ fn->dirProperty.visit(visitor);
+ fn->fileProperty.visit(visitor);
+ fn->pathProperty.visit(visitor);
+}
+
+DEFINE_VISIT_CHILDREN(ImportMetaObject);
+
void ImportMetaObject::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<ImportMetaObject*>(cell);
@@ -475,9 +628,6 @@ void ImportMetaObject::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
Base::analyzeHeap(cell, analyzer);
}
-const JSC::ClassInfo ImportMetaObjectPrototype::s_info = { "ImportMeta"_s, &Base::s_info, nullptr, nullptr,
- CREATE_METHOD_TABLE(ImportMetaObjectPrototype) };
-
const JSC::ClassInfo ImportMetaObject::s_info = { "ImportMeta"_s, &Base::s_info, nullptr, nullptr,
CREATE_METHOD_TABLE(ImportMetaObject) };
}