diff options
author | 2022-02-24 19:09:55 -0800 | |
---|---|---|
committer | 2022-02-24 19:09:55 -0800 | |
commit | d1eba784b9d902ac6043c1b76e64382d43fbc261 (patch) | |
tree | b711a3f5624817496b0071721634dad8bdc50e4a /src | |
parent | ead77e074d0cfb3d170a243140cce564a4f287a5 (diff) | |
download | bun-d1eba784b9d902ac6043c1b76e64382d43fbc261.tar.gz bun-d1eba784b9d902ac6043c1b76e64382d43fbc261.tar.zst bun-d1eba784b9d902ac6043c1b76e64382d43fbc261.zip |
Add WASM modules but disable it for now
Diffstat (limited to 'src')
23 files changed, 497 insertions, 133 deletions
diff --git a/src/api/schema.d.ts b/src/api/schema.d.ts index 64bd2eff6..d8129fd27 100644 --- a/src/api/schema.d.ts +++ b/src/api/schema.d.ts @@ -21,6 +21,7 @@ export enum Loader { file = 6, json = 7, toml = 8, + wasm = 9, } export const LoaderKeys = { 1: "jsx", @@ -39,6 +40,8 @@ export const LoaderKeys = { json: "json", 8: "toml", toml: "toml", + 9: "wasm", + wasm: "wasm", }; export enum FrameworkEntryPointType { client = 1, diff --git a/src/api/schema.js b/src/api/schema.js index d6dbfe1c3..f2e9b24a5 100644 --- a/src/api/schema.js +++ b/src/api/schema.js @@ -7,6 +7,7 @@ const Loader = { 6: 6, 7: 7, 8: 8, + 9: 9, jsx: 1, js: 2, ts: 3, @@ -15,6 +16,7 @@ const Loader = { file: 6, json: 7, toml: 8, + wasm: 9, }; const LoaderKeys = { 1: "jsx", @@ -25,6 +27,7 @@ const LoaderKeys = { 6: "file", 7: "json", 8: "toml", + 9: "wasm", jsx: "jsx", js: "js", ts: "ts", @@ -33,6 +36,7 @@ const LoaderKeys = { file: "file", json: "json", toml: "toml", + wasm: "wasm", }; const FrameworkEntryPointType = { 1: 1, diff --git a/src/api/schema.peechy b/src/api/schema.peechy index 64f0844b8..59cb1edf5 100644 --- a/src/api/schema.peechy +++ b/src/api/schema.peechy @@ -9,6 +9,7 @@ smol Loader { file = 6; json = 7; toml = 8; + wasm = 9; } smol FrameworkEntryPointType { diff --git a/src/api/schema.zig b/src/api/schema.zig index 7c9344209..61d6b82d1 100644 --- a/src/api/schema.zig +++ b/src/api/schema.zig @@ -356,6 +356,9 @@ pub const Api = struct { /// toml toml, + /// wasm + wasm, + _, pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void { diff --git a/src/bundler.zig b/src/bundler.zig index 9744883cf..f2582e2d4 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -2574,7 +2574,7 @@ pub const Bundler = struct { output_file.value = .{ .move = file_op }; }, - .file => { + .wasm, .file => { var hashed_name = try bundler.linker.getHashedFilename(file_path, null); var pathname = try bundler.allocator.alloc(u8, hashed_name.len + file_path.name.ext.len); std.mem.copy(u8, pathname, hashed_name); @@ -2749,7 +2749,7 @@ pub const Bundler = struct { break :brk logger.Source.initRecycledFile(Fs.File{ .path = path, .contents = entry.contents }, bundler.allocator) catch return null; }; - if (source.contents.len == 0 or (source.contents.len < 33 and std.mem.trim(u8, source.contents, "\n\r ").len == 0)) { + if (loader != .wasm and source.contents.len == 0 and source.contents.len < 33 and std.mem.trim(u8, source.contents, "\n\r ").len == 0) { return ParseResult{ .source = source, .input_fd = input_fd, .loader = loader, .empty = true, .ast = js_ast.Ast.empty }; } @@ -2850,6 +2850,27 @@ pub const Bundler = struct { .input_fd = input_fd, }; }, + .wasm => { + if (bundler.options.platform.isBun()) { + if (source.contents.len < 4 or @bitCast(u32, source.contents[0..4].*) != @bitCast(u32, [4]u8{ 0, 'a', 's', 'm' })) { + bundler.log.addErrorFmt( + null, + logger.Loc.Empty, + bundler.allocator, + "Invalid wasm file \"{s}\" (missing magic header)", + .{path.text}, + ) catch {}; + return null; + } + + return ParseResult{ + .ast = js_ast.Ast.empty, + .source = source, + .loader = loader, + .input_fd = input_fd, + }; + } + }, .css => {}, else => Global.panic("Unsupported loader {s} for path: {s}", .{ loader, source.path.text }), } diff --git a/src/fallback.version b/src/fallback.version index 1705429c4..82270a367 100644 --- a/src/fallback.version +++ b/src/fallback.version @@ -1 +1 @@ -c212be1d3ec811cc
\ No newline at end of file +d570fd92dbb9dbbb
\ No newline at end of file diff --git a/src/install/lockfile.zig b/src/install/lockfile.zig index 974d06258..325f1e96d 100644 --- a/src/install/lockfile.zig +++ b/src/install/lockfile.zig @@ -87,7 +87,10 @@ pub const SmallExternalStringList = ExternalSlice(String); /// The version of the lockfile format, intended to prevent data corruption for format changes. format: FormatVersion = .v1, -/// +/// Not used yet. +/// Eventually, this will be a relative path to a parent lockfile +workspace_path: string = "", + packages: Lockfile.Package.List = Lockfile.Package.List{}, buffers: Buffers = Buffers{}, @@ -146,6 +149,9 @@ pub fn loadFromDisk(this: *Lockfile, allocator: std.mem.Allocator, log: *logger. pub fn loadFromBytes(this: *Lockfile, buf: []u8, allocator: std.mem.Allocator, log: *logger.Log) LoadFromDiskResult { var stream = Stream{ .buffer = buf, .pos = 0 }; + this.workspace_path = ""; + this.format = FormatVersion.current; + Lockfile.Serializer.load(this, &stream, allocator, log) catch |err| { return LoadFromDiskResult{ .err = .{ .step = .parse_file, .value = err } }; }; @@ -2814,6 +2820,11 @@ pub const Serializer = struct { try Lockfile.Buffers.save(this.buffers, z_allocator, StreamType, stream, @TypeOf(&writer), &writer); try writer.writeIntLittle(u64, 0); const end = try stream.getPos(); + + try writer.writeIntLittle(u64, this.workspace_path.len); + if (this.workspace_path.len > 0) + try writer.writeAll(this.workspace_path); + try writer.writeAll(&alignment_bytes_to_repeat_buffer); _ = try std.os.pwrite(stream.handle, std.mem.asBytes(&end), pos); @@ -2854,6 +2865,16 @@ pub const Serializer = struct { return error.@"Lockfile is malformed (expected 0 at the end)"; } std.debug.assert(stream.pos == total_buffer_size); + + load_workspace: { + const workspace_path_len = reader.readIntLittle(u64) catch break :load_workspace; + if (workspace_path_len > 0 and workspace_path_len < std.fs.MAX_PATH_BYTES) { + var workspace_path = try allocator.alloc(u8, workspace_path_len); + const len = reader.readAll(workspace_path) catch break :load_workspace; + lockfile.workspace_path = workspace_path[0..len]; + } + } + lockfile.scratch = Lockfile.Scratch.init(allocator); { diff --git a/src/install/semver.zig b/src/install/semver.zig index bb1e1a8aa..0c0f18e7d 100644 --- a/src/install/semver.zig +++ b/src/install/semver.zig @@ -994,6 +994,16 @@ pub const Range = struct { left: Comparator = Comparator{}, right: Comparator = Comparator{}, + /// * + /// >= 0.0.0 + /// >= 0 + /// >= 0.0 + /// >= x + /// >= 0 + pub fn anyRangeSatisfies(this: *const Range) bool { + return this.left.op == .gte and this.left.version.eql(Version{}); + } + pub fn initWildcard(version: Version, wildcard: Query.Token.Wildcard) Range { switch (wildcard) { .none => { diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 352669b1d..dd9982737 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -94,6 +94,9 @@ extern "C" void JSCInitialize() return; has_loaded_jsc = true; + JSC::Options::useConcurrentJIT() = true; + JSC::Options::useSigillCrashAnalyzer() = true; + JSC::Options::useWebAssembly() = true; JSC::Options::useSourceProviderCache() = true; JSC::Options::useUnlinkedCodeBlockJettisoning() = false; JSC::Options::exposeInternalModuleLoader() = true; @@ -113,9 +116,8 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje Bun::JSVMClientData::create(&vm); vm.heap.acquireAccess(); -#if ENABLE(WEBASSEMBLY) + JSC::Wasm::enableFastMemory(); -#endif JSC::JSLockHolder locker(vm); Zig::GlobalObject* globalObject = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::jsNull())); @@ -237,8 +239,7 @@ static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObjec Zig::GlobalObject* shadow = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::jsNull())); shadow->setConsole(shadow); size_t count = 0; - JSClassRef* globalObjectClass; - globalObjectClass = Zig__getAPIGlobals(&count); + JSClassRef* globalObjectClass = Zig__getAPIGlobals(&count); shadow->setConsole(shadow); if (count > 0) { @@ -620,17 +621,33 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalOb RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); } - auto provider = Zig::SourceProvider::create(res.result.value); + if (res.result.value.tag == 1) { + auto buffer = Vector<uint8_t>(res.result.value.source_code.ptr, res.result.value.source_code.len); + auto source = JSC::SourceCode( + JSC::WebAssemblySourceProvider::create(WTFMove(buffer), + JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(Zig::toString(res.result.value.source_url))), + WTFMove(moduleKey))); + + auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); + RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - auto jsSourceCode = JSC::JSSourceCode::create(vm, JSC::SourceCode(provider)); + promise->resolve(globalObject, sourceCode); + scope.release(); - if (provider.ptr()->isBytecodeCacheEnabled()) { - provider.ptr()->readOrGenerateByteCodeCache(vm, jsSourceCode->sourceCode()); + globalObject->vm().drainMicrotasks(); + return promise; + } else { + auto provider = Zig::SourceProvider::create(res.result.value); + auto jsSourceCode = JSC::JSSourceCode::create(vm, JSC::SourceCode(provider)); + promise->resolve(globalObject, jsSourceCode); } + // if (provider.ptr()->isBytecodeCacheEnabled()) { + // provider.ptr()->readOrGenerateByteCodeCache(vm, jsSourceCode->sourceCode()); + // } + scope.release(); - promise->resolve(globalObject, jsSourceCode); globalObject->vm().drainMicrotasks(); return promise; } diff --git a/src/javascript/jsc/bindings/ZigSourceProvider.cpp b/src/javascript/jsc/bindings/ZigSourceProvider.cpp index 523adbee3..c7394f1cb 100644 --- a/src/javascript/jsc/bindings/ZigSourceProvider.cpp +++ b/src/javascript/jsc/bindings/ZigSourceProvider.cpp @@ -23,10 +23,14 @@ using SourceOrigin = JSC::SourceOrigin; using String = WTF::String; using SourceProviderSourceType = JSC::SourceProviderSourceType; +static char* wasmSourceName = "[WebAssembly Source]"; +static size_t wasmSourceName_len = 20; Ref<SourceProvider> SourceProvider::create(ResolvedSource resolvedSource) { void* allocator = resolvedSource.allocator; + JSC::SourceProviderSourceType sourceType = JSC::SourceProviderSourceType::Module; + WTF::StringImpl* stringImpl = nullptr; if (allocator) { Ref<WTF::ExternalStringImpl> stringImpl_ = WTF::ExternalStringImpl::create( @@ -38,8 +42,7 @@ Ref<SourceProvider> SourceProvider::create(ResolvedSource resolvedSource) resolvedSource, reinterpret_cast<WTF::StringImpl*>(stringImpl_.ptr()), JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(toString(resolvedSource.source_url))), toStringNotConst(resolvedSource.source_url), TextPosition(), - JSC::SourceProviderSourceType::Module)); - + sourceType)); } else { Ref<WTF::ExternalStringImpl> stringImpl_ = WTF::ExternalStringImpl::createStatic( resolvedSource.source_code.ptr, resolvedSource.source_code.len); @@ -47,7 +50,7 @@ Ref<SourceProvider> SourceProvider::create(ResolvedSource resolvedSource) resolvedSource, reinterpret_cast<WTF::StringImpl*>(stringImpl_.ptr()), JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(toString(resolvedSource.source_url))), toStringNotConst(resolvedSource.source_url), TextPosition(), - JSC::SourceProviderSourceType::Module)); + sourceType)); } } @@ -82,8 +85,8 @@ void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, c CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock) { - if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode) - return; + // if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode) + return; JSC::BytecodeCacheError error; RefPtr<JSC::CachedBytecode> cachedBytecode = JSC::encodeFunctionCodeBlock(executable->vm(), codeBlock, error); @@ -93,8 +96,8 @@ void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, c void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator) { - if (!m_resolvedSource.bytecodecache_fd) - return; + // if (!m_resolvedSource.bytecodecache_fd) + return; if (!m_cachedBytecode) m_cachedBytecode = JSC::CachedBytecode::create(); @@ -104,84 +107,86 @@ void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator) } void SourceProvider::commitCachedBytecode() { - if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode || !m_cachedBytecode->hasUpdates()) - return; + // if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode || !m_cachedBytecode->hasUpdates()) + return; - auto clearBytecode = WTF::makeScopeExit([&] { m_cachedBytecode = nullptr; }); - const auto fd = m_resolvedSource.bytecodecache_fd; + // auto clearBytecode = WTF::makeScopeExit([&] { m_cachedBytecode = nullptr; }); + // const auto fd = m_resolvedSource.bytecodecache_fd; - auto fileSize = FileSystem::fileSize(fd); - if (!fileSize) - return; + // auto fileSize = FileSystem::fileSize(fd); + // if (!fileSize) + // return; - size_t cacheFileSize; - if (!WTF::convertSafely(*fileSize, cacheFileSize) || cacheFileSize != m_cachedBytecode->size()) { - // The bytecode cache has already been updated - return; - } + // size_t cacheFileSize; + // if (!WTF::convertSafely(*fileSize, cacheFileSize) || cacheFileSize != m_cachedBytecode->size()) { + // // The bytecode cache has already been updated + // return; + // } - if (!FileSystem::truncateFile(fd, m_cachedBytecode->sizeForUpdate())) - return; + // if (!FileSystem::truncateFile(fd, m_cachedBytecode->sizeForUpdate())) + // return; - m_cachedBytecode->commitUpdates([&](off_t offset, const void* data, size_t size) { - long long result = FileSystem::seekFile(fd, offset, FileSystem::FileSeekOrigin::Beginning); - ASSERT_UNUSED(result, result != -1); - size_t bytesWritten = static_cast<size_t>(FileSystem::writeToFile(fd, data, size)); - ASSERT_UNUSED(bytesWritten, bytesWritten == size); - }); + // m_cachedBytecode->commitUpdates([&](off_t offset, const void* data, size_t size) { + // long long result = FileSystem::seekFile(fd, offset, FileSystem::FileSeekOrigin::Beginning); + // ASSERT_UNUSED(result, result != -1); + // size_t bytesWritten = static_cast<size_t>(FileSystem::writeToFile(fd, data, size)); + // ASSERT_UNUSED(bytesWritten, bytesWritten == size); + // }); } bool SourceProvider::isBytecodeCacheEnabled() const { - return m_resolvedSource.bytecodecache_fd > 0; + // return m_resolvedSource.bytecodecache_fd > 0; + return false; } void SourceProvider::readOrGenerateByteCodeCache(JSC::VM& vm, const JSC::SourceCode& sourceCode) { - auto status = this->readCache(vm, sourceCode); - switch (status) { - case -1: { - m_resolvedSource.bytecodecache_fd = 0; - break; - } - case 0: { - JSC::BytecodeCacheError err; - m_cachedBytecode = JSC::generateModuleBytecode(vm, sourceCode, m_resolvedSource.bytecodecache_fd, err); - - if (err.isValid()) { - m_resolvedSource.bytecodecache_fd = 0; - m_cachedBytecode = JSC::CachedBytecode::create(); - } - } - // TODO: read the bytecode into a JSC::SourceCode object here - case 1: { - } - } + // auto status = this->readCache(vm, sourceCode); + // switch (status) { + // case -1: { + // m_resolvedSource.bytecodecache_fd = 0; + // break; + // } + // case 0: { + // JSC::BytecodeCacheError err; + // m_cachedBytecode = JSC::generateModuleBytecode(vm, sourceCode, m_resolvedSource.bytecodecache_fd, err); + + // if (err.isValid()) { + // m_resolvedSource.bytecodecache_fd = 0; + // m_cachedBytecode = JSC::CachedBytecode::create(); + // } + // } + // // TODO: read the bytecode into a JSC::SourceCode object here + // case 1: { + // } + // } } int SourceProvider::readCache(JSC::VM& vm, const JSC::SourceCode& sourceCode) { - if (m_resolvedSource.bytecodecache_fd == 0) - return -1; - if (!FileSystem::isHandleValid(m_resolvedSource.bytecodecache_fd)) - return -1; - const auto fd = m_resolvedSource.bytecodecache_fd; - - bool success; - FileSystem::MappedFileData mappedFile(fd, FileSystem::MappedFileMode::Shared, success); - if (!success) - return -1; - - const uint8_t* fileData = reinterpret_cast<const uint8_t*>(mappedFile.data()); - unsigned fileTotalSize = mappedFile.size(); - if (fileTotalSize == 0) - return 0; - - Ref<JSC::CachedBytecode> cachedBytecode = JSC::CachedBytecode::create(WTFMove(mappedFile)); - // auto key = JSC::sourceCodeKeyForSerializedModule(vm, sourceCode); - // if (isCachedBytecodeStillValid(vm, cachedBytecode.copyRef(), key, - // JSC::SourceCodeType::ModuleType)) { - m_cachedBytecode = WTFMove(cachedBytecode); - return 1; + return -1; + // if (m_resolvedSource.bytecodecache_fd == 0) + // return -1; + // if (!FileSystem::isHandleValid(m_resolvedSource.bytecodecache_fd)) + // return -1; + // const auto fd = m_resolvedSource.bytecodecache_fd; + + // bool success; + // FileSystem::MappedFileData mappedFile(fd, FileSystem::MappedFileMode::Shared, success); + // if (!success) + // return -1; + + // const uint8_t* fileData = reinterpret_cast<const uint8_t*>(mappedFile.data()); + // unsigned fileTotalSize = mappedFile.size(); + // if (fileTotalSize == 0) + // return 0; + + // Ref<JSC::CachedBytecode> cachedBytecode = JSC::CachedBytecode::create(WTFMove(mappedFile)); + // // auto key = JSC::sourceCodeKeyForSerializedModule(vm, sourceCode); + // // if (isCachedBytecodeStillValid(vm, cachedBytecode.copyRef(), key, + // // JSC::SourceCodeType::ModuleType)) { + // m_cachedBytecode = WTFMove(cachedBytecode); + // return 1; // } else { // FileSystem::truncateFile(fd, 0); // return 0; diff --git a/src/javascript/jsc/bindings/ZigSourceProvider.h b/src/javascript/jsc/bindings/ZigSourceProvider.h index 3a1a73b8f..fc584db6f 100644 --- a/src/javascript/jsc/bindings/ZigSourceProvider.h +++ b/src/javascript/jsc/bindings/ZigSourceProvider.h @@ -45,11 +45,11 @@ public: StringView source() const { return StringView(m_source.get()); } RefPtr<JSC::CachedBytecode> cachedBytecode() { - if (m_resolvedSource.bytecodecache_fd == 0) { - return nullptr; - } + // if (m_resolvedSource.bytecodecache_fd == 0) { + return nullptr; + // } - return m_cachedBytecode; + // return m_cachedBytecode; }; void updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&, @@ -73,6 +73,7 @@ private: m_resolvedSource = resolvedSource; m_hash = resolvedSource.hash; + getHash(); } diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp index 589a19293..83e311b43 100644 --- a/src/javascript/jsc/bindings/bindings.cpp +++ b/src/javascript/jsc/bindings/bindings.cpp @@ -979,13 +979,35 @@ bool JSC__JSInternalPromise__isHandled(const JSC__JSInternalPromise* arg0, JSC__ return arg0->isHandled(reinterpret_cast<JSC::VM&>(arg1)); } -JSC__JSInternalPromise* JSC__JSInternalPromise__then(JSC__JSInternalPromise* arg0, - JSC__JSGlobalObject* arg1, - JSC__JSFunction* arg2, JSC__JSFunction* arg3) -{ - return arg0->then(arg1, arg2, arg3); -} +// static JSC::JSFunction* nativeFunctionCallback(JSC__JSGlobalObject* globalObject, void* ctx, JSC__JSValue (*Callback)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3)); + +// static JSC::JSFunction* nativeFunctionCallback(JSC__JSGlobalObject* globalObject, void* ctx, JSC__JSValue (*Callback)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3)) +// { +// return JSC::JSNativeStdFunction::create( +// globalObject->vm(), globalObject, 1, String(), [&ctx, &Callback](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue { +// size_t argumentCount = callFrame->argumentCount(); +// Vector<JSC__JSValue, 16> arguments; +// arguments.reserveInitialCapacity(argumentCount); +// for (size_t i = 0; i < argumentCount; ++i) +// arguments.uncheckedAppend(JSC::JSValue::encode(callFrame->uncheckedArgument(i))); + +// return Callback(ctx, globalObject, arguments.data(), argumentCount); +// }); +// } + +// JSC__JSInternalPromise* JSC__JSInternalPromise__then_(JSC__JSInternalPromise* promise, JSC__JSGlobalObject* global, void* resolveCtx, JSC__JSValue (*onResolve)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3), void* arg4, JSC__JSValue (*ArgFn5)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3)) +// { +// return promise->then(global, nativeFunctionCallback(global, resolveCtx, onResolve), nativeFunctionCallback(global, arg4, ArgFn5)); +// } +// JSC__JSInternalPromise* JSC__JSInternalPromise__thenReject_(JSC__JSInternalPromise* promise, JSC__JSGlobalObject* global, void* arg2, JSC__JSValue (*ArgFn3)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3)) +// { +// return promise->then(global, nullptr, nativeFunctionCallback(global, arg2, ArgFn3)); +// } +// JSC__JSInternalPromise* JSC__JSInternalPromise__thenResolve_(JSC__JSInternalPromise* promise, JSC__JSGlobalObject* global, void* arg2, JSC__JSValue (*ArgFn3)(void* arg0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3)) +// { +// return promise->then(global, nativeFunctionCallback(global, arg2, ArgFn3), nullptr); +// } // bool JSC__JSPromise__isInternal(JSC__JSPromise* arg0, JSC__VM* arg1) { // return arg0->inf // } @@ -2067,9 +2089,8 @@ JSC__VM* JSC__VM__create(unsigned char HeapType0) auto& vm = JSC::VM::create(HeapType0 == 0 ? JSC::HeapType::Small : JSC::HeapType::Large, nullptr) .leakRef(); -#if ENABLE(WEBASSEMBLY) + JSC::Wasm::enableFastMemory(); -#endif g_commonVMOrNull = &vm; vm.heap.acquireAccess(); // At any time, we may do things that affect the GC. diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index 8687352fc..6fabeeb17 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -602,6 +602,21 @@ pub const JSModuleLoader = extern struct { }; }; +pub fn PromiseCallback(comptime Type: type, comptime CallbackFunction: fn (*Type, *JSGlobalObject, []const JSValue) anyerror!JSValue) type { + return struct { + pub fn callback( + ctx: ?*anyopaque, + globalThis: *JSGlobalObject, + arguments: [*]const JSValue, + arguments_len: usize, + ) callconv(.C) JSValue { + return CallbackFunction(@ptrCast(*Type, @alignCast(@alignOf(*Type), ctx.?)), globalThis, arguments[0..arguments_len]) catch |err| brk: { + break :brk ZigString.init(std.mem.span(@errorName(err))).toErrorInstance(globalThis); + }; + } + }.callback; +} + pub const JSModuleRecord = extern struct { pub const shim = Shimmer("JSC", "JSModuleRecord", @This()); bytes: shim.Bytes, @@ -742,10 +757,150 @@ pub const JSInternalPromise = extern struct { pub fn rejectAsHandledException(this: *JSInternalPromise, globalThis: *JSGlobalObject, value: *Exception) void { cppFn("rejectAsHandledException", .{ this, globalThis, value }); } + // pub const PromiseCallbackPrimitive = fn ( + // ctx: ?*anyopaque, + // globalThis: *JSGlobalObject, + // arguments: [*]const JSValue, + // arguments_len: usize, + // ) callconv(.C) JSValue; + // pub fn then_( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // resolve_ctx: ?*anyopaque, + // onResolve: PromiseCallbackPrimitive, + // reject_ctx: ?*anyopaque, + // onReject: PromiseCallbackPrimitive, + // ) *JSInternalPromise { + // return cppFn("then_", .{ this, globalThis, resolve_ctx, onResolve, reject_ctx, onReject }); + // } - pub fn then(this: *JSInternalPromise, globalThis: *JSGlobalObject, resolvefunc: ?*JSFunction, rejectfunc: ?*JSFunction) *JSInternalPromise { - return cppFn("then", .{ this, globalThis, resolvefunc, rejectfunc }); - } + // pub const Completion = struct { + // result: []const JSValue, + // global: *JSGlobalObject, + // resolved: bool = false, + + // pub const PromiseTask = struct { + // frame: @Frame(JSInternalPromise._wait), + // completion: Completion, + + // pub fn onResolve(this: *PromiseTask, global: *JSGlobalObject, arguments: []const JSValue) anyerror!JSValue { + // this.completion.global = global; + // this.completion.resolved = true; + // this.completion.result = arguments; + + // return resume this.frame; + // } + + // pub fn onReject(this: *PromiseTask, global: *JSGlobalObject, arguments: []const JSValue) anyerror!JSValue { + // this.completion.global = global; + // this.completion.resolved = false; + // this.completion.result = arguments; + // return resume this.frame; + // } + // }; + // }; + + // pub fn _wait( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // internal: *Completion.PromiseTask, + // ) void { + // this.then( + // globalThis, + // Completion.PromiseTask, + // internal, + // Completion.PromiseTask.onResolve, + // Completion.PromiseTask, + // internal, + // Completion.PromiseTask.onReject, + // ); + + // suspend { + // internal.frame = @frame().*; + // } + // } + + // pub fn wait( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // allocator: std.mem.Allocator, + // ) callconv(.Async) anyerror!Completion { + // var internal = try allocator.create(Completion.PromiseTask); + // defer allocator.destroy(internal); + // internal.* = Completion.Internal{ + // .frame = undefined, + // .completion = Completion{ + // .global = globalThis, + // .resolved = false, + // .result = &[_]JSValue{}, + // }, + // }; + + // this._wait(globalThis, internal); + + // return internal.completion; + // } + + // pub fn then( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // comptime Resolve: type, + // resolver: *Resolve, + // comptime onResolve: fn (*Resolve, *JSGlobalObject, []const JSValue) anyerror!JSValue, + // comptime Reject: type, + // rejecter: *Reject, + // comptime onReject: fn (*Reject, *JSGlobalObject, []const JSValue) anyerror!JSValue, + // ) *JSInternalPromise { + // return then_(this, globalThis, resolver, PromiseCallback(Resolve, onResolve), Reject, rejecter, PromiseCallback(Reject, onReject)); + // } + + // pub fn thenResolve( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // comptime Resolve: type, + // resolver: *Resolve, + // comptime onResolve: fn (*Resolve, *JSGlobalObject, []const JSValue) anyerror!JSValue, + // ) *JSInternalPromise { + // return thenResolve_(this, globalThis, resolver, PromiseCallback(Resolve, onResolve)); + // } + + // pub fn thenResolve_( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // resolve_ctx: ?*anyopaque, + // onResolve: PromiseCallbackPrimitive, + // ) *JSInternalPromise { + // return cppFn("thenResolve_", .{ + // this, + // globalThis, + // resolve_ctx, + // onResolve, + // }); + // } + + // pub fn thenReject_( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // resolve_ctx: ?*anyopaque, + // onResolve: PromiseCallbackPrimitive, + // ) *JSInternalPromise { + // return cppFn("thenReject_", .{ + // this, + // globalThis, + // resolve_ctx, + // onResolve, + // }); + // } + + // pub fn thenReject( + // this: *JSInternalPromise, + // globalThis: *JSGlobalObject, + // comptime Resolve: type, + // resolver: *Resolve, + // comptime onResolve: fn (*Resolve, *JSGlobalObject, []const JSValue) anyerror!JSValue, + // ) *JSInternalPromise { + // return thenReject_(this, globalThis, resolver, PromiseCallback(Resolve, onResolve)); + // } pub fn create(globalThis: *JSGlobalObject) *JSInternalPromise { return cppFn("create", .{globalThis}); @@ -753,7 +908,7 @@ pub const JSInternalPromise = extern struct { pub const Extern = [_][]const u8{ "create", - "then", + // "then_", "rejectWithCaughtException", "status", "result", @@ -763,6 +918,8 @@ pub const JSInternalPromise = extern struct { "resolve", "reject", "rejectAsHandled", + // "thenResolve_", + // "thenReject_", // "rejectException", "rejectAsHandledException", }; diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig index a7d281299..c18482641 100644 --- a/src/javascript/jsc/bindings/exports.zig +++ b/src/javascript/jsc/bindings/exports.zig @@ -225,8 +225,12 @@ pub const ResolvedSource = extern struct { allocator: ?*anyopaque, - // 0 means disabled - bytecodecache_fd: u64, + tag: Tag = Tag.javascript, + + pub const Tag = enum(u64) { + javascript = 0, + wasm = 1, + }; }; export fn ZigString__free(ptr: [*]const u8, len: usize, allocator_: ?*anyopaque) void { diff --git a/src/javascript/jsc/bindings/header-gen.zig b/src/javascript/jsc/bindings/header-gen.zig index 9a9b9314f..64adb5a99 100644 --- a/src/javascript/jsc/bindings/header-gen.zig +++ b/src/javascript/jsc/bindings/header-gen.zig @@ -325,10 +325,23 @@ pub const C_Generator = struct { self: *Self, comptime T: type, ) void { - const TT = comptime if (@typeInfo(T) == .Pointer and !std.meta.trait.isManyItemPtr(T)) @typeInfo(T).Pointer.child else T; + const TT = comptime brk: { + var Type = T; + if (@typeInfo(Type) == .Optional) { + const OtherType = std.meta.Child(Type); + if (@typeInfo(OtherType) == .Fn) { + Type = OtherType; + } + } + if (@typeInfo(Type) == .Pointer and !std.meta.trait.isManyItemPtr(Type)) { + Type = @typeInfo(Type).Pointer.child; + } + + break :brk Type; + }; if (comptime (isCppObject(TT)) and @hasDecl(TT, "name")) { - if (@typeInfo(T) == .Pointer or @hasDecl(TT, "Type") and @typeInfo(TT.Type) == .Pointer) { + if (@typeInfo(T) == .Pointer or (@hasDecl(TT, "Type") and (@TypeOf(TT.Type) == type and @typeInfo(TT.Type) == .Pointer))) { if (@hasDecl(TT, "is_pointer") and !TT.is_pointer) {} else if (@typeInfo(T).Pointer.is_const) { write(self, "const "); } @@ -377,7 +390,7 @@ pub const C_Generator = struct { write(self, comptime formatted_name); } - if (@typeInfo(T) == .Pointer or @hasDecl(TT, "Type") and @typeInfo(TT.Type) == .Pointer) { + if (@typeInfo(T) == .Pointer or (@hasDecl(TT, "Type") and (@TypeOf(TT.Type) == type and @typeInfo(TT.Type) == .Pointer))) { if (@hasDecl(TT, "is_pointer") and !TT.is_pointer) {} else { write(self, "*"); } diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index f99e629e7..3a3800139 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1645667010 +//-- AUTOGENERATED FILE -- 1645755471 // clang-format off #pragma once diff --git a/src/javascript/jsc/bindings/headers-handwritten.h b/src/javascript/jsc/bindings/headers-handwritten.h index 6a92f1666..56d5c0773 100644 --- a/src/javascript/jsc/bindings/headers-handwritten.h +++ b/src/javascript/jsc/bindings/headers-handwritten.h @@ -24,7 +24,7 @@ typedef struct ResolvedSource { ZigString source_url; uint32_t hash; void* allocator; - uint64_t bytecodecache_fd; + uint64_t tag; } ResolvedSource; typedef union ErrorableResolvedSourceResult { ResolvedSource value; diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index c7d4cf21b..aa100ee4b 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format: off -//-- AUTOGENERATED FILE -- 1645667010 +//-- AUTOGENERATED FILE -- 1645755471 #pragma once #include <stddef.h> @@ -324,7 +324,6 @@ CPP_DECL void JSC__JSInternalPromise__resolve(JSC__JSInternalPromise* arg0, JSC_ CPP_DECL JSC__JSInternalPromise* JSC__JSInternalPromise__resolvedPromise(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1); CPP_DECL JSC__JSValue JSC__JSInternalPromise__result(const JSC__JSInternalPromise* arg0, JSC__VM* arg1); CPP_DECL uint32_t JSC__JSInternalPromise__status(const JSC__JSInternalPromise* arg0, JSC__VM* arg1); -CPP_DECL JSC__JSInternalPromise* JSC__JSInternalPromise__then(JSC__JSInternalPromise* arg0, JSC__JSGlobalObject* arg1, JSC__JSFunction* arg2, JSC__JSFunction* arg3); #pragma mark - JSC::SourceOrigin @@ -695,6 +694,7 @@ ZIG_DECL JSC__JSValue Bun__Path__resolve(JSC__JSGlobalObject* arg0, bool arg1, J #ifdef __cplusplus +ZIG_DECL void Bun__Process__exit(JSC__JSGlobalObject* arg0, int32_t arg1); ZIG_DECL JSC__JSValue Bun__Process__getArgv(JSC__JSGlobalObject* arg0); ZIG_DECL JSC__JSValue Bun__Process__getCwd(JSC__JSGlobalObject* arg0); ZIG_DECL void Bun__Process__getTitle(JSC__JSGlobalObject* arg0, ZigString* arg1); diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig index 6b235bbdb..93169276e 100644 --- a/src/javascript/jsc/bindings/headers.zig +++ b/src/javascript/jsc/bindings/headers.zig @@ -189,7 +189,6 @@ pub extern fn JSC__JSInternalPromise__resolve(arg0: [*c]JSC__JSInternalPromise, pub extern fn JSC__JSInternalPromise__resolvedPromise(arg0: [*c]JSC__JSGlobalObject, JSValue1: JSC__JSValue) [*c]JSC__JSInternalPromise; pub extern fn JSC__JSInternalPromise__result(arg0: [*c]const JSC__JSInternalPromise, arg1: [*c]JSC__VM) JSC__JSValue; pub extern fn JSC__JSInternalPromise__status(arg0: [*c]const JSC__JSInternalPromise, arg1: [*c]JSC__VM) u32; -pub extern fn JSC__JSInternalPromise__then(arg0: [*c]JSC__JSInternalPromise, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]JSC__JSFunction, arg3: [*c]JSC__JSFunction) [*c]JSC__JSInternalPromise; pub extern fn JSC__SourceOrigin__fromURL(arg0: [*c]const WTF__URL) bJSC__SourceOrigin; pub extern fn JSC__SourceCode__fromString(arg0: [*c]JSC__SourceCode, arg1: [*c]const WTF__String, arg2: [*c]const JSC__SourceOrigin, arg3: [*c]WTF__String, SourceType4: u8) void; pub extern fn JSC__JSFunction__calculatedDisplayName(arg0: [*c]JSC__JSFunction, arg1: [*c]JSC__VM) bWTF__String; diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig index b843b7c57..a6a85c4db 100644 --- a/src/javascript/jsc/javascript.zig +++ b/src/javascript/jsc/javascript.zig @@ -76,6 +76,7 @@ const Exception = @import("../../jsc.zig").Exception; const ErrorableZigString = @import("../../jsc.zig").ErrorableZigString; const ZigGlobalObject = @import("../../jsc.zig").ZigGlobalObject; const VM = @import("../../jsc.zig").VM; +const JSFunction = @import("../../jsc.zig").JSFunction; const Config = @import("./config.zig"); const URL = @import("../../query_string_map.zig").URL; const Transpiler = @import("./api/transpiler.zig"); @@ -1466,11 +1467,12 @@ pub fn ConcurrentPromiseTask(comptime Context: type) type { }; } const AsyncTransformTask = @import("./api/transpiler.zig").TransformTask.AsyncTransformTask; +// const PromiseTask = JSInternalPromise.Completion.PromiseTask; pub const Task = TaggedPointerUnion(.{ FetchTasklet, Microtask, AsyncTransformTask, - + // PromiseTask, // TimeoutTasklet, }); @@ -1525,18 +1527,19 @@ pub const VirtualMachine = struct { return this.event_loop; } - const EventLoop = struct { + pub const EventLoop = struct { ready_tasks_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0), pending_tasks_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0), io_tasks_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0), tasks: Queue = undefined, concurrent_tasks: Queue = undefined, concurrent_lock: Lock = Lock.init(), + global: *JSGlobalObject = undefined, pub const Queue = std.fifo.LinearFifo(Task, .Dynamic); pub fn tickWithCount(this: *EventLoop) u32 { var finished: u32 = 0; - var global = VirtualMachine.vm.global; + var global = this.global; while (this.tasks.readItem()) |task| { switch (task.tag()) { .Microtask => { @@ -1640,6 +1643,7 @@ pub const VirtualMachine = struct { if (!this.has_enabled_macro_mode) { this.has_enabled_macro_mode = true; this.macro_event_loop.tasks = EventLoop.Queue.init(default_allocator); + this.macro_event_loop.global = this.global; this.macro_event_loop.concurrent_tasks = EventLoop.Queue.init(default_allocator); } @@ -1658,6 +1662,8 @@ pub const VirtualMachine = struct { } pub fn getAPIGlobals() []js.JSClassRef { + if (is_bindgen) + return &[_]js.JSClassRef{}; var classes = default_allocator.alloc(js.JSClassRef, GlobalClasses.len) catch return &[_]js.JSClassRef{}; inline for (GlobalClasses) |Class, i| { classes[i] = Class.get().*; @@ -1734,6 +1740,7 @@ pub const VirtualMachine = struct { @intCast(i32, global_classes.len), vm.console, ); + VirtualMachine.vm.regular_event_loop.global = VirtualMachine.vm.global; VirtualMachine.vm_loaded = true; if (!source_code_printer_loaded) { @@ -1793,10 +1800,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(bun_file_import_path), .source_url = ZigString.init(bun_file_import_path[1..]), .hash = 0, // TODO - .bytecodecache_fd = std.math.lossyCast(u64, vm.node_modules.?.fetchByteCodeCache( - bun_file_import_path[1..], - &vm.bundler.fs.fs, - ) orelse 0), }; } else if (vm.node_modules == null and strings.eqlComptime(_specifier, Runtime.Runtime.Imports.Name)) { return ResolvedSource{ @@ -1805,7 +1808,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(Runtime.Runtime.Imports.Name), .source_url = ZigString.init(Runtime.Runtime.Imports.Name), .hash = Runtime.Runtime.versionHash(), - .bytecodecache_fd = 0, }; // This is all complicated because the imports have to be linked and we want to run the printer on it // so it consistently handles bundled imports @@ -1869,7 +1871,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(std.mem.span(main_file_name)), .source_url = ZigString.init(std.mem.span(main_file_name)), .hash = 0, - .bytecodecache_fd = 0, }; } else if (_specifier.len > js_ast.Macro.namespaceWithColon.len and strings.eqlComptimeIgnoreLen(_specifier[0..js_ast.Macro.namespaceWithColon.len], js_ast.Macro.namespaceWithColon)) @@ -1881,7 +1882,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(_specifier), .source_url = ZigString.init(_specifier), .hash = 0, - .bytecodecache_fd = 0, }; } } else if (strings.eqlComptime(_specifier, "node:fs")) { @@ -1891,7 +1891,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init("node:fs"), .source_url = ZigString.init("node:fs"), .hash = 0, - .bytecodecache_fd = 0, }; } else if (strings.eqlComptime(_specifier, "node:path")) { return ResolvedSource{ @@ -1900,7 +1899,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init("node:path"), .source_url = ZigString.init("node:path"), .hash = 0, - .bytecodecache_fd = 0, }; } @@ -2011,9 +2009,49 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(specifier), .source_url = ZigString.init(path.text), .hash = 0, - .bytecodecache_fd = 0, }; }, + // .wasm => { + // vm.transpiled_count += 1; + // var fd: ?StoredFileDescriptorType = null; + + // var allocator = if (vm.has_loaded) vm.arena.allocator() else vm.allocator; + + // const hash = http.Watcher.getHash(path.text); + // if (vm.watcher) |watcher| { + // if (watcher.indexOf(hash)) |index| { + // const _fd = watcher.watchlist.items(.fd)[index]; + // fd = if (_fd > 0) _fd else null; + // } + // } + + // var parse_options = Bundler.ParseOptions{ + // .allocator = allocator, + // .path = path, + // .loader = loader, + // .dirname_fd = 0, + // .file_descriptor = fd, + // .file_hash = hash, + // .macro_remappings = MacroRemap{}, + // .jsx = vm.bundler.options.jsx, + // }; + + // var parse_result = vm.bundler.parse( + // parse_options, + // null, + // ) orelse { + // return error.ParseError; + // }; + + // return ResolvedSource{ + // .allocator = if (vm.has_loaded) &vm.allocator else null, + // .source_code = ZigString.init(vm.allocator.dupe(u8, parse_result.source.contents) catch unreachable), + // .specifier = ZigString.init(specifier), + // .source_url = ZigString.init(path.text), + // .hash = 0, + // .tag = ResolvedSource.Tag.wasm, + // }; + // }, else => { return ResolvedSource{ .allocator = &vm.allocator, @@ -2021,7 +2059,6 @@ pub const VirtualMachine = struct { .specifier = ZigString.init(path.text), .source_url = ZigString.init(path.text), .hash = 0, - .bytecodecache_fd = 0, }; }, } diff --git a/src/javascript/jsc/node/types.zig b/src/javascript/jsc/node/types.zig index 1174257ab..6ee9bd293 100644 --- a/src/javascript/jsc/node/types.zig +++ b/src/javascript/jsc/node/types.zig @@ -1275,6 +1275,13 @@ pub const Writable = struct { pub const Chunk = struct { data: StringOrBuffer, encoding: Encoding = Encoding.utf8, + + pub fn init(allocator: std.mem.Allocator, size: u32) !Chunk { + var bytes = try allocator.alloc(u8, size); + return Chunk{ + .data = JSC.ArrayBuffer.fromBytes(bytes, JSC.JSValue.JSType.Uint8Array), + }; + } }; pub const Pipe = struct { @@ -1403,6 +1410,20 @@ pub const Writable = struct { } } + // fn runGeneric(this: *Pipe, pipeline: *Pipeline) !void { + // var source = this.source; + // var destination = this.destination; + // const source_content_type = source.content_type; + // const destination_content_type = destination.content_type; + + // if (this.chunk == null) { + // this.chunk = try this.source.allocator.create(Chunk); + // this.chunk.?.* = try Chunk.init(this.source.allocator, this.source.sink.readable.state.highwater_mark); + // } + + // source.readInto + // } + pub fn run(this: *Pipe, pipeline: *Pipeline) void { var source = this.source; var destination = this.destination; @@ -2160,7 +2181,12 @@ pub const Path = struct { return std.fs.path.isAbsoluteWindows(zig_str.slice()); } - pub fn join(globalThis: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [*]JSC.JSValue, args_len: u16) callconv(.C) JSC.JSValue { + pub fn join( + globalThis: *JSC.JSGlobalObject, + isWindows: bool, + args_ptr: [*]JSC.JSValue, + args_len: u16, + ) callconv(.C) JSC.JSValue { if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); if (args_len == 0) return JSC.ZigString.init("").toValue(globalThis); @@ -2445,6 +2471,7 @@ pub const Process = struct { const slice = to.sliceZBuf(&buf) catch { return JSC.toInvalidArguments("Invalid path", .{}, globalObject.ref()); }; + const result = Syscall.chdir(slice); switch (result) { @@ -2455,16 +2482,24 @@ pub const Process = struct { // When we update the cwd from JS, we have to update the bundler's version as well // However, this might be called many times in a row, so we use a pre-allocated buffer // that way we don't have to worry about garbage collector - var trimmed = std.mem.trimRight(u8, buf[0..slice.len], std.fs.path.sep_str); - buf[trimmed.len] = std.fs.path.sep; - const with_trailing_slash = buf[0 .. trimmed.len + 1]; - std.mem.copy(u8, &JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf, with_trailing_slash); - JSC.VirtualMachine.vm.bundler.fs.top_level_dir = JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf[0..with_trailing_slash.len]; + JSC.VirtualMachine.vm.bundler.fs.top_level_dir = std.os.getcwd(&JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf) catch { + _ = Syscall.chdir(std.meta.assumeSentinel(JSC.VirtualMachine.vm.bundler.fs.top_level_dir, 0)); + return JSC.toInvalidArguments("Invalid path", .{}, globalObject.ref()); + }; + + JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf[JSC.VirtualMachine.vm.bundler.fs.top_level_dir.len] = std.fs.path.sep; + JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf[JSC.VirtualMachine.vm.bundler.fs.top_level_dir.len + 1] = 0; + JSC.VirtualMachine.vm.bundler.fs.top_level_dir = JSC.VirtualMachine.vm.bundler.fs.top_level_dir_buf[0 .. JSC.VirtualMachine.vm.bundler.fs.top_level_dir.len + 1]; + return JSC.JSValue.jsUndefined(); }, } } + pub fn exit(_: *JSC.JSGlobalObject, code: i32) callconv(.C) void { + std.os.exit(@truncate(u8, @intCast(u32, @maximum(code, 0)))); + } + pub export const Bun__version: [:0]const u8 = "v" ++ _global.Global.package_json_version; pub export const Bun__versions_mimalloc: [:0]const u8 = _global.Global.versions.mimalloc; pub export const Bun__versions_webkit: [:0]const u8 = _global.Global.versions.webkit; diff --git a/src/linker.zig b/src/linker.zig index 8ac15ddd7..b82fa03ec 100644 --- a/src/linker.zig +++ b/src/linker.zig @@ -259,6 +259,12 @@ pub const Linker = struct { continue; } + // if (strings.eqlComptime(import_record.path.text, "process") or strings.eqlComptime(import_record.path.text, "node:process")) { + // import_record.path.text = "node:process"; + // externals.append(record_index) catch unreachable; + // continue; + // } + // TODO: this is technical debt if (linker.options.rewrite_jest_for_tests) { if (strings.eqlComptime( @@ -744,7 +750,7 @@ pub const Linker = struct { import_record.path = try linker.generateImportPath( source_dir, if (path.is_symlink and import_path_format == .absolute_url and linker.options.platform.isNotBun()) path.pretty else path.text, - loader == .file, + loader == .file or loader == .wasm, path.namespace, origin, import_path_format, @@ -758,7 +764,7 @@ pub const Linker = struct { // This saves us a less reliable string check import_record.print_mode = .css; }, - .file => { + .wasm, .file => { import_record.print_mode = .import_path; }, else => {}, diff --git a/src/options.zig b/src/options.zig index 0e532e5e3..f1ba76ad2 100644 --- a/src/options.zig +++ b/src/options.zig @@ -442,7 +442,7 @@ pub const Platform = enum { pub inline fn supportsBrowserField(this: Platform) bool { return switch (this) { - .neutral, .browser => true, + .neutral, .browser, .bun, .bun_macro => true, else => false, }; } @@ -630,6 +630,7 @@ pub const Loader = enum(u4) { file, json, toml, + wasm, pub const Map = std.EnumArray(Loader, string); pub const stdin_name: Map = brk: { var map = Map.initFill(""); @@ -641,6 +642,7 @@ pub const Loader = enum(u4) { map.set(Loader.file, "input"); map.set(Loader.json, "input.json"); map.set(Loader.toml, "input.toml"); + map.set(Loader.wasm, "input.wasm"); break :brk map; }; @@ -661,7 +663,7 @@ pub const Loader = enum(u4) { if (zig_str.len == 0) return null; return fromString(zig_str.slice()) orelse { - JSC.throwInvalidArguments("invalid loader – must be js, jsx, tsx, ts, css, file, toml, or json", .{}, global.ref(), exception); + JSC.throwInvalidArguments("invalid loader – must be js, jsx, tsx, ts, css, file, toml, wasm, or json", .{}, global.ref(), exception); return null; }; } @@ -682,6 +684,7 @@ pub const Loader = enum(u4) { LoaderMatcher.case("file") => Loader.file, LoaderMatcher.case("json") => Loader.json, LoaderMatcher.case("toml") => Loader.toml, + LoaderMatcher.case("wasm") => Loader.wasm, else => null, }; } @@ -702,6 +705,7 @@ pub const Loader = enum(u4) { .css => .css, .json => .json, .toml => .toml, + .wasm => .wasm, else => .file, }; } @@ -751,6 +755,7 @@ pub const defaultLoaders = std.ComptimeStringMap(Loader, .{ .{ ".cts", Loader.ts }, .{ ".toml", Loader.toml }, + .{ ".wasm", Loader.wasm }, }); // https://webpack.js.org/guides/package-exports/#reference-syntax @@ -1037,6 +1042,7 @@ pub fn loadersFromTransformOptions(allocator: std.mem.Allocator, _loaders: ?Api. .tsx => Loader.tsx, .json => Loader.json, .toml => Loader.toml, + .wasm => Loader.wasm, else => unreachable, }; @@ -1058,7 +1064,7 @@ pub fn loadersFromTransformOptions(allocator: std.mem.Allocator, _loaders: ?Api. ".ts", ".tsx", ".mts", ".cts", - ".toml", + ".toml", ".wasm", }; inline for (default_loader_ext) |ext| { |