Compare commits

...

11 Commits

Author SHA1 Message Date
Dylan Conway
6e803d428e update for cmake 2023-11-04 22:14:55 -07:00
Dylan Conway
8311a1886b Merge branch 'main' into sdl 2023-11-04 16:00:16 -07:00
Dylan Conway
202bd070f1 Merge branch 'main' into sdl 2023-10-21 17:21:43 -07:00
Dylan Conway
f9add8b6be Merge branch 'main' into sdl 2023-10-14 12:58:30 -07:00
Dylan Conway
81a1a58d66 hex colors 2023-10-09 21:16:44 -07:00
Dylan Conway
06957242d4 keep color in u32 2023-10-09 03:31:25 -07:00
Dylan Conway
07edcc426e rename 2023-10-09 02:00:51 -07:00
Dylan Conway
43c84ffb43 2d rendering context 2023-10-09 00:52:03 -07:00
Dylan Conway
89d494c5ed canvas class 2023-10-07 18:55:59 -07:00
Dylan Conway
dd7b47a30e checkout SDL 2.28.4 2023-10-07 13:06:57 -07:00
Dylan Conway
12700e5f7b add sdl 2023-10-07 13:05:40 -07:00
22 changed files with 1394 additions and 18 deletions

4
.gitmodules vendored
View File

@@ -75,4 +75,6 @@ url = https://github.com/aklomp/base64.git
ignore = dirty
depth = 1
shallow = true
fetchRecurseSubmodules = false
[submodule "src/deps/SDL"]
path = src/deps/SDL
url = https://github.com/libsdl-org/SDL

View File

@@ -229,6 +229,7 @@ option(USE_CUSTOM_MIMALLOC "Use Bun's recommended version of Mimalloc" ON)
option(USE_CUSTOM_ZSTD "Use Bun's recommended version of zstd" ON)
option(USE_CUSTOM_CARES "Use Bun's recommended version of c-ares" ON)
option(USE_CUSTOM_BASE64 "Use Bun's recommended version of libbase64" ON)
option(USE_CUSTOM_SDL2 "Use Bun's recommended version of SDL2" ON)
option(USE_CUSTOM_LOLHTML "Use Bun's recommended version of lolhtml" ON)
option(USE_CUSTOM_TINYCC "Use Bun's recommended version of tinycc" ON)
option(USE_CUSTOM_LIBUV "Use Bun's recommended version of libuv (Windows only)" ON)
@@ -1139,6 +1140,19 @@ else()
target_link_libraries(${bun} PRIVATE base64::base64)
endif()
if(USE_CUSTOM_SDL2)
include_directories(${BUN_DEPS_DIR}/SDL/include)
if(WIN32)
target_link_libraries(${bun} PRIVATE "${BUN_DEPS_OUT_DIR}/SDL2.lib")
else()
target_link_libraries(${bun} PRIVATE "${BUN_DEPS_OUT_DIR}/libSDL2.a")
endif()
else()
find_package(SDL2 REQUIRED)
target_link_libraries(${bun} PRIVATE SDL2::SDL2)
endif()
if(NOT WIN32)
if(USE_CUSTOM_TINYCC)
if(WIN32)

View File

@@ -455,6 +455,7 @@ ARCHIVE_FILES_WITHOUT_LIBCRYPTO = $(MINIMUM_ARCHIVE_FILES) \
-lusockets \
-lcares \
-lzstd \
-lSDL2 \
$(BUN_DEPS_OUT_DIR)/libuwsockets.o
ARCHIVE_FILES = $(ARCHIVE_FILES_WITHOUT_LIBCRYPTO)
@@ -1878,6 +1879,11 @@ base64:
cd $(BUN_DEPS_DIR)/base64 && make clean && rm -rf CMakeCache.txt CMakeFiles && cmake $(CMAKE_FLAGS) . && make
cp $(BUN_DEPS_DIR)/base64/libbase64.a $(BUN_DEPS_OUT_DIR)/libbase64.a
.PHONY: sdl
sdl:
cd $(BUN_DEPS_DIR)/SDL && ./configure && make
cp $(BUN_DEPS_DIR)/SDL/build/.libs/libSDL2.a $(BUN_DEPS_OUT_DIR)/libSDL2.a
.PHONY: cold-jsc-start
cold-jsc-start:
$(CXX_WITH_CCACHE) $(CLANG_FLAGS) \
@@ -1895,7 +1901,7 @@ cold-jsc-start:
misctools/cold-jsc-start.cpp -o cold-jsc-start
.PHONY: vendor-without-npm
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares zstd base64
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares zstd base64 sdl
.PHONY: vendor-without-check

View File

@@ -4,6 +4,7 @@ const std = @import("std");
const pathRel = std.fs.path.relative;
const Wyhash = @import("./src/wyhash.zig").Wyhash;
const LazyPath = std.Build.LazyPath;
var is_debug_build = false;
fn moduleSource(comptime out: []const u8) FileSource {
if (comptime std.fs.path.dirname(@src().file)) |base| {
@@ -288,6 +289,8 @@ pub fn build_(b: *Build) !void {
.main_mod_path = .{ .cwd_relative = b.pathFromRoot(".") },
});
obj.addIncludePath(LazyPath.relative("./src/deps/SDL/include"));
if (!exists(b.pathFromRoot(try std.fs.path.join(b.allocator, &.{
"src",
"js_lexer",

View File

@@ -62,6 +62,7 @@ dep mimalloc libmimalloc.a libmimalloc.o
dep tinycc libtcc.a
dep zlib libz.a
dep zstd libzstd.a
dep SDL2 libSDL2.a
if [ "$BUILT_ANY" -eq 0 ]; then
printf "(run with -f to rebuild)\n"

10
scripts/build-SDL2.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euxo pipefail
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
cd $BUN_DEPS_DIR/SDL
rm -rf build
./configure && make
cp build/.libs/libSDL2.a $BUN_DEPS_OUT_DIR/libSDL2.a

View File

@@ -57,6 +57,7 @@ pub const BunObject = struct {
pub const SHA512_256 = Crypto.SHA512_256.getter;
pub const TOML = Bun.getTOMLObject;
pub const Transpiler = Bun.getTranspilerConstructor;
pub const Canvas = Bun.getCanvasConstructor;
pub const argv = Bun.getArgv;
pub const assetPrefix = Bun.getAssetPrefix;
pub const cwd = Bun.getCWD;
@@ -102,6 +103,7 @@ pub const BunObject = struct {
@export(BunObject.SHA512_256, .{ .name = getterName("SHA512_256") });
@export(BunObject.TOML, .{ .name = getterName("TOML") });
@export(BunObject.Transpiler, .{ .name = getterName("Transpiler") });
@export(BunObject.Canvas, .{ .name = getterName("Canvas") });
@export(BunObject.argv, .{ .name = getterName("argv") });
@export(BunObject.assetPrefix, .{ .name = getterName("assetPrefix") });
@export(BunObject.cwd, .{ .name = getterName("cwd") });
@@ -2827,6 +2829,13 @@ pub fn getTranspilerConstructor(
return JSC.API.JSTranspiler.getConstructor(globalThis);
}
pub fn getCanvasConstructor(
globalThis: *JSC.JSGlobalObject,
_: *JSC.JSObject,
) callconv(.C) JSC.JSValue {
return JSC.API.Canvas.getConstructor(globalThis);
}
pub fn getFileSystemRouter(
globalThis: *JSC.JSGlobalObject,
_: *JSC.JSObject,
@@ -3743,6 +3752,7 @@ pub const Timer = struct {
return TimerObject.init(globalThis, id, .setTimeout, interval, wrappedCallback, arguments);
}
pub fn setInterval(
globalThis: *JSGlobalObject,
callback: JSValue,
@@ -3767,10 +3777,9 @@ pub const Timer = struct {
return TimerObject.init(globalThis, id, .setInterval, interval, wrappedCallback, arguments);
}
pub fn clearTimer(timer_id_value: JSValue, globalThis: *JSGlobalObject, repeats: bool) void {
pub fn clearTimer(timer_id_value: JSValue, globalThis: *JSGlobalObject, kind: Timeout.Kind) void {
JSC.markBinding(@src());
const kind: Timeout.Kind = if (repeats) .setInterval else .setTimeout;
var vm = globalThis.bunVM();
var map = vm.timer.maps.get(kind);
@@ -3809,16 +3818,26 @@ pub const Timer = struct {
id: JSValue,
) callconv(.C) JSValue {
JSC.markBinding(@src());
Timer.clearTimer(id, globalThis, false);
return JSValue.jsUndefined();
Timer.clearTimer(id, globalThis, .setTimeout);
return .undefined;
}
pub fn clearImmediate(
globalThis: *JSGlobalObject,
id: JSValue,
) callconv(.C) JSValue {
JSC.markBinding(@src());
Timer.clearTimer(id, globalThis, .setImmediate);
return .undefined;
}
pub fn clearInterval(
globalThis: *JSGlobalObject,
id: JSValue,
) callconv(.C) JSValue {
JSC.markBinding(@src());
Timer.clearTimer(id, globalThis, true);
return JSValue.jsUndefined();
Timer.clearTimer(id, globalThis, .setInterval);
return .undefined;
}
const Shimmer = @import("../bindings/shimmer.zig").Shimmer;

View File

@@ -0,0 +1,76 @@
import { define } from "../../codegen/class-definitions";
export default [
define({
name: "Canvas",
construct: true,
finalize: true,
hasPendingActivity: true,
configurable: false,
klass: {},
JSType: "0b11101110",
proto: {
width: {
getter: "getWidth",
setter: "setWidth",
},
height: {
getter: "getHeight",
setter: "setHeight",
},
x: {
getter: "getX",
setter: "setX",
},
y: {
getter: "getY",
setter: "setY",
},
animate: {
fn: "animate",
length: 1,
},
close: {
fn: "close",
length: 0,
},
getContext: {
fn: "getContext",
length: 1,
},
},
}),
define({
name: "CanvasRenderingContext2D",
construct: true,
finalize: false,
configurable: false,
klass: {},
JSType: "0b11101110",
proto: {
canvas: {
getter: "getCanvas",
},
strokeStyle: {
getter: "getStrokeStyle",
setter: "setStrokeStyle",
},
fillStyle: {
getter: "getFillStyle",
setter: "setFillStyle",
},
clearRect: {
fn: "clearRect",
length: 4,
},
fillRect: {
fn: "fillRect",
length: 4,
},
strokeRect: {
fn: "strokeRect",
length: 4,
},
},
}),
];

1183
src/bun.js/api/canvas.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@
macro(SHA512_256) \
macro(TOML) \
macro(Transpiler) \
macro(Canvas) \
macro(argv) \
macro(assetPrefix) \
macro(cwd) \

View File

@@ -577,6 +577,7 @@ JSC_DEFINE_HOST_FUNCTION(functionHashCode,
SHA512_256 BunObject_getter_wrap_SHA512_256 DontDelete|PropertyCallback
TOML BunObject_getter_wrap_TOML DontDelete|PropertyCallback
Transpiler BunObject_getter_wrap_Transpiler DontDelete|PropertyCallback
Canvas BunObject_getter_wrap_Canvas DontDelete|PropertyCallback
_Os BunObject_callback__Os DontEnum|DontDelete|Function 1
_Path BunObject_callback__Path DontEnum|DontDelete|Function 1
allocUnsafe BunObject_callback_allocUnsafe DontDelete|Function 1

View File

@@ -55,4 +55,6 @@ pub const Classes = struct {
pub const DebugHTTPSServer = JSC.API.DebugHTTPSServer;
pub const Crypto = JSC.WebCore.Crypto;
pub const FFI = JSC.FFI;
pub const Canvas = JSC.API.Canvas;
pub const CanvasRenderingContext2D = JSC.API.CanvasRenderingContext2D;
};

View File

@@ -44,6 +44,7 @@ static constexpr ASCIILiteral builtinModuleNamesSortedLength[] = {
"_tls_wrap"_s,
"constants"_s,
"inspector"_s,
"bun:canvas"_s,
"bun:sqlite"_s,
"path/posix"_s,
"path/win32"_s,

View File

@@ -2076,6 +2076,7 @@ pub const ModuleLoader = struct {
.@"node:util/types" => return jsSyntheticModule(.@"node:util/types", specifier),
.@"node:constants" => return jsSyntheticModule(.@"node:constants", specifier),
.@"bun:jsc" => return jsSyntheticModule(.@"bun:jsc", specifier),
.@"bun:canvas" => return jsSyntheticModule(.@"bun:canvas", specifier),
// These are defined in src/js/*
.@"bun:ffi" => return jsSyntheticModule(.@"bun:ffi", specifier),
@@ -2251,6 +2252,7 @@ pub const HardcodedModule = enum {
bun,
@"bun:ffi",
@"bun:jsc",
@"bun:canvas",
@"bun:main",
@"bun:sqlite",
@"detect-libc",
@@ -2324,6 +2326,7 @@ pub const HardcodedModule = enum {
.{ "bun", HardcodedModule.bun },
.{ "bun:ffi", HardcodedModule.@"bun:ffi" },
.{ "bun:jsc", HardcodedModule.@"bun:jsc" },
.{ "bun:canvas", HardcodedModule.@"bun:canvas" },
.{ "bun:main", HardcodedModule.@"bun:main" },
.{ "bun:sqlite", HardcodedModule.@"bun:sqlite" },
.{ "detect-libc", HardcodedModule.@"detect-libc" },
@@ -2535,6 +2538,7 @@ pub const HardcodedModule = enum {
.{ "bun", .{ .path = "bun", .tag = .bun } },
.{ "bun:ffi", .{ .path = "bun:ffi" } },
.{ "bun:jsc", .{ .path = "bun:jsc" } },
.{ "bun:canvas", .{ .path = "bun:canvas" } },
.{ "bun:sqlite", .{ .path = "bun:sqlite" } },
.{ "bun:wrap", .{ .path = "bun:wrap" } },
.{ "ffi", .{ .path = "bun:ffi" } },

View File

@@ -0,0 +1,24 @@
// #include "DOMPoint.h"
// #include "JSDOMConstructor.h"
// #include "JSDOMGlobalObjectInlines.h"
#include "ZigGeneratedClasses.h"
#include "_NativeModule.h"
namespace Zig {
using namespace WebCore;
DEFINE_NATIVE_MODULE(BunCanvas) {
INIT_NATIVE_MODULE(1);
put(Identifier::fromString(vm, "Canvas"_s),
globalObject->JSCanvasConstructor());
// put(Identifier::fromString(vm, "Path2D"_s),
// getDOMConstructor<JSDOMConstructor<JSPath2D>,
// DOMConstructorID::Path2D>(
// vm, globalObject));
RETURN_NATIVE_MODULE();
}
} // namespace Zig

View File

@@ -2,10 +2,10 @@
#include "CommonJSModuleRecord.h"
#include "ImportMetaObject.h"
#include <JavaScriptCore/JSBoundFunction.h>
#include <JavaScriptCore/ObjectConstructor.h>
#include "_NativeModule.h"
#include "isBuiltinModule.h"
#include <JavaScriptCore/JSBoundFunction.h>
#include <JavaScriptCore/ObjectConstructor.h>
using namespace Zig;
using namespace JSC;
@@ -34,6 +34,7 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
"bun"_s,
"bun:ffi"_s,
"bun:jsc"_s,
"bun:canvas"_s,
"bun:sqlite"_s,
"bun:wrap"_s,
"child_process"_s,
@@ -189,7 +190,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
vm, globalObject, val)));
}
extern "C" JSC::EncodedJSValue Resolver__nodeModulePathsForJS(JSGlobalObject *,
CallFrame *);
CallFrame *);
JSC_DEFINE_HOST_FUNCTION(jsFunctionFindSourceMap,
(JSGlobalObject * globalObject,

View File

@@ -33,6 +33,7 @@
macro("node:string_decoder"_s, NodeStringDecoder) \
macro("node:util/types"_s, NodeUtilTypes) \
macro("utf-8-validate"_s, UTF8Validate) \
macro("bun:canvas"_s, BunCanvas) \
#if ASSERT_ENABLED

1
src/deps/SDL Submodule

Submodule src/deps/SDL added at cc016b0046

View File

@@ -45,6 +45,8 @@ pub const API = struct {
pub const TCPSocket = @import("./bun.js/api/bun/socket.zig").TCPSocket;
pub const TLSSocket = @import("./bun.js/api/bun/socket.zig").TLSSocket;
pub const Listener = @import("./bun.js/api/bun/socket.zig").Listener;
pub const Canvas = @import("./bun.js/api/canvas.zig").Canvas;
pub const CanvasRenderingContext2D = @import("./bun.js/api/canvas.zig").CanvasRenderingContext2D;
};
pub const DNS = @import("./bun.js/api/bun/dns_resolver.zig");
pub const FFI = @import("./bun.js/api/ffi.zig").FFI;

View File

@@ -787,6 +787,8 @@ pub const String = extern struct {
}
pub fn indexOfComptimeArrayCaseInsensitiveSameLength(this: String, comptime values: []const []const u8) ?usize {
if (values.len == 0) return null;
if (this.is8Bit()) {
const bytes = this.byteSlice();

View File

@@ -4442,18 +4442,40 @@ pub const StringArrayByIndexSorter = struct {
}
};
pub fn isASCIIHexDigit(c: u8) bool {
return std.ascii.isHex(c);
pub fn toASCIILowerUnchecked(comptime T: type, character: T) T {
return character | 0x20;
}
pub fn toASCIIHexValue(character: u8) u8 {
if (comptime Environment.allow_assert) std.debug.assert(isASCIIHexDigit(character));
pub fn isASCIIDigit(comptime T: type, character: T) bool {
return character >= '0' and character <= '9';
}
pub fn isASCIIHexDigit(comptime T: type, digit: T) bool {
return (digit >= '0' and digit <= '9') or (toASCIILowerUnchecked(T, digit) >= 'a' and toASCIILowerUnchecked(T, digit) <= 'f');
}
pub fn toASCIIHexValue(comptime T: type, _character: T) u8 {
if (comptime Environment.allow_assert) {
std.debug.assert(isASCIIHexDigit(T, _character));
}
const character: u8 = @intCast(_character);
return switch (character) {
0...('A' - 1) => character - '0',
else => (character - 'A' + 10) & 0xF,
};
}
pub fn isASCIIWhitespace(comptime T: type, character: T) bool {
return character == ' ' or character == '\n' or character == '\t' or character == '\r' or character == 0x0C;
}
pub fn isASCIIAlphaCaselessEqual(comptime T: type, character: T, expectedASCIILowercaseLetter: u8) bool {
if (comptime Environment.allow_assert) {
std.debug.assert(toASCIILowerUnchecked(T, expectedASCIILowercaseLetter) == expectedASCIILowercaseLetter);
}
return toASCIILowerUnchecked(T, character) == expectedASCIILowercaseLetter;
}
pub inline fn utf8ByteSequenceLength(first_byte: u8) u3 {
return switch (first_byte) {
0b0000_0000...0b0111_1111 => 1,

View File

@@ -841,7 +841,7 @@ pub const PercentEncoding = struct {
switch (input[i]) {
'%' => {
if (comptime fault_tolerant) {
if (!(i + 3 <= input.len and strings.isASCIIHexDigit(input[i + 1]) and strings.isASCIIHexDigit(input[i + 2]))) {
if (!(i + 3 <= input.len and strings.isASCIIHexDigit(u8, input[i + 1]) and strings.isASCIIHexDigit(u8, input[i + 2]))) {
// i do not feel good about this
// create-react-app's public/index.html uses %PUBLIC_URL% in various tags
// This is an invalid %-encoded string, intended to be swapped out at build time by webpack-html-plugin
@@ -858,11 +858,11 @@ pub const PercentEncoding = struct {
return error.DecodingError;
}
} else {
if (!(i + 3 <= input.len and strings.isASCIIHexDigit(input[i + 1]) and strings.isASCIIHexDigit(input[i + 2])))
if (!(i + 3 <= input.len and strings.isASCIIHexDigit(u8, input[i + 1]) and strings.isASCIIHexDigit(u8, input[i + 2])))
return error.DecodingError;
}
try writer.writeByte((strings.toASCIIHexValue(input[i + 1]) << 4) | strings.toASCIIHexValue(input[i + 2]));
try writer.writeByte((strings.toASCIIHexValue(u8, input[i + 1]) << 4) | strings.toASCIIHexValue(u8, input[i + 2]));
i += 3;
written += 1;
continue;