mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
[misctools] Add cold jsc start test
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -116,3 +116,6 @@ src/bun.js/debug-bindings-obj
|
||||
failing-tests.txt
|
||||
test.txt
|
||||
myscript.sh
|
||||
|
||||
cold-jsc-start
|
||||
cold-jsc-start.d
|
||||
|
||||
16
Makefile
16
Makefile
@@ -1827,6 +1827,22 @@ copy-to-bun-release-dir-bin:
|
||||
PACKAGE_MAP = --pkg-begin async_io $(BUN_DIR)/src/io/io_darwin.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end
|
||||
|
||||
|
||||
.PHONY: cold-jsc-start
|
||||
cold-jsc-start:
|
||||
$(CXX_WITH_CCACHE) $(CLANG_FLAGS) \
|
||||
$(MACOS_MIN_FLAG) \
|
||||
$(OPTIMIZATION_LEVEL) \
|
||||
-MMD \
|
||||
-fno-exceptions \
|
||||
-fno-rtti \
|
||||
-ferror-limit=1000 \
|
||||
$(LIBICONV_PATH) \
|
||||
$(DEFAULT_LINKER_FLAGS) \
|
||||
$(PLATFORM_LINKER_FLAGS) \
|
||||
$(ICU_FLAGS) \
|
||||
$(JSC_FILES) \
|
||||
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
|
||||
|
||||
|
||||
191
misctools/cold-jsc-start.cpp
Normal file
191
misctools/cold-jsc-start.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
// print how long each step took
|
||||
#define VERBOSE
|
||||
|
||||
//
|
||||
// This loads up a JavaScriptCore global object which only has a "write"
|
||||
// global function and then calls eval
|
||||
//
|
||||
//
|
||||
// Usage:
|
||||
// ./cold-jsc-start <file>
|
||||
// ./cold-jsc-start -e "write('hey')"
|
||||
//
|
||||
#include "root.h"
|
||||
|
||||
#include <wtf/FileSystem.h>
|
||||
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
|
||||
#include <JavaScriptCore/JSArrayBufferView.h>
|
||||
#include <JavaScriptCore/JSArrayBufferViewInlines.h>
|
||||
|
||||
#include <JavaScriptCore/Completion.h>
|
||||
#include <JavaScriptCore/InitializeThreading.h>
|
||||
#include <unistd.h>
|
||||
#include <wtf/Stopwatch.h>
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionWrite, (JSC::JSGlobalObject * globalObject,
|
||||
JSC::CallFrame *callframe)) {
|
||||
|
||||
if (callframe->argumentCount() < 1)
|
||||
return JSValue::encode(jsUndefined());
|
||||
|
||||
JSValue arg1 = callframe->argument(0);
|
||||
JSValue toWriteArg = callframe->argument(1);
|
||||
auto &vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
int32_t fd = STDOUT_FILENO;
|
||||
if (callframe->argumentCount() > 1) {
|
||||
fd = arg1.toInt32(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, encodedJSValue());
|
||||
} else {
|
||||
toWriteArg = arg1;
|
||||
}
|
||||
|
||||
if (auto *buffer = jsDynamicCast<JSC::JSArrayBufferView *>(toWriteArg)) {
|
||||
auto *data = buffer->vector();
|
||||
auto length = buffer->byteLength();
|
||||
auto written = write(fd, data, length);
|
||||
return JSValue::encode(jsNumber(written));
|
||||
}
|
||||
|
||||
auto string = toWriteArg.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, encodedJSValue());
|
||||
auto utf8 = string.utf8();
|
||||
auto length = utf8.length();
|
||||
auto written = write(fd, utf8.data(), length);
|
||||
return JSValue::encode(jsNumber(written));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
auto stopwatch = Stopwatch::create();
|
||||
stopwatch->start();
|
||||
#endif
|
||||
|
||||
{
|
||||
WTF::initializeMainThread();
|
||||
JSC::initialize();
|
||||
{
|
||||
JSC::Options::AllowUnfinalizedAccessScope scope;
|
||||
|
||||
JSC::Options::useConcurrentJIT() = true;
|
||||
// JSC::Options::useSigillCrashAnalyzer() = true;
|
||||
JSC::Options::useWebAssembly() = true;
|
||||
JSC::Options::useSourceProviderCache() = true;
|
||||
// JSC::Options::useUnlinkedCodeBlockJettisoning() = false;
|
||||
JSC::Options::exposeInternalModuleLoader() = true;
|
||||
JSC::Options::useSharedArrayBuffer() = true;
|
||||
JSC::Options::useJIT() = true;
|
||||
JSC::Options::useBBQJIT() = true;
|
||||
JSC::Options::useJITCage() = false;
|
||||
JSC::Options::useShadowRealm() = true;
|
||||
JSC::Options::useResizableArrayBuffer() = true;
|
||||
JSC::Options::showPrivateScriptsInStackTraces() = true;
|
||||
JSC::Options::useSetMethods() = true;
|
||||
JSC::Options::assertOptionsAreCoherent();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
|
||||
fprintf(stderr, "JSC::Initialize took %f ms\n",
|
||||
stopwatch->elapsedTime().milliseconds());
|
||||
stopwatch->reset();
|
||||
stopwatch->start();
|
||||
#endif
|
||||
|
||||
auto &vm = JSC::VM::create(JSC::HeapType::Large).leakRef();
|
||||
vm.heap.acquireAccess();
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "JSC::VM::create took %f ms\n",
|
||||
stopwatch->elapsedTime().milliseconds());
|
||||
stopwatch->reset();
|
||||
stopwatch->start();
|
||||
#endif
|
||||
|
||||
JSC::JSLockHolder locker(vm);
|
||||
auto *globalObject = JSC::JSGlobalObject::create(
|
||||
vm, JSC::JSGlobalObject::createStructure(vm, JSC::jsNull()));
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "JSC::JSGlobalObject::create took %f ms\n",
|
||||
stopwatch->elapsedTime().milliseconds());
|
||||
stopwatch->reset();
|
||||
stopwatch->start();
|
||||
#endif
|
||||
|
||||
JSC::gcProtect(globalObject);
|
||||
globalObject->putDirectNativeFunction(
|
||||
vm, globalObject,
|
||||
PropertyName(JSC::Identifier::fromString(vm, "write"_s)), 0,
|
||||
jsFunctionWrite, ImplementationVisibility::Public, JSC::NoIntrinsic,
|
||||
JSC::PropertyAttribute::ReadOnly | 0);
|
||||
|
||||
vm.ref();
|
||||
if (argc > 2) {
|
||||
auto source = JSC::makeSource(WTF::String::fromUTF8(argv[argc - 1]),
|
||||
SourceOrigin(WTF::URL("file://eval.js"_s)),
|
||||
"eval.js"_s);
|
||||
|
||||
NakedPtr<Exception> evaluationException;
|
||||
JSValue returnValue =
|
||||
JSC::profiledEvaluate(globalObject, ProfilingReason::API, source,
|
||||
globalObject, evaluationException);
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "\neval took %f ms\n",
|
||||
stopwatch->elapsedTime().milliseconds());
|
||||
stopwatch->reset();
|
||||
|
||||
#endif
|
||||
|
||||
if (evaluationException) {
|
||||
fprintf(
|
||||
stderr, "Exception: %s\n",
|
||||
evaluationException->value().toWTFString(globalObject).utf8().data());
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WTF::String fileURLString = WTF::String::fromUTF8(argv[argc - 1]);
|
||||
|
||||
if (auto contents = WTF::FileSystemImpl::readEntireFile(fileURLString)) {
|
||||
auto source =
|
||||
JSC::makeSource(WTF::String::fromUTF8(contents.value()),
|
||||
SourceOrigin(WTF::URL(fileURLString)), fileURLString);
|
||||
|
||||
NakedPtr<Exception> evaluationException;
|
||||
JSValue returnValue =
|
||||
JSC::profiledEvaluate(globalObject, ProfilingReason::API, source,
|
||||
globalObject, evaluationException);
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "eval took %f ms\n",
|
||||
stopwatch->elapsedTime().milliseconds());
|
||||
stopwatch->reset();
|
||||
#endif
|
||||
|
||||
if (evaluationException) {
|
||||
fprintf(
|
||||
stderr, "Exception: %s\n",
|
||||
evaluationException->value().toWTFString(globalObject).utf8().data());
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Could not read file %s\n", argv[argc - 1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user