aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-03 00:18:26 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-03 00:18:26 -0700
commit6142715c06d5eb3dbaa07901a6281ae1394483a9 (patch)
treec549d8597ba4f89b1e3a19efdcd2351297d5b5cb /src/bun.js
parent34e130a3e0cb251cb163071b75228c6d521edf95 (diff)
downloadbun-6142715c06d5eb3dbaa07901a6281ae1394483a9.tar.gz
bun-6142715c06d5eb3dbaa07901a6281ae1394483a9.tar.zst
bun-6142715c06d5eb3dbaa07901a6281ae1394483a9.zip
Introduce `import.meta.primordials` for builtin JS
the `import.meta` object in Bun now has a `primordials` object which makes a handful of globals safe for access. Inside of bun: or node: modules, it is a special object (ownKeys is not implemented, so Object.keys() wont work on it) - Array - String - `isPromise` - `isCallable` - `isConstructable` - `tryGetById(foo, "bar')` which is like foo?.bar - `arrayPush` which is like `Array.prototype.push` - `Bun` - `isAbortSignal` cc @ThatOneBro @lawrencecchen
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp1
-rw-r--r--src/bun.js/bindings/ImportMetaObject.h3
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp87
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h3
4 files changed, 91 insertions, 3 deletions
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index 17338da5c..cdd00ced2 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -319,6 +319,7 @@ void ImportMetaObjectPrototype::finishCreation(VM& vm, JSGlobalObject* globalObj
this->putDirect(vm, builtinNames.pathPublicName(), jsEmptyString(vm), 0);
this->putDirect(vm, builtinNames.urlPublicName(), jsEmptyString(vm), 0);
this->putDirect(vm, builtinNames.mainPublicName(), jsBoolean(false), 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);
diff --git a/src/bun.js/bindings/ImportMetaObject.h b/src/bun.js/bindings/ImportMetaObject.h
index ac50df12d..920d4f74f 100644
--- a/src/bun.js/bindings/ImportMetaObject.h
+++ b/src/bun.js/bindings/ImportMetaObject.h
@@ -67,6 +67,9 @@ public:
if (view.startsWith('/')) {
metaProperties->putDirect(vm, builtinNames.urlPublicName(), JSC::JSValue(JSC::jsString(vm, WTF::URL::fileURLWithFileSystemPath(view).string())));
} else {
+ if (view.startsWith("node:"_s) || view.startsWith("bun:"_s)) {
+ metaProperties->putDirect(globalObject->vm(), JSC::Identifier::fromString(globalObject->vm(), "primordials"_s), reinterpret_cast<Zig::GlobalObject*>(globalObject)->primordialsObject());
+ }
metaProperties->putDirect(vm, builtinNames.urlPublicName(), keyString);
}
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 637a06ed8..481fe8aeb 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -89,7 +89,6 @@
#include "JSStringDecoder.h"
#include "JSReadableState.h"
#include "JSReadableHelper.h"
-
#include "Process.h"
#include "WebCoreJSBuiltinInternals.h"
@@ -1940,6 +1939,81 @@ JSC_DEFINE_HOST_FUNCTION(functionReadableStreamToArrayBuffer, (JSGlobalObject *
return ZigGlobalObject__readableStreamToArrayBufferBody(reinterpret_cast<Zig::GlobalObject*>(globalObject), JSValue::encode(readableStreamValue));
}
+class BunPrimordialsObject final : public JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | GetOwnPropertySlotMayBeWrongAboutDontEnum;
+ static BunPrimordialsObject* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ BunPrimordialsObject* ptr = new (NotNull, JSC::allocateCell<BunPrimordialsObject>(vm)) BunPrimordialsObject(vm, globalObject, structure);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(BunPrimordialsObject, Base);
+ 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());
+ }
+
+ static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
+ {
+ JSC::VM& vm = globalObject->vm();
+
+ auto str = String(propertyName.publicName());
+ SymbolImpl* symbol = vm.propertyNames->builtinNames().lookUpPrivateName(str);
+ if (!symbol) {
+ return false;
+ }
+
+ auto identifier = JSC::Identifier::fromUid(vm, symbol);
+ if (auto value = globalObject->getIfPropertyExists(globalObject, identifier)) {
+ slot.setValue(globalObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly, value);
+ return true;
+ } else if (auto value = vm.bytecodeIntrinsicRegistry().lookup(identifier)) {
+ auto name = identifier.string();
+ String functionText;
+ bool isFunction = false;
+ // this is...terrible code
+ if (name.characters8()[0] >= 'A' && name.characters8()[0] <= 'Z') {
+ functionText = makeString("(function () { return @"_s, name, ";\n})\n"_s);
+ } else if (name.characters8()[0] == 'p' || name.characters8()[0] == 't' || name.characters8()[0] == 'g') {
+ isFunction = true;
+ functionText = makeString("(function (arg1, arg2) { return @"_s, name, "(arg1, arg2);\n})\n"_s);
+ } else {
+ isFunction = true;
+ functionText = makeString("(function (arg1) { return @"_s, name, "(arg1);\n})\n"_s);
+ }
+
+ SourceCode source = makeSource(WTFMove(functionText), {});
+ JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, name), ImplementationVisibility::Public, ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
+
+ slot.setValue(
+ globalObject,
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | 0,
+ isFunction ? JSValue(func) : JSC::call(globalObject, func, JSC::getCallData(func), globalObject, JSC::MarkedArgumentBuffer()));
+
+ return true;
+ }
+ return false;
+ }
+
+ DECLARE_INFO
+
+ BunPrimordialsObject(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+ : JSC::JSNonFinalObject(vm, structure)
+ {
+ }
+};
+
+const ClassInfo BunPrimordialsObject::s_info = { "Primordials"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(BunPrimordialsObject) };
+
void GlobalObject::finishCreation(VM& vm)
{
Base::finishCreation(vm);
@@ -1992,6 +2066,14 @@ void GlobalObject::finishCreation(VM& vm)
toJSNewlyCreated<IDLInterface<SubtleCrypto>>(*init.owner, global, WTFMove(crypto)).getObject());
});
+ m_primordialsObject.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
+ auto& global = *reinterpret_cast<Zig::GlobalObject*>(init.owner);
+ BunPrimordialsObject* object = BunPrimordialsObject::create(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.owner),
+ BunPrimordialsObject::createStructure(init.vm, init.owner, init.owner->objectPrototype()));
+ init.set(object);
+ });
+
m_NapiClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
init.setStructure(Zig::NapiClass::createStructure(init.vm, init.global, init.global->functionPrototype()));
@@ -2563,8 +2645,6 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "SubtleCrypto"_s), JSC::CustomGetterSetter::create(vm, getterSubtleCryptoConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CryptoKey"_s), JSC::CustomGetterSetter::create(vm, getterCryptoKeyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- // putDirect(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().nativeReadableStreamPrototypePrivateName(), jsUndefined(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum | 0);
}
// We set it in here since it's a global
@@ -2824,6 +2904,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_performanceObject.visit(visitor);
thisObject->m_navigatorObject.visit(visitor);
thisObject->m_subtleCryptoObject.visit(visitor);
+ thisObject->m_primordialsObject.visit(visitor);
thisObject->m_JSHTTPResponseSinkClassStructure.visit(visitor);
thisObject->m_JSHTTPSResponseSinkClassStructure.visit(visitor);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index e91cf86bf..6863f72af 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -219,6 +219,7 @@ public:
JSC::JSObject* encodeIntoObjectPrototype() { return m_encodeIntoObjectPrototype.getInitializedOnMainThread(this); }
JSC::JSObject* performanceObject() { return m_performanceObject.getInitializedOnMainThread(this); }
+ JSC::JSObject* primordialsObject() { return m_primordialsObject.getInitializedOnMainThread(this); }
JSC::JSObject* processObject()
{
@@ -417,6 +418,8 @@ private:
LazyClassStructure m_JSReadableStateClassStructure;
LazyClassStructure m_OnigurumaRegExpClassStructure;
+ LazyProperty<JSGlobalObject, JSObject> m_primordialsObject;
+
LazyProperty<JSGlobalObject, JSObject> m_navigatorObject;
LazyProperty<JSGlobalObject, JSObject> m_JSArrayBufferControllerPrototype;