aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/ImportMetaObject.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-07-01 03:22:23 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-07-01 03:22:23 -0700
commite105cfcca8ec86464c33501861d506ec529882b5 (patch)
tree0b6cc50b59697273d4220298cacb745614c08e8b /src/bun.js/bindings/ImportMetaObject.cpp
parentf2569c8c6ed7ce10451005dcc61e4a2d8807e869 (diff)
downloadbun-e105cfcca8ec86464c33501861d506ec529882b5.tar.gz
bun-e105cfcca8ec86464c33501861d506ec529882b5.tar.zst
bun-e105cfcca8ec86464c33501861d506ec529882b5.zip
Zig::ImportMeta
Diffstat (limited to 'src/bun.js/bindings/ImportMetaObject.cpp')
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
new file mode 100644
index 000000000..dc4290c91
--- /dev/null
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -0,0 +1,249 @@
+#include "root.h"
+#include "ImportMetaObject.h"
+#include "ZigGlobalObject.h"
+#include "ActiveDOMObject.h"
+#include "ExtendedDOMClientIsoSubspaces.h"
+#include "ExtendedDOMIsoSubspaces.h"
+#include "IDLTypes.h"
+// #include "JSBlob.h"
+#include "JSDOMAttribute.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructor.h"
+#include "JSDOMConvertBase.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMGlobalObject.h"
+#include "JSDOMGlobalObjectInlines.h"
+#include "JSDOMOperation.h"
+#include "JSDOMWrapperCache.h"
+#include "ScriptExecutionContext.h"
+#include "WebCoreJSClientData.h"
+#include "JavaScriptCore/FunctionPrototype.h"
+#include "JavaScriptCore/HeapAnalyzer.h"
+
+#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h"
+#include "JavaScriptCore/SlotVisitorMacros.h"
+#include "JavaScriptCore/SubspaceInlines.h"
+#include "wtf/GetPtr.h"
+#include "wtf/PointerPreparations.h"
+#include "wtf/URL.h"
+#include "JavaScriptCore/BuiltinNames.h"
+
+#include "JSBufferEncodingType.h"
+#include "JSBufferPrototypeBuiltins.h"
+#include "JSBufferConstructorBuiltins.h"
+#include "JavaScriptCore/JSBase.h"
+
+namespace Zig {
+using namespace JSC;
+using namespace WebCore;
+
+extern "C" JSC__JSValue Bun__resolve(JSC::JSGlobalObject* global, JSC__JSValue specifier, JSC__JSValue from);
+extern "C" JSC__JSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC__JSValue specifier, JSC__JSValue from);
+
+static JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync);
+
+static JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolveSync,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ JSC::VM& vm = globalObject->vm();
+
+ switch (callFrame->argumentCount()) {
+ case 0: {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ // not "requires" because "require" could be confusing
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync needs 1 argument (a string)"_s);
+ scope.release();
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ default: {
+ JSC::JSValue moduleName = callFrame->argument(0);
+
+ if (moduleName.isUndefinedOrNull()) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync expects a string"_s);
+ scope.release();
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSC__JSValue from;
+
+ 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);
+ }
+ }
+ }
+ from = JSC::JSValue::encode(fromValue);
+ } else {
+ JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync must be bound to an import.meta object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto clientData = WebCore::clientData(vm);
+
+ from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName()));
+ }
+
+ auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from);
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+
+ if (!JSC::JSValue::decode(result).isString()) {
+ JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ scope.release();
+ return result;
+ }
+ }
+}
+
+static JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolve);
+
+static JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ JSC::VM& vm = globalObject->vm();
+
+ switch (callFrame->argumentCount()) {
+ case 0: {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ // not "requires" because "require" could be confusing
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolve needs 1 argument (a string)"_s);
+ scope.release();
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ default: {
+ JSC::JSValue moduleName = callFrame->argument(0);
+
+ if (moduleName.isUndefinedOrNull()) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolve expects a string"_s);
+ scope.release();
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSC__JSValue from;
+
+ if (callFrame->argumentCount() > 1) {
+ from = JSC::JSValue::encode(callFrame->argument(1));
+ } else {
+ JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolve must be bound to an import.meta object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto clientData = WebCore::clientData(vm);
+
+ from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName()));
+ }
+
+ return Bun__resolve(globalObject, JSC::JSValue::encode(moduleName), from);
+ }
+ }
+}
+
+class ImportMetaObjectPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+
+ static ImportMetaObjectPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ ImportMetaObjectPrototype* ptr = new (NotNull, JSC::allocateCell<ImportMetaObjectPrototype>(vm)) ImportMetaObjectPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm, globalObject);
+ return ptr;
+ }
+
+ 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)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ ImportMetaObjectPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ImportMetaObjectPrototype, ImportMetaObjectPrototype::Base);
+
+JSObject* ImportMetaObject::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return ImportMetaObjectPrototype::create(vm, &globalObject, ImportMetaObjectPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+void ImportMetaObjectPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject_)
+{
+ Base::finishCreation(vm);
+ auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject_);
+ auto clientData = WebCore::clientData(vm);
+
+ this->putDirect(vm, clientData->builtinNames().filePublicName(), jsEmptyString(vm), 0);
+ this->putDirect(vm, clientData->builtinNames().dirPublicName(), jsEmptyString(vm), 0);
+ this->putDirect(vm, clientData->builtinNames().pathPublicName(), jsEmptyString(vm), 0);
+ this->putDirect(vm, clientData->builtinNames().urlPublicName(), jsEmptyString(vm), 0);
+ this->putDirect(vm, clientData->builtinNames().mainPublicName(), jsBoolean(false), 0);
+ this->putDirectBuiltinFunction(vm, globalObject,
+ clientData->builtinNames().requirePublicName(), importMetaObjectRequireCodeGenerator(vm), 0);
+ this->putDirectBuiltinFunction(vm, globalObject,
+ clientData->builtinNames().loadModulePublicName(), importMetaObjectLoadModuleCodeGenerator(vm), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0);
+ this->putDirectBuiltinFunction(vm, globalObject,
+ clientData->builtinNames().requireModulePublicName(), importMetaObjectRequireModuleCodeGenerator(vm), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0);
+
+ this->putDirectNativeFunction(vm, globalObject, clientData->builtinNames().resolvePublicName(), 1,
+ functionImportMeta__resolve,
+ NoIntrinsic,
+ JSC::PropertyAttribute::Function | 0);
+ this->putDirectNativeFunction(
+ vm, globalObject, clientData->builtinNames().resolveSyncPublicName(),
+ 1,
+ functionImportMeta__resolveSync,
+ NoIntrinsic,
+ JSC::PropertyAttribute::Function | 0);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+void ImportMetaObject::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+void ImportMetaObject::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<ImportMetaObject*>(cell);
+ // if (void* wrapped = thisObject->wrapped()) {
+ // if (thisObject->scriptExecutionContext())
+ // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ // }
+ 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) };
+
+}