Former-commit-id: 0dc1c1a74b845d037326f4f2facd786924ca722e
This commit is contained in:
Jarred Sumner
2021-08-01 19:04:38 -07:00
parent 7245f90b2d
commit 85b6d448ce
27 changed files with 1743 additions and 324 deletions

View File

@@ -18,9 +18,9 @@ pub const JSPropertyNameArrayRef = ?*struct_OpaqueJSPropertyNameArray;
pub const struct_OpaqueJSPropertyNameAccumulator = generic;
pub const JSPropertyNameAccumulatorRef = ?*struct_OpaqueJSPropertyNameAccumulator;
pub const JSTypedArrayBytesDeallocator = ?fn (?*c_void, ?*c_void) callconv(.C) void;
pub const struct_OpaqueJSValue = generic;
pub const JSValueRef = ?*struct_OpaqueJSValue;
pub const JSObjectRef = ?*struct_OpaqueJSValue;
pub const OpaqueJSValue = opaque {};
pub const JSValueRef = ?*OpaqueJSValue;
pub const JSObjectRef = ?*OpaqueJSValue;
pub extern fn JSEvaluateScript(ctx: JSContextRef, script: JSStringRef, thisObject: JSObjectRef, sourceURL: JSStringRef, startingLineNumber: c_int, exception: ExceptionRef) JSValueRef;
pub extern fn JSCheckScriptSyntax(ctx: JSContextRef, script: JSStringRef, sourceURL: JSStringRef, startingLineNumber: c_int, exception: ExceptionRef) bool;
pub extern fn JSGarbageCollect(ctx: JSContextRef) void;
@@ -242,7 +242,6 @@ pub const OpaqueJSString = struct_OpaqueJSString;
pub const OpaqueJSClass = struct_OpaqueJSClass;
pub const OpaqueJSPropertyNameArray = struct_OpaqueJSPropertyNameArray;
pub const OpaqueJSPropertyNameAccumulator = struct_OpaqueJSPropertyNameAccumulator;
pub const OpaqueJSValue = struct_OpaqueJSValue;
// const JSProcessID = ;
pub extern fn JSRemoteInspectorDisableAutoStart() void;

View File

@@ -1,7 +1,12 @@
pub const js = @import("./JavaScriptCore.zig");
const std = @import("std");
pub usingnamespace @import("../../global.zig");
const javascript = @import("./javascript.zig");
usingnamespace @import("./javascript.zig");
usingnamespace @import("./webcore/response.zig");
const TaggedPointerTypes = @import("../../tagged_pointer.zig");
const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion;
pub const ExceptionValueRef = [*c]js.JSValueRef;
pub const JSValueRef = js.JSValueRef;
@@ -26,10 +31,10 @@ pub const To = struct {
) js.JSValueRef,
) js.JSObjectRef {
var function = js.JSObjectMakeFunctionWithCallback(ctx, name, Callback(ZigContextType, callback).rfn);
_ = js.JSObjectSetPrivate(
std.debug.assert(js.JSObjectSetPrivate(
function,
@ptrCast(*c_void, @alignCast(@alignOf(*c_void), zig)),
);
JSPrivateDataPtr.init(zig).ptr(),
));
return function;
}
@@ -44,12 +49,8 @@ pub const To = struct {
pub fn rfn(
object: js.JSObjectRef,
) callconv(.C) void {
var object_ptr_ = js.JSObjectGetPrivate(object);
if (object_ptr_ == null) return;
return ctxfn(
@ptrCast(*ZigContextType, @alignCast(@alignOf(*ZigContextType), object_ptr_.?)),
object,
GetJSPrivateData(ZigContextType, object) orelse return,
);
}
};
@@ -128,26 +129,25 @@ pub const To = struct {
) callconv(.C) js.JSValueRef {
var object_ptr: *c_void = undefined;
if (comptime ZigContextType != c_void) {
var object_ptr_ = js.JSObjectGetPrivate(function);
if (object_ptr_ == null) {
object_ptr_ = js.JSObjectGetPrivate(thisObject);
}
if (object_ptr_ == null) {
return js.JSValueMakeUndefined(ctx);
}
object_ptr = object_ptr_.?;
if (comptime ZigContextType == c_void) {
return ctxfn(
js.JSObjectGetPrivate(function) or js.jsObjectGetPrivate(thisObject),
ctx,
function,
thisObject,
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
exception,
);
} else {
return ctxfn(
GetJSPrivateData(ZigContextType, function) orelse GetJSPrivateData(ZigContextType, thisObject) orelse return js.JSValueMakeUndefined(ctx),
ctx,
function,
thisObject,
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
exception,
);
}
return ctxfn(
@ptrCast(*ZigContextType, @alignCast(@alignOf(*ZigContextType), object_ptr)),
ctx,
function,
thisObject,
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
exception,
);
}
};
}
@@ -164,15 +164,7 @@ pub const To = struct {
return buf[0..js.JSStringGetUTF8CString(Ref.str(ref), buf.ptr, buf.len)];
}
pub inline fn ptr(comptime StructType: type, obj: js.JSObjectRef) *StructType {
return @ptrCast(
*StructType,
@alignCast(
@alignOf(
*StructType,
),
js.JSObjectGetPrivate(obj).?,
),
);
return GetJSPrivateData(StructType, obj).?;
}
};
};
@@ -764,10 +756,6 @@ pub fn NewClass(
pub const static_value_count = static_properties.len;
pub fn new(ctx: js.JSContextRef, ptr: ?*ZigType) js.JSObjectRef {
return js.JSObjectMake(ctx, get().*, ptr);
}
pub fn get() callconv(.C) [*c]js.JSClassRef {
if (!loaded) {
loaded = true;
@@ -795,6 +783,17 @@ pub fn NewClass(
return ClassGetter;
}
pub fn customHasInstance(ctx: js.JSContextRef, obj: js.JSObjectRef, value: js.JSValueRef, exception: ExceptionRef) callconv(.C) bool {
return js.JSValueIsObjectOfClass(ctx, obj, get().*);
}
pub fn make(ctx: js.JSContextRef, ptr: *ZigType) callconv(.C) js.JSObjectRef {
return js.JSObjectMake(
ctx,
get().*,
JSPrivateDataPtr.init(ptr).ptr(),
);
}
pub fn GetClass(comptime ReceiverType: type) type {
const ClassGetter = struct {
get: fn (
@@ -825,21 +824,7 @@ pub fn NewClass(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
var instance_pointer_ = js.JSObjectGetPrivate(obj);
if (comptime ZigType != c_void) {
if (instance_pointer_ == null) return null;
}
var instance_pointer: *c_void = if (comptime ZigType == c_void) undefined else instance_pointer_.?;
var ptr = @ptrCast(
*ZigType,
@alignCast(
@alignOf(
*ZigType,
),
instance_pointer,
),
);
var pointer = GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
if (singleton) {
inline for (function_names) |propname, i| {
@@ -876,17 +861,7 @@ pub fn NewClass(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
var instance_pointer_ = js.JSObjectGetPrivate(obj);
if (instance_pointer_ == null) return null;
var this: *ZigType = @ptrCast(
*ZigType,
@alignCast(
@alignOf(
*ZigType,
),
instance_pointer_.?,
),
);
var this = GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
var exc: js.JSValueRef = null;
const Field = @TypeOf(@field(
@@ -958,17 +933,7 @@ pub fn NewClass(
value: js.JSValueRef,
exception: js.ExceptionRef,
) callconv(.C) bool {
var instance_pointer_ = js.JSObjectGetPrivate(obj);
if (instance_pointer_ == null) return false;
var this: *ZigType = @ptrCast(
*ZigType,
@alignCast(
@alignOf(
*ZigType,
),
instance_pointer_.?,
),
);
var this = GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
var exc: js.ExceptionRef = null;
@@ -1375,13 +1340,14 @@ pub fn NewClass(
}
static_properties[i].name = property_names[i][0.. :0].ptr;
}
def.staticValues = (&static_properties);
}
def.className = class_name_str;
// def.getProperty = getPropertyCallback;
if (!singleton)
def.hasInstance = customHasInstance;
return def;
}
};
@@ -1430,8 +1396,19 @@ pub const ArrayBuffer = struct {
};
pub fn castObj(obj: js.JSObjectRef, comptime Type: type) *Type {
return @ptrCast(
*Type,
@alignCast(@alignOf(*Type), js.JSObjectGetPrivate(obj).?),
);
return JSPrivateDataPtr.from(js.JSObjectGetPrivate(obj)).as(Type);
}
pub const JSPrivateDataPtr = TaggedPointerUnion(.{
ResolveError,
BuildError,
Response,
Request,
FetchEvent,
Headers,
Body,
});
pub inline fn GetJSPrivateData(comptime Type: type, ref: js.JSObjectRef) ?*Type {
return JSPrivateDataPtr.from(js.JSObjectGetPrivate(ref)).get(Type);
}

View File

@@ -147,7 +147,7 @@ JSC::Identifier GlobalObject::moduleLoaderResolve(JSGlobalObject *globalObject,
return toIdentifier(res.result.value, globalObject);
} else {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
throwException(scope, res.result.err.message, globalObject);
throwException(scope, res.result.err, globalObject);
return globalObject->vm().propertyNames->emptyIdentifier;
}
}
@@ -168,7 +168,7 @@ JSC::JSInternalPromise *GlobalObject::moduleLoaderImportModule(JSGlobalObject *g
globalObject, toZigString(moduleNameValue, globalObject),
sourceURL.isEmpty() ? ZigStringCwd : toZigString(sourceURL.fileSystemPath()));
if (!resolved.success) {
throwException(scope, resolved.result.err.message, globalObject);
throwException(scope, resolved.result.err, globalObject);
return promise->rejectWithCaughtException(globalObject, scope);
}
@@ -196,11 +196,15 @@ JSC::JSInternalPromise *GlobalObject::moduleLoaderFetch(JSGlobalObject *globalOb
auto moduleKey = key.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
auto moduleKeyZig = toZigString(moduleKey);
ErrorableResolvedSource res;
res.success = false;
res.result.err.code = 0;
res.result.err.ptr = nullptr;
auto res = Zig__GlobalObject__fetch(globalObject, moduleKeyZig, ZigStringEmpty);
Zig__GlobalObject__fetch(&res, globalObject, moduleKeyZig, ZigStringEmpty);
if (!res.success) {
throwException(scope, res.result.err.message, globalObject);
throwException(scope, res.result.err, globalObject);
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
}

View File

@@ -1,10 +1,14 @@
#include "helpers.h"
#include "root.h"
#include <JavaScriptCore/AggregateError.h>
#include <JavaScriptCore/BytecodeIndex.h>
#include <JavaScriptCore/CodeBlock.h>
#include <JavaScriptCore/Completion.h>
#include <JavaScriptCore/ErrorInstance.h>
#include <JavaScriptCore/ExceptionScope.h>
#include <JavaScriptCore/FunctionConstructor.h>
#include <JavaScriptCore/Identifier.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSCallbackObject.h>
#include <JavaScriptCore/JSClassRef.h>
@@ -16,15 +20,17 @@
#include <JavaScriptCore/JSSet.h>
#include <JavaScriptCore/JSString.h>
#include <JavaScriptCore/ParserError.h>
#include <JavaScriptCore/ScriptExecutable.h>
#include <JavaScriptCore/StackFrame.h>
#include <JavaScriptCore/StackVisitor.h>
#include <JavaScriptCore/VM.h>
#include <JavaScriptCore/WasmFaultSignalHandler.h>
#include <wtf/text/ExternalStringImpl.h>
#include <wtf/text/StringCommon.h>
#include <wtf/text/StringImpl.h>
#include <wtf/text/StringView.h>
#include <wtf/text/WTFString.h>
#include <wtf/text/WTFString.h>
extern "C" {
// #pragma mark - JSC::PropertyNameArray
@@ -131,20 +137,51 @@ static JSC::JSValue doLink(JSC__JSGlobalObject *globalObject, JSC::JSValue modul
return JSC::linkAndEvaluateModule(globalObject, moduleKey, JSC::JSValue());
}
JSC__JSValue JSC__JSGlobalObject__createAggregateError(JSC__JSGlobalObject *globalObject,
JSC__JSValue *errors, uint16_t errors_count,
ZigString arg3) {
JSC::VM &vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSC::JSValue message = JSC::JSValue(JSC::jsOwnedString(vm, Zig::toString(arg3)));
JSC::JSValue options = JSC::jsUndefined();
JSC::JSArray *array = nullptr;
{
JSC::ObjectInitializationScope initializationScope(vm);
if ((array = JSC::JSArray::tryCreateUninitializedRestricted(
initializationScope, nullptr,
globalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous),
errors_count))) {
for (uint16_t i = 0; i < errors_count; ++i) {
array->initializeIndexWithoutBarrier(initializationScope, i,
JSC::JSValue::decode(errors[i]));
}
}
}
if (!array) {
JSC::throwOutOfMemoryError(globalObject, scope);
return JSC::JSValue::encode(JSC::JSValue());
}
JSC::Structure *errorStructure = globalObject->errorStructure(JSC::ErrorType::AggregateError);
return RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::createAggregateError(
globalObject, vm, errorStructure, array, message, options,
nullptr, JSC::TypeNothing, false)));
}
// static JSC::JSNativeStdFunction* resolverFunction;
// static JSC::JSNativeStdFunction* rejecterFunction;
// static bool resolverFunctionInitialized = false;
JSC__JSValue ZigString__toValue(ZigString arg0, JSC__JSGlobalObject *arg1) {
return JSC::JSValue::encode(JSC::JSValue(JSC::jsOwnedString(arg1->vm(), Zig::toString(arg0))));
}
static JSC::EncodedJSValue resolverFunctionCallback(JSC::JSGlobalObject *globalObject,
JSC::CallFrame *callFrame) {
return JSC::JSValue::encode(doLink(globalObject, callFrame->argument(0)));
}
static JSC::EncodedJSValue rejecterFunctionCallback(JSC::JSGlobalObject *globalObject,
JSC::CallFrame *callFrame) {
return JSC::JSValue::encode(callFrame->argument(0));
}
JSC__JSInternalPromise *
JSC__JSModuleLoader__loadAndEvaluateModule(JSC__JSGlobalObject *globalObject, ZigString arg1) {
globalObject->vm().drainMicrotasks();
@@ -157,9 +194,14 @@ JSC__JSModuleLoader__loadAndEvaluateModule(JSC__JSGlobalObject *globalObject, Zi
JSC::JSNativeStdFunction *resolverFunction = JSC::JSNativeStdFunction::create(
globalObject->vm(), globalObject, 1, String(), resolverFunctionCallback);
JSC::JSNativeStdFunction *rejecterFunction = JSC::JSNativeStdFunction::create(
globalObject->vm(), globalObject, 1, String(), rejecterFunctionCallback);
globalObject->vm(), globalObject, 1, String(),
[&arg1](JSC::JSGlobalObject *globalObject, JSC::CallFrame *callFrame) -> JSC::EncodedJSValue {
return JSC::JSValue::encode(
JSC::JSInternalPromise::rejectedPromise(globalObject, callFrame->argument(0)));
});
globalObject->vm().drainMicrotasks();
auto result = promise->then(globalObject, resolverFunction, nullptr);
auto result = promise->then(globalObject, resolverFunction, rejecterFunction);
globalObject->vm().drainMicrotasks();
// if (promise->status(globalObject->vm()) ==
@@ -687,100 +729,321 @@ bWTF__String JSC__JSValue__toWTFString(JSC__JSValue JSValue0, JSC__JSGlobalObjec
return Wrap<WTF::String, bWTF__String>::wrap(value.toWTFString(arg1));
};
static ZigException fromErrorInstance(JSC::JSGlobalObject *global, JSC::ErrorInstance *err,
JSC::JSValue val) {
ZigException except = Zig::ZigExceptionNone;
JSC::JSObject *obj = JSC::jsDynamicCast<JSC::JSObject *>(global->vm(), val);
if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) {
JSC::StackFrame *stack = &err->stackTrace()->first();
except.sourceURL = Zig::toZigString(stack->sourceURL());
static void populateStackFrameMetadata(const JSC::StackFrame *stackFrame, ZigStackFrame *frame) {
frame->source_url = Zig::toZigString(stackFrame->sourceURL());
if (stack->hasLineAndColumnInfo()) {
unsigned lineNumber;
unsigned column;
stack->computeLineAndColumn(lineNumber, column);
except.line = lineNumber;
except.column = column;
if (stackFrame->isWasmFrame()) {
frame->code_type = ZigStackFrameCodeWasm;
return;
}
auto m_codeBlock = stackFrame->codeBlock();
if (m_codeBlock) {
switch (m_codeBlock->codeType()) {
case JSC::EvalCode: {
frame->code_type = ZigStackFrameCodeEval;
return;
}
case JSC::ModuleCode: {
frame->code_type = ZigStackFrameCodeModule;
return;
}
case JSC::GlobalCode: {
frame->code_type = ZigStackFrameCodeGlobal;
return;
}
case JSC::FunctionCode: {
frame->code_type =
!m_codeBlock->isConstructor() ? ZigStackFrameCodeFunction : ZigStackFrameCodeConstructor;
break;
}
default: ASSERT_NOT_REACHED();
}
}
auto calleeCell = stackFrame->callee();
if (!calleeCell || !calleeCell->isObject()) return;
JSC::JSObject *callee = JSC::jsCast<JSC::JSObject *>(calleeCell);
// Does the code block have a user-defined name property?
JSC::JSValue name = callee->getDirect(m_codeBlock->vm(), m_codeBlock->vm().propertyNames->name);
if (name && name.isString()) {
auto str = name.toWTFString(m_codeBlock->globalObject());
frame->function_name = Zig::toZigString(str);
return;
}
/* For functions (either JSFunction or InternalFunction), fallback to their "native" name
* property. Based on JSC::getCalculatedDisplayName, "inlining" the
* JSFunction::calculatedDisplayName\InternalFunction::calculatedDisplayName calls */
if (JSC::JSFunction *function =
JSC::jsDynamicCast<JSC::JSFunction *>(m_codeBlock->vm(), callee)) {
WTF::String actualName = function->name(m_codeBlock->vm());
if (!actualName.isEmpty() || function->isHostOrBuiltinFunction()) {
frame->function_name = Zig::toZigString(actualName);
return;
}
auto inferred_name = function->jsExecutable()->name();
frame->function_name = Zig::toZigString(inferred_name.string());
}
if (JSC::InternalFunction *function =
JSC::jsDynamicCast<JSC::InternalFunction *>(m_codeBlock->vm(), callee)) {
// Based on JSC::InternalFunction::calculatedDisplayName, skipping the "displayName" property
frame->function_name = Zig::toZigString(function->name());
}
}
// Based on
// https://github.com/mceSystems/node-jsc/blob/master/deps/jscshim/src/shim/JSCStackTrace.cpp#L298
static void populateStackFramePosition(const JSC::StackFrame *stackFrame, ZigString *source_lines,
int32_t *source_line_numbers, uint8_t source_lines_count,
ZigStackFramePosition *position) {
auto m_codeBlock = stackFrame->codeBlock();
if (!m_codeBlock) return;
JSC::BytecodeIndex bytecodeOffset =
stackFrame->hasBytecodeIndex() ? stackFrame->bytecodeIndex() : JSC::BytecodeIndex();
/* Get the "raw" position info.
* Note that we're using m_codeBlock->unlinkedCodeBlock()->expressionRangeForBytecodeOffset
* rather than m_codeBlock->expressionRangeForBytecodeOffset in order get the "raw" offsets and
* avoid the CodeBlock's expressionRangeForBytecodeOffset modifications to the line and column
* numbers, (we don't need the column number from it, and we'll calculate the line "fixes"
* ourselves). */
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
unsigned line = 0;
unsigned unusedColumn = 0;
m_codeBlock->unlinkedCodeBlock()->expressionRangeForBytecodeIndex(
bytecodeOffset, divotPoint, startOffset, endOffset, line, unusedColumn);
divotPoint += m_codeBlock->sourceOffset();
// TODO: evaluate if using the API from UnlinkedCodeBlock can be used instead of iterating
// through source text.
/* On the first line of the source code, it seems that we need to "fix" the column with the
* starting offset. We currently use codeBlock->source()->startPosition().m_column.oneBasedInt()
* as the offset in the first line rather than codeBlock->firstLineColumnOffset(), which seems
* simpler (and what CodeBlock::expressionRangeForBytecodeOffset does). This is because
* firstLineColumnOffset values seems different from what we expect (according to v8's tests)
* and I haven't dove into the relevant parts in JSC (yet) to figure out why. */
unsigned columnOffset = line ? 0 : m_codeBlock->source().startColumn().zeroBasedInt();
// "Fix" the line number
JSC::ScriptExecutable *executable = m_codeBlock->ownerExecutable();
if (std::optional<int> overrideLine = executable->overrideLineNumber(m_codeBlock->vm())) {
line = overrideLine.value();
} else {
// JSC::ErrorInstance marks these as protected.
// To work around that, we cast as a JSC::JSObject
// This code path triggers when there was an exception before the code was executed
// For example, ParserError becomes one of these
auto source_url_value = obj->getDirect(global->vm(), global->vm().propertyNames->sourceURL);
auto str = source_url_value.toWTFString(global);
except.sourceURL = Zig::toZigString(str);
except.line = obj->getDirect(global->vm(), global->vm().propertyNames->line).toInt32(global);
except.column =
obj->getDirect(global->vm(), global->vm().propertyNames->column).toInt32(global);
line += executable->firstLine();
}
if (obj->hasProperty(global, global->vm().propertyNames->stack)) {
except.stack = Zig::toZigString(
obj->getDirect(global->vm(), global->vm().propertyNames->stack).toWTFString(global));
// Calculate the staring\ending offsets of the entire expression
int expressionStart = divotPoint - startOffset;
int expressionStop = divotPoint + endOffset;
// Make sure the range is valid
WTF::StringView sourceString = m_codeBlock->source().provider()->source();
if (!expressionStop || expressionStart > static_cast<int>(sourceString.length())) { return; }
// Search for the beginning of the line
unsigned int lineStart = expressionStart;
while ((lineStart > 0) && ('\n' != sourceString[lineStart - 1])) { lineStart--; }
// Search for the end of the line
unsigned int lineStop = expressionStop;
unsigned int sourceLength = sourceString.length();
while ((lineStop < sourceLength) && ('\n' != sourceString[lineStop])) { lineStop++; }
if (source_lines_count > 1 && source_lines != nullptr) {
auto chars = sourceString.characters8();
// Most of the time, when you look at a stack trace, you want a couple lines above
source_lines[0] = {&chars[lineStart], lineStop - lineStart};
source_line_numbers[0] = line;
if (lineStart > 0) {
auto byte_offset_in_source_string = lineStart - 1;
uint8_t source_line_i = 1;
auto remaining_lines_to_grab = source_lines_count - 1;
while (byte_offset_in_source_string > 0 && remaining_lines_to_grab > 0) {
unsigned int end_of_line_offset = byte_offset_in_source_string;
// This should probably be code points instead of newlines
while (byte_offset_in_source_string > 0 && chars[byte_offset_in_source_string] != '\n') {
byte_offset_in_source_string--;
}
// We are at the beginning of the line
source_lines[source_line_i] = {&chars[byte_offset_in_source_string],
end_of_line_offset - byte_offset_in_source_string + 1};
source_line_numbers[source_line_i] = line - source_line_i;
source_line_i++;
remaining_lines_to_grab--;
byte_offset_in_source_string -= byte_offset_in_source_string > 0;
}
}
}
except.code = (unsigned char)err->errorType();
if (err->isStackOverflowError()) { except.code = 253; }
if (err->isOutOfMemoryError()) { except.code = 8; }
/* Finally, store the source "positions" info.
* Notes:
* - The retrieved column seem to point the "end column". To make sure we're current, we'll
*calculate the columns ourselves, since we've already found where the line starts. Note that in
*v8 it should be 0-based here (in contrast the 1-based column number in v8::StackFrame).
* - The static_casts are ugly, but comes from differences between JSC and v8's api, and should
*be OK since no source should be longer than "max int" chars.
* TODO: If expressionStart == expressionStop, then m_endColumn will be equal to m_startColumn.
*Should we handle this case?
*/
position->expression_start = expressionStart;
position->expression_stop = expressionStop;
position->line = WTF::OrdinalNumber::fromOneBasedInt(static_cast<int>(line)).zeroBasedInt();
position->column_start = (expressionStart - lineStart) + columnOffset;
position->column_stop = position->column_start + (expressionStop - expressionStart);
position->line_start = lineStart;
position->line_stop = lineStop;
return;
}
static void populateStackFrame(ZigStackTrace *trace, const JSC::StackFrame *stackFrame,
ZigStackFrame *frame, bool is_top) {
populateStackFrameMetadata(stackFrame, frame);
populateStackFramePosition(stackFrame, is_top ? trace->source_lines_ptr : nullptr,
is_top ? trace->source_lines_numbers : nullptr,
is_top ? trace->source_lines_to_collect : 0, &frame->position);
}
static void populateStackTrace(const WTF::Vector<JSC::StackFrame> &frames, ZigStackTrace *trace) {
uint8_t frame_i = 0;
size_t stack_frame_i = 0;
const size_t total_frame_count = frames.size();
const uint8_t frame_count =
total_frame_count < trace->frames_len ? total_frame_count : trace->frames_len;
while (frame_i < frame_count && stack_frame_i < total_frame_count) {
// Skip native frames
while (stack_frame_i < total_frame_count && !(&frames.at(stack_frame_i))->codeBlock() &&
!(&frames.at(stack_frame_i))->isWasmFrame()) {
stack_frame_i++;
}
if (stack_frame_i >= total_frame_count) break;
ZigStackFrame *frame = &trace->frames_ptr[frame_i];
populateStackFrame(trace, &frames[stack_frame_i], frame, frame_i == 0);
stack_frame_i++;
frame_i++;
}
trace->frames_len = frame_i;
}
static void fromErrorInstance(ZigException *except, JSC::JSGlobalObject *global,
JSC::ErrorInstance *err, const Vector<JSC::StackFrame> *stackTrace,
JSC::JSValue val) {
JSC::JSObject *obj = JSC::jsDynamicCast<JSC::JSObject *>(global->vm(), val);
if (stackTrace != nullptr && stackTrace->size() > 0) {
populateStackTrace(*stackTrace, &except->stack);
} else if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) {
populateStackTrace(*err->stackTrace(), &except->stack);
}
except->code = (unsigned char)err->errorType();
if (err->isStackOverflowError()) { except->code = 253; }
if (err->isOutOfMemoryError()) { except->code = 8; }
if (obj->hasProperty(global, global->vm().propertyNames->message)) {
except.message = Zig::toZigString(
except->message = Zig::toZigString(
obj->getDirect(global->vm(), global->vm().propertyNames->message).toWTFString(global));
} else {
except.message = Zig::toZigString(err->sanitizedMessageString(global));
except->message = Zig::toZigString(err->sanitizedMessageString(global));
}
except.name = Zig::toZigString(err->sanitizedNameString(global));
except.runtime_type = err->runtimeTypeForCause();
except->name = Zig::toZigString(err->sanitizedNameString(global));
except->runtime_type = err->runtimeTypeForCause();
except.exception = err;
return except;
except->exception = err;
}
static ZigException exceptionFromString(WTF::String &str) {
ZigException except = Zig::ZigExceptionNone;
auto ref = OpaqueJSString::tryCreate(str);
except.message = ZigString{ref->characters8(), ref->length()};
ref->ref();
void exceptionFromString(ZigException *except, JSC::JSValue value, JSC::JSGlobalObject *global) {
// Fallback case for when it's a user-defined ErrorLike-object that doesn't inherit from
// ErrorInstance
if (JSC::JSObject *obj = JSC::jsDynamicCast<JSC::JSObject *>(global->vm(), value)) {
if (obj->hasProperty(global, global->vm().propertyNames->name)) {
auto name_str =
obj->getDirect(global->vm(), global->vm().propertyNames->name).toWTFString(global);
except->name = Zig::toZigString(name_str);
if (name_str == "Error"_s) {
except->code = JSErrorCodeError;
} else if (name_str == "EvalError"_s) {
except->code = JSErrorCodeEvalError;
} else if (name_str == "RangeError"_s) {
except->code = JSErrorCodeRangeError;
} else if (name_str == "ReferenceError"_s) {
except->code = JSErrorCodeReferenceError;
} else if (name_str == "SyntaxError"_s) {
except->code = JSErrorCodeSyntaxError;
} else if (name_str == "TypeError"_s) {
except->code = JSErrorCodeTypeError;
} else if (name_str == "URIError"_s) {
except->code = JSErrorCodeURIError;
} else if (name_str == "AggregateError"_s) {
except->code = JSErrorCodeAggregateError;
}
}
return except;
}
if (obj->hasProperty(global, global->vm().propertyNames->message)) {
except->message = Zig::toZigString(
obj->getDirect(global->vm(), global->vm().propertyNames->message).toWTFString(global));
}
static ZigException exceptionFromString(JSC::JSValue value, JSC::JSGlobalObject *global) {
if (obj->hasProperty(global, global->vm().propertyNames->sourceURL)) {
except->stack.frames_ptr[0].source_url = Zig::toZigString(
obj->getDirect(global->vm(), global->vm().propertyNames->sourceURL).toWTFString(global));
except->stack.frames_len = 1;
}
if (obj->hasProperty(global, global->vm().propertyNames->line)) {
except->stack.frames_ptr[0].position.line =
obj->getDirect(global->vm(), global->vm().propertyNames->line).toInt32(global);
except->stack.frames_len = 1;
}
return;
}
auto scope = DECLARE_THROW_SCOPE(global->vm());
auto str = value.toWTFString(global);
if (scope.exception()) {
scope.clearException();
scope.release();
return Zig::ZigExceptionNone;
return;
}
scope.release();
ZigException except = Zig::ZigExceptionNone;
auto ref = OpaqueJSString::tryCreate(str);
except.message = ZigString{ref->characters8(), ref->length()};
except->message = ZigString{ref->characters8(), ref->length()};
ref->ref();
return except;
}
ZigException JSC__JSValue__toZigException(JSC__JSValue JSValue0, JSC__JSGlobalObject *arg1) {
void JSC__JSValue__toZigException(JSC__JSValue JSValue0, JSC__JSGlobalObject *arg1,
ZigException *exception) {
JSC::JSValue value = JSC::JSValue::decode(JSValue0);
if (JSC::ErrorInstance *error = JSC::jsDynamicCast<JSC::ErrorInstance *>(arg1->vm(), value)) {
return fromErrorInstance(arg1, error, value);
}
if (JSC::Exception *exception = JSC::jsDynamicCast<JSC::Exception *>(arg1->vm(), value)) {
if (JSC::Exception *jscException = JSC::jsDynamicCast<JSC::Exception *>(arg1->vm(), value)) {
if (JSC::ErrorInstance *error =
JSC::jsDynamicCast<JSC::ErrorInstance *>(arg1->vm(), exception->value())) {
return fromErrorInstance(arg1, error, value);
JSC::jsDynamicCast<JSC::ErrorInstance *>(arg1->vm(), jscException->value())) {
fromErrorInstance(exception, arg1, error, &jscException->stack(), value);
return;
}
}
return exceptionFromString(value, arg1);
if (JSC::ErrorInstance *error = JSC::jsDynamicCast<JSC::ErrorInstance *>(arg1->vm(), value)) {
fromErrorInstance(exception, arg1, error, nullptr, value);
return;
}
exceptionFromString(exception, value, arg1);
}
#pragma mark - JSC::PropertyName

View File

@@ -2,6 +2,7 @@ usingnamespace @import("./shared.zig");
usingnamespace @import("./headers.zig");
pub const Shimmer = @import("./shimmer.zig").Shimmer;
const hasRef = std.meta.trait.hasField("ref");
const C_API = @import("../JavaScriptCore.zig");
pub const JSObject = extern struct {
pub const shim = Shimmer("JSC", "JSObject", @This());
@@ -37,6 +38,10 @@ pub const JSObject = extern struct {
pub const ZigString = extern struct {
ptr: [*]const u8,
len: usize,
pub const shim = Shimmer("Zig", "ZigString", @This());
pub const name = "ZigString";
pub const namespace = "Zig";
pub fn init(slice_: []const u8) ZigString {
return ZigString{ .ptr = slice_.ptr, .len = slice_.len };
@@ -47,6 +52,18 @@ pub const ZigString = extern struct {
pub fn slice(this: *const ZigString) []const u8 {
return this.ptr[0..std.math.min(this.len, 4096)];
}
pub fn toValue(this: ZigString, global: *JSGlobalObject) JSValue {
return shim.cppFn("toValue", .{ this, global });
}
pub fn toJSStringRef(this: *const ZigString) C_API.JSStringRef {
return C_API.JSStringCreateStatic(this.ptr, this.len);
}
pub const Extern = [_][]const u8{
"toValue",
};
};
pub const JSCell = extern struct {
@@ -184,11 +201,12 @@ pub fn NewGlobalObject(comptime Type: type) type {
}
return ErrorableZigString.err(error.ResolveFailed, "resolve not implemented");
}
pub fn fetch(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableResolvedSource {
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) void {
if (comptime @hasDecl(Type, "fetch")) {
return @call(.{ .modifier = .always_inline }, Type.fetch, .{ global, specifier, source });
@call(.{ .modifier = .always_inline }, Type.fetch, .{ ret, global, specifier, source });
return;
}
return ErrorableResolvedSource.err(error.FetchFailed, "Module fetch not implemented");
ret.* = ErrorableResolvedSource.err(error.FetchFailed, "Module fetch not implemented");
}
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
if (comptime @hasDecl(Type, "promiseRejectionTracker")) {
@@ -776,11 +794,16 @@ pub const JSGlobalObject = extern struct {
return cppFn("asyncGeneratorFunctionPrototype", .{this});
}
pub fn createAggregateError(globalObject: *JSGlobalObject, errors: [*]JSValue, errors_len: u16, message: ZigString) JSValue {
return cppFn("createAggregateError", .{ globalObject, errors, errors_len, message });
}
pub fn vm(this: *JSGlobalObject) *VM {
return cppFn("vm", .{this});
}
pub const Extern = [_][]const u8{
"createAggregateError",
"objectPrototype",
"functionPrototype",
"arrayPrototype",
@@ -1087,6 +1110,7 @@ pub const JSValue = enum(i64) {
pub fn jsNumberFromInt32(i: i32) JSValue {
return cppFn("jsNumberFromInt32", .{i});
}
pub fn jsNumberFromInt64(i: i64) JSValue {
return cppFn("jsNumberFromInt64", .{i});
}
@@ -1165,8 +1189,8 @@ pub const JSValue = enum(i64) {
return cppFn("isException", .{ this, vm });
}
pub fn toZigException(this: JSValue, global: *JSGlobalObject) ZigException {
return cppFn("toZigException", .{ this, global });
pub fn toZigException(this: JSValue, global: *JSGlobalObject, exception: *ZigException) void {
return cppFn("toZigException", .{ this, global, exception });
}
// On exception, this returns the empty string.

View File

@@ -3,6 +3,7 @@ usingnamespace @import("./shared.zig");
const Fs = @import("../../../fs.zig");
const CAPI = @import("../JavaScriptCore.zig");
const JS = @import("../javascript.zig");
const JSBase = @import("../base.zig");
const Handler = struct {
pub export fn global_signal_handler_fn(sig: i32, info: *const std.os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) void {
Global.panic("C++ Crash!!", .{});
@@ -47,11 +48,11 @@ pub const ZigGlobalObject = extern struct {
}
return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, specifier, source });
}
pub fn fetch(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableResolvedSource {
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) void {
if (comptime is_bindgen) {
unreachable;
}
return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, specifier, source });
@call(.{ .modifier = .always_inline }, Interface.fetch, .{ ret, global, specifier, source });
}
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
@@ -106,7 +107,8 @@ pub const ZigGlobalObject = extern struct {
}
};
const ErrorCodeInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);
const ErrorCodeInt = usize;
pub const ErrorCode = enum(ErrorCodeInt) {
_,
@@ -114,18 +116,33 @@ pub const ErrorCode = enum(ErrorCodeInt) {
return @intToEnum(ErrorCode, @errorToInt(code));
}
pub const Type = switch (@sizeOf(anyerror)) {
0, 1 => u8,
2 => u16,
3 => u32,
4 => u64,
else => @compileError("anyerror is too big"),
};
pub const ParserError = @enumToInt(ErrorCode.from(error.ParserError));
pub const JSErrorObject = @enumToInt(ErrorCode.from(error.JSErrorObject));
pub const Type = ErrorCodeInt;
};
pub const ZigErrorType = extern struct {
pub const shim = Shimmer("Zig", "ErrorType", @This());
pub const name = "ErrorType";
pub const namespace = shim.namespace;
code: ErrorCode,
message: ZigString,
ptr: ?*c_void,
pub fn isPrivateData(ptr: ?*c_void) callconv(.C) bool {
return JSBase.JSPrivateDataPtr.isValidPtr(ptr);
}
pub const Export = shim.exportFunctions(.{
.@"isPrivateData" = isPrivateData,
});
comptime {
@export(isPrivateData, .{
.name = Export[0].symbol_name,
});
}
};
pub const JSErrorCode = enum(u8) {
@@ -140,6 +157,7 @@ pub const JSErrorCode = enum(u8) {
// StackOverflow & OutOfMemoryError is not an ErrorType in <JavaScriptCore/ErrorType.h> within JSC, so the number here is just totally made up
OutOfMemoryError = 8,
BundlerError = 252,
StackOverflow = 253,
UserErrorCode = 254,
_,
@@ -181,18 +199,12 @@ pub fn Errorable(comptime Type: type) type {
}
threadlocal var err_buf: [4096]u8 = undefined;
pub fn errFmt(code: anyerror, comptime fmt: []const u8, args: anytype) @This() {
const message = std.fmt.bufPrint(&err_buf, fmt, args) catch @as([]const u8, @errorName(code)[0..]);
return @call(.{ .modifier = .always_inline }, err, .{ code, message });
}
pub fn err(code: anyerror, msg: []const u8) @This() {
pub fn err(code: anyerror, ptr: *c_void) @This() {
return @This(){
.result = .{
.err = .{
.code = ErrorCode.from(code),
.message = ZigString.init(msg),
.ptr = ptr,
},
},
.success = false,
@@ -215,10 +227,200 @@ pub const ResolvedSource = extern struct {
bytecodecache_fd: u64,
};
pub const ErrorableResolvedSource = Errorable(ResolvedSource);
pub const ZigStackFrameCode = enum(u8) {
None = 0,
// 🏃
Eval = 1,
// 📦
Module = 2,
// λ
Function = 3,
// 🌎
Global = 4,
// ⚙️
Wasm = 5,
// 👷
Constructor = 6,
_,
pub const ErrorableZigString = Errorable(ZigString);
pub const ErrorableJSValue = Errorable(JSValue);
pub fn emoji(this: ZigStackFrameCode) u21 {
return switch (this) {
.Eval => 0x1F3C3,
.Module => 0x1F4E6,
.Function => 0x03BB,
.Global => 0x1F30E,
.Wasm => 0xFE0F,
.Constructor => 0xF1477,
else => ' ',
};
}
pub fn ansiColor(this: ZigStackFrameCode) string {
return switch (this) {
.Eval => "\x1b[31m",
.Module => "\x1b[36m",
.Function => "\x1b[32m",
.Global => "\x1b[35m",
.Wasm => "\x1b[37m",
.Constructor => "\x1b[33m",
else => "",
};
}
};
pub const ZigStackTrace = extern struct {
source_lines_ptr: [*c]ZigString,
source_lines_numbers: [*c]i32,
source_lines_len: u8,
source_lines_to_collect: u8,
frames_ptr: [*c]ZigStackFrame,
frames_len: u8,
pub fn frames(this: *const ZigStackTrace) []const ZigStackFrame {
return this.frames_ptr[0..this.frames_len];
}
pub const SourceLineIterator = struct {
trace: *const ZigStackTrace,
i: i16,
pub const SourceLine = struct {
line: i32,
text: string,
};
pub fn untilLast(this: *SourceLineIterator) ?SourceLine {
if (this.i < 1) return null;
return this.next();
}
pub fn next(this: *SourceLineIterator) ?SourceLine {
if (this.i < 0) return null;
const result = SourceLine{
.line = this.trace.source_lines_numbers[@intCast(usize, this.i)],
.text = this.trace.source_lines_ptr[@intCast(usize, this.i)].slice(),
};
this.i -= 1;
return result;
}
};
pub fn sourceLineIterator(this: *const ZigStackTrace) SourceLineIterator {
var i: usize = 0;
for (this.source_lines_numbers[0..this.source_lines_len]) |num, j| {
if (num > 0) {
i = j;
}
}
return SourceLineIterator{ .trace = this, .i = @intCast(i16, i) };
}
};
pub const ZigStackFrame = extern struct {
pub const SourceURLFormatter = struct {
source_url: ZigString,
position: ZigStackFramePosition,
enable_color: bool,
pub fn format(this: SourceURLFormatter, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
try writer.writeAll(this.source_url.slice());
if (this.position.line > -1 and this.position.column_start > -1) {
try std.fmt.format(writer, ":{d}:{d}", .{ this.position.line, this.position.column_start });
} else if (this.position.line > -1) {
try std.fmt.format(writer, ":{d}", .{
this.position.line,
});
}
}
};
pub const NameFormatter = struct {
function_name: ZigString,
code_type: ZigStackFrameCode,
enable_color: bool,
pub fn format(this: NameFormatter, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
const name = this.function_name.slice();
switch (this.code_type) {
.Eval => {
try writer.writeAll("(eval)");
},
.Module => {
try writer.writeAll("(esm)");
},
.Function => {
if (name.len > 0) {
try std.fmt.format(writer, "{s}", .{name});
} else {
try writer.writeAll("(anonymous)");
}
},
.Global => {
if (name.len > 0) {
try std.fmt.format(writer, "globalThis {s}", .{name});
} else {
try writer.writeAll("globalThis");
}
},
.Wasm => {
try std.fmt.format(writer, "WASM {s}", .{name});
},
.Constructor => {
try std.fmt.format(writer, "new {s}", .{name});
},
else => {},
}
}
};
pub const Zero: ZigStackFrame = ZigStackFrame{
.function_name = ZigString{ .ptr = "", .len = 0 },
.code_type = ZigStackFrameCode.None,
.source_url = ZigString{ .ptr = "", .len = 0 },
.position = ZigStackFramePosition.Invalid,
};
function_name: ZigString,
source_url: ZigString,
position: ZigStackFramePosition,
code_type: ZigStackFrameCode,
pub fn nameFormatter(this: *const ZigStackFrame, comptime enable_color: bool) NameFormatter {
return NameFormatter{ .function_name = this.function_name, .code_type = this.code_type, .enable_color = enable_color };
}
pub fn sourceURLFormatter(this: *const ZigStackFrame, comptime enable_color: bool) SourceURLFormatter {
return SourceURLFormatter{ .source_url = this.source_url, .position = this.position, .enable_color = enable_color };
}
};
pub const ZigStackFramePosition = extern struct {
source_offset: i32,
line: i32,
line_start: i32,
line_stop: i32,
column_start: i32,
column_stop: i32,
expression_start: i32,
expression_stop: i32,
pub const Invalid = ZigStackFramePosition{
.source_offset = -1,
.line = -1,
.line_start = -1,
.line_stop = -1,
.column_start = -1,
.column_stop = -1,
.expression_start = -1,
.expression_stop = -1,
};
pub fn isInvalid(this: *const ZigStackFramePosition) bool {
return std.mem.eql(u8, std.mem.asBytes(this), std.mem.asBytes(&Invalid));
}
};
pub const ZigException = extern struct {
pub const shim = Shimmer("Zig", "Exception", @This());
@@ -229,12 +431,68 @@ pub const ZigException = extern struct {
runtime_type: JSRuntimeType,
name: ZigString,
message: ZigString,
sourceURL: ZigString,
line: i32,
column: i32,
stack: ZigString,
stack: ZigStackTrace,
exception: ?*c_void,
pub const Holder = extern struct {
const frame_count = 24;
const source_lines_count = 6;
source_line_numbers: [source_lines_count]i32,
source_lines: [source_lines_count]ZigString,
frames: [frame_count]ZigStackFrame,
loaded: bool,
zig_exception: ZigException,
pub const Zero: Holder = Holder{
.frames = brk: {
var _frames: [frame_count]ZigStackFrame = undefined;
std.mem.set(ZigStackFrame, &_frames, ZigStackFrame.Zero);
break :brk _frames;
},
.source_line_numbers = brk: {
var lines: [source_lines_count]i32 = undefined;
std.mem.set(i32, &lines, -1);
break :brk lines;
},
.source_lines = brk: {
var lines: [source_lines_count]ZigString = undefined;
std.mem.set(ZigString, &lines, ZigString.Empty);
break :brk lines;
},
.zig_exception = undefined,
.loaded = false,
};
pub fn init() Holder {
return Holder.Zero;
}
pub fn zigException(this: *Holder) *ZigException {
if (!this.loaded) {
this.zig_exception = ZigException{
.code = @intToEnum(JSErrorCode, 255),
.runtime_type = JSRuntimeType.Nothing,
.name = ZigString.Empty,
.message = ZigString.Empty,
.exception = null,
.stack = ZigStackTrace{
.source_lines_ptr = &this.source_lines,
.source_lines_numbers = &this.source_line_numbers,
.source_lines_len = source_lines_count,
.source_lines_to_collect = source_lines_count,
.frames_ptr = &this.frames,
.frames_len = this.frames.len,
},
};
this.loaded = true;
}
return &this.zig_exception;
}
};
pub fn fromException(exception: *Exception) ZigException {
return shim.cppFn("fromException", .{exception});
}
@@ -242,6 +500,10 @@ pub const ZigException = extern struct {
pub const Extern = [_][]const u8{"fromException"};
};
pub const ErrorableResolvedSource = Errorable(ResolvedSource);
pub const ErrorableZigString = Errorable(ZigString);
pub const ErrorableJSValue = Errorable(JSValue);
pub const ZigConsoleClient = struct {
pub const shim = Shimmer("Zig", "ConsoleClient", @This());
pub const Type = *c_void;
@@ -463,3 +725,8 @@ pub const ZigConsoleClient = struct {
pub inline fn toGlobalContextRef(ptr: *JSGlobalObject) CAPI.JSGlobalContextRef {
return @ptrCast(CAPI.JSGlobalContextRef, ptr);
}
comptime {
@export(ErrorCode.ParserError, .{ .name = "Zig_ErrorCodeParserError" });
@export(ErrorCode.JSErrorObject, .{ .name = "Zig_ErrorCodeJSErrorObject" });
}

View File

@@ -577,7 +577,7 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
const Generator = C_Generator;
validateGenerator(Generator);
var file_writer = file.writer();
file_writer.print("//-- AUTOGENERATED FILE -- {d}\n", .{std.time.timestamp()}) catch unreachable;
file_writer.print("//-- AUTOGENERATED FILE -- {d}\n// clang-format: off\n", .{std.time.timestamp()}) catch unreachable;
file.writeAll(
\\#pragma once
\\
@@ -594,18 +594,15 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
\\#define CPP_DECL AUTO_EXTERN_C
\\#define CPP_SIZE AUTO_EXTERN_C
\\
\\typedef uint16_t ZigErrorCode;
\\#ifndef __cplusplus
\\typedef void* JSClassRef;
\\#endif
\\typedef struct ZigString { const unsigned char* ptr; size_t len; } ZigString;
\\typedef struct ZigErrorType { ZigErrorCode code; ZigString message; } ZigErrorType;
\\typedef struct ZigException { unsigned char code; uint16_t runtime_type; ZigString name; ZigString message; ZigString sourceURL; int32_t line; int32_t column; ZigString stack; void* exception; } ZigException;
\\typedef union ErrorableZigStringResult { ZigString value; ZigErrorType err; } ErrorableZigStringResult;
\\typedef struct ErrorableZigString { ErrorableZigStringResult result; bool success; } ErrorableZigString;
\\typedef struct ResolvedSource { ZigString specifier; ZigString source_code; ZigString source_url; uint32_t hash; uint32_t bytecodecache_fd; } ResolvedSource;
\\typedef union ErrorableResolvedSourceResult { ResolvedSource value; ZigErrorType err; } ErrorableResolvedSourceResult;
\\typedef struct ErrorableResolvedSource { ErrorableResolvedSourceResult result; bool success; } ErrorableResolvedSource;
\\
\\#ifdef __cplusplus
\\#include "root.h"
\\#include <JavaScriptCore/JSClassRef.h>
\\#endif
\\#include "headers-handwritten.h"
\\
) catch {};

View File

@@ -1,4 +1,4 @@
//-- AUTOGENERATED FILE -- 1627603981
//-- AUTOGENERATED FILE -- 1627867755
// clang-format off
#pragma once
@@ -224,8 +224,8 @@ extern "C" const size_t Zig__GlobalObject_object_align_ = alignof(Zig::GlobalObj
extern "C" const size_t Zig__ConsoleClient_object_size_ = sizeof(Zig::ConsoleClient);
extern "C" const size_t Zig__ConsoleClient_object_align_ = alignof(Zig::ConsoleClient);
const size_t sizes[27] = {sizeof(JSC::JSObject), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::CallFrame), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(Zig::GlobalObject), sizeof(ZigException)};
const size_t sizes[28] = {sizeof(JSC::JSObject), sizeof(ZigString), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::CallFrame), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(Zig::GlobalObject), sizeof(ZigException)};
const char* names[27] = {"JSC__JSObject", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__CallFrame", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "Zig__GlobalObject", "ZigException"};
const char* names[28] = {"JSC__JSObject", "ZigString", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__CallFrame", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "Zig__GlobalObject", "ZigException"};
const size_t aligns[27] = {alignof(JSC::JSObject), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::CallFrame), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(Zig::GlobalObject), alignof(ZigException)};
const size_t aligns[28] = {alignof(JSC::JSObject), alignof(ZigString), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::CallFrame), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(Zig::GlobalObject), alignof(ZigException)};

View File

@@ -0,0 +1,95 @@
typedef uint16_t ZigErrorCode;
typedef struct ZigString {
const unsigned char *ptr;
size_t len;
} ZigString;
typedef struct ZigErrorType {
ZigErrorCode code;
void *ptr;
} ZigErrorType;
typedef union ErrorableZigStringResult {
ZigString value;
ZigErrorType err;
} ErrorableZigStringResult;
typedef struct ErrorableZigString {
ErrorableZigStringResult result;
bool success;
} ErrorableZigString;
typedef struct ResolvedSource {
ZigString specifier;
ZigString source_code;
ZigString source_url;
uint32_t hash;
uint32_t bytecodecache_fd;
} ResolvedSource;
typedef union ErrorableResolvedSourceResult {
ResolvedSource value;
ZigErrorType err;
} ErrorableResolvedSourceResult;
typedef struct ErrorableResolvedSource {
ErrorableResolvedSourceResult result;
bool success;
} ErrorableResolvedSource;
typedef uint8_t ZigStackFrameCode;
const ZigStackFrameCode ZigStackFrameCodeNone = 0;
const ZigStackFrameCode ZigStackFrameCodeEval = 1;
const ZigStackFrameCode ZigStackFrameCodeModule = 2;
const ZigStackFrameCode ZigStackFrameCodeFunction = 3;
const ZigStackFrameCode ZigStackFrameCodeGlobal = 4;
const ZigStackFrameCode ZigStackFrameCodeWasm = 5;
const ZigStackFrameCode ZigStackFrameCodeConstructor = 6;
typedef struct ZigStackFramePosition {
int32_t source_offset;
int32_t line;
int32_t line_start;
int32_t line_stop;
int32_t column_start;
int32_t column_stop;
int32_t expression_start;
int32_t expression_stop;
} ZigStackFramePosition;
typedef struct ZigStackFrame {
ZigString function_name;
ZigString source_url;
ZigStackFramePosition position;
ZigStackFrameCode code_type;
} ZigStackFrame;
typedef struct ZigStackTrace {
ZigString *source_lines_ptr;
int32_t *source_lines_numbers;
uint8_t source_lines_len;
uint8_t source_lines_to_collect;
ZigStackFrame *frames_ptr;
uint8_t frames_len;
} ZigStackTrace;
typedef struct ZigException {
unsigned char code;
uint16_t runtime_type;
ZigString name;
ZigString message;
ZigStackTrace stack;
void *exception;
} ZigException;
typedef uint8_t JSErrorCode;
const JSErrorCode JSErrorCodeError = 0;
const JSErrorCode JSErrorCodeEvalError = 1;
const JSErrorCode JSErrorCodeRangeError = 2;
const JSErrorCode JSErrorCodeReferenceError = 3;
const JSErrorCode JSErrorCodeSyntaxError = 4;
const JSErrorCode JSErrorCodeTypeError = 5;
const JSErrorCode JSErrorCodeURIError = 6;
const JSErrorCode JSErrorCodeAggregateError = 7;
const JSErrorCode JSErrorCodeOutOfMemoryError = 8;
const JSErrorCode JSErrorCodeStackOverflow = 253;
const JSErrorCode JSErrorCodeUserErrorCode = 254;
#ifdef __cplusplus
extern "C" ZigErrorCode Zig_ErrorCodeParserError;
#endif

File diff suppressed because one or more lines are too long

View File

@@ -124,9 +124,9 @@ static ZigString toZigString(JSC::Identifier *str, JSC::JSGlobalObject *global)
static WTF::StringView toStringView(ZigString str) { return WTF::StringView(str.ptr, str.len); }
static void throwException(JSC::ThrowScope &scope, ZigString msg, JSC::JSGlobalObject *global) {
auto str = toJSString(msg, global);
scope.throwException(global, JSC::Exception::create(global->vm(), JSC::JSValue(str)));
static void throwException(JSC::ThrowScope &scope, ZigErrorType err, JSC::JSGlobalObject *global) {
scope.throwException(
global, JSC::Exception::create(global->vm(), JSC::JSValue((JSC::EncodedJSValue)err.ptr)));
}
static ZigString toZigString(JSC::JSValue val, JSC::JSGlobalObject *global) {
@@ -144,6 +144,4 @@ static ZigString toZigString(JSC::JSValue val, JSC::JSGlobalObject *global) {
return toZigString(str);
}
static ZigException ZigExceptionNone = ZigException{
0, 0, ZigStringEmpty, ZigStringEmpty, ZigStringEmpty, -1, -1, ZigStringEmpty, nullptr};
} // namespace Zig
}; // namespace Zig

View File

@@ -4,6 +4,7 @@ symbol_name: []const u8,
local_name: []const u8,
Parent: type,
pub fn Decl(comptime this: *const @This()) std.builtin.TypeInfo.Declaration {
return comptime std.meta.declarationInfo(this.Parent, this.local_name);
}

View File

@@ -11,7 +11,7 @@ const Bundler = @import("../../bundler.zig").ServeBundler;
const js_printer = @import("../../js_printer.zig");
const hash_map = @import("../../hash_map.zig");
const http = @import("../../http.zig");
const ImportKind = ast.ImportKind;
usingnamespace @import("./node_env_buf_map.zig");
usingnamespace @import("./base.zig");
usingnamespace @import("./webcore/response.zig");
@@ -26,8 +26,12 @@ pub const GlobalClasses = [_]type{
Response.Class,
Headers.Class,
EventListenerMixin.addEventListener(VirtualMachine),
BuildError.Class,
ResolveError.Class,
};
pub const LazyClasses = [_]type{};
pub const Module = struct {
reload_pending: bool = false,
};
@@ -106,7 +110,12 @@ pub const VirtualMachine = struct {
threadlocal var source_code_printer: js_printer.BufferPrinter = undefined;
threadlocal var source_code_printer_loaded: bool = false;
inline fn _fetch(global: *JSGlobalObject, specifier: string, source: string) !ResolvedSource {
inline fn _fetch(
global: *JSGlobalObject,
specifier: string,
source: string,
log: *logger.Log,
) !ResolvedSource {
std.debug.assert(VirtualMachine.vm_loaded);
std.debug.assert(VirtualMachine.vm.global == global);
@@ -158,6 +167,10 @@ pub const VirtualMachine = struct {
}
}
var old = vm.bundler.log;
vm.bundler.log = log;
defer vm.bundler.log = old;
var parse_result = vm.bundler.parse(
vm.bundler.allocator,
path,
@@ -202,7 +215,7 @@ pub const VirtualMachine = struct {
return ResolvedSource{
.source_code = ZigString.init(vm.allocator.dupe(u8, source_code_printer.ctx.written) catch unreachable),
.specifier = ZigString.init(specifier),
.source_url = ZigString.init(path.pretty),
.source_url = ZigString.init(path.text),
.hash = 0,
.bytecodecache_fd = 0,
};
@@ -211,7 +224,7 @@ pub const VirtualMachine = struct {
return ResolvedSource{
.source_code = ZigString.init(try strings.quotedAlloc(VirtualMachine.vm.allocator, path.pretty)),
.specifier = ZigString.init(path.text),
.source_url = ZigString.init(path.pretty),
.source_url = ZigString.init(path.text),
.hash = 0,
.bytecodecache_fd = 0,
};
@@ -295,15 +308,32 @@ pub const VirtualMachine = struct {
return ErrorableZigString.ok(ZigString.init(result));
}
pub fn fetch(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableResolvedSource {
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) void {
var log = logger.Log.init(vm.bundler.allocator);
const result = _fetch(global, specifier.slice(), source.slice()) catch |err| {
return ErrorableResolvedSource.errFmt(err, "{s}: \"{s}\"", .{
@errorName(err),
specifier.slice(),
});
switch (err) {
error.ParserError => {
std.debug.assert(log.msgs.items.len > 0);
switch (log.msgs.items.len) {
1 => {
return ErrorableResolvedSource.err(error.ParserError, BuildError.create(vm.bundler.allocator, &log.msgs.items[0]));
},
else => {
},
}
},
else => {
ret.* = ErrorableResolvedSource.errFmt(err, "{s}: \"{s}\"", .{
@errorName(err),
specifier.slice(),
});
},
}
};
return ErrorableResolvedSource.ok(result);
ret.* = ErrorableResolvedSource.ok(result);
}
pub fn loadEntryPoint(this: *VirtualMachine, entry_point: string) !void {
@@ -318,15 +348,179 @@ pub const VirtualMachine = struct {
}
if (promise.status(this.global.vm()) == JSPromise.Status.Rejected) {
var exception = promise.result(this.global.vm()).toZigException(this.global);
Output.prettyErrorln("<r><red>{s}<r><d>:<r> <b>{s}<r>\n<blue>{s}<r>:{d}:{d}\n{s}", .{
exception.name.slice(),
exception.message.slice(),
exception.sourceURL.slice(),
exception.line,
exception.column,
exception.stack.slice(),
});
var exception_holder = ZigException.Holder.init();
var exception = exception_holder.zigException();
promise.result(this.global.vm()).toZigException(vm.global, exception);
var stderr: std.fs.File = Output.errorStream();
var buffered = std.io.bufferedWriter(stderr.writer());
var writer = buffered.writer();
defer buffered.flush() catch unreachable;
// We are going to print the stack trace backwards
const stack = exception.stack.frames();
if (stack.len > 0) {
var i = @intCast(i16, stack.len - 1);
var func_name_pad: usize = 0;
while (i >= 0) : (i -= 1) {
const frame = stack[@intCast(usize, i)];
func_name_pad = std.math.max(func_name_pad, std.fmt.count("{any}", .{
frame.nameFormatter(true),
}));
}
i = @intCast(i16, stack.len - 1);
while (i >= 0) : (i -= 1) {
const frame = stack[@intCast(usize, i)];
const file = frame.source_url.slice();
const func = frame.function_name.slice();
try writer.print(" {any}", .{frame.sourceURLFormatter(true)});
try writer.writeAll(" in ");
try writer.print(" {any}\n", .{frame.nameFormatter(true)});
// if (!frame.position.isInvalid()) {
// if (func.len > 0) {
// writer.print(
// comptime Output.prettyFmt("<r><d>{s}<r> {s}{s} - {s}:{d}:{d}\n", true),
// .{
// if (i > 1) "↓" else "↳",
// frame.code_type.ansiColor(),
// func,
// file,
// frame.position.line,
// frame.position.column_start,
// },
// ) catch unreachable;
// } else {
// writer.print(comptime Output.prettyFmt("<r><d>{s}<r> {u} - {s}{s}:{d}:{d}\n", true), .{
// if (i > 1) "↓" else "↳",
// frame.code_type.emoji(),
// frame.code_type.ansiColor(),
// file,
// frame.position.line,
// frame.position.column_start,
// }) catch unreachable;
// }
// } else {
// if (func.len > 0) {
// writer.print(
// comptime Output.prettyFmt("<r><d>{s}<r> {s}{s} - {s}\n", true),
// .{
// if (i > 1) "↓" else "↳",
// frame.code_type.ansiColor(),
// func,
// file,
// },
// ) catch unreachable;
// } else {
// writer.print(
// comptime Output.prettyFmt("<r><d>{s}<r> {u} - {s}{s}\n", true),
// .{
// if (i > 1) "↓" else "↳",
// frame.code_type.emoji(),
// frame.code_type.ansiColor(),
// file,
// },
// ) catch unreachable;
// }
// }
}
}
var line_numbers = exception.stack.source_lines_numbers[0..exception.stack.source_lines_len];
var max_line: i32 = -1;
for (line_numbers) |line| max_line = std.math.max(max_line, line);
const max_line_number_pad = std.fmt.count("{d}", .{max_line});
var source_lines = exception.stack.sourceLineIterator();
var last_pad: u64 = 0;
while (source_lines.untilLast()) |source| {
const int_size = std.fmt.count("{d}", .{source.line});
const pad = max_line_number_pad - int_size;
last_pad = pad;
writer.writeByteNTimes(' ', pad) catch unreachable;
writer.print(
comptime Output.prettyFmt("<r><d>{d} | <r>{s}\n", true),
.{
source.line,
std.mem.trim(u8, source.text, "\n"),
},
) catch unreachable;
}
const name = exception.name.slice();
const message = exception.message.slice();
var did_print_name = false;
if (source_lines.next()) |source| {
const int_size = std.fmt.count("{d}", .{source.line});
const pad = max_line_number_pad - int_size;
writer.writeByteNTimes(' ', pad) catch unreachable;
std.debug.assert(!stack[0].position.isInvalid());
var remainder = std.mem.trim(u8, source.text, "\n");
const prefix = remainder[0..@intCast(usize, stack[0].position.column_start)];
const underline = remainder[@intCast(usize, stack[0].position.column_start)..@intCast(usize, stack[0].position.column_stop)];
const suffix = remainder[@intCast(usize, stack[0].position.column_stop)..];
writer.print(
comptime Output.prettyFmt("<r><d>{d} |<r> {s}<red>{s}<r>{s}<r>\n<r>", true),
.{
source.line,
prefix,
underline,
suffix,
},
) catch unreachable;
var first_non_whitespace = @intCast(u32, stack[0].position.column_start);
while (first_non_whitespace < source.text.len and source.text[first_non_whitespace] == ' ') {
first_non_whitespace += 1;
}
std.debug.assert(stack.len > 0);
const indent = @intCast(usize, pad) + " | ".len + first_non_whitespace + 1;
writer.writeByteNTimes(' ', indent) catch unreachable;
writer.print(comptime Output.prettyFmt(
"<red><b>^<r>\n",
true,
), .{}) catch unreachable;
if (name.len > 0 and message.len > 0) {
writer.print(comptime Output.prettyFmt(" <r><red><b>{s}<r><d>:<r> <b>{s}<r>\n", true), .{
name,
message,
}) catch unreachable;
} else if (name.len > 0) {
writer.print(comptime Output.prettyFmt(" <r><b>{s}<r>\n", true), .{name}) catch unreachable;
} else if (message.len > 0) {
writer.print(comptime Output.prettyFmt(" <r><b>{s}<r>\n", true), .{message}) catch unreachable;
}
did_print_name = true;
}
if (!did_print_name) {
if (name.len > 0 and message.len > 0) {
writer.print(comptime Output.prettyFmt("<r><red><b>{s}<r><d>:<r> <b>{s}<r>\n", true), .{
name,
message,
}) catch unreachable;
} else if (name.len > 0) {
writer.print(comptime Output.prettyFmt("<r><b>{s}<r>\n", true), .{name}) catch unreachable;
} else if (message.len > 0) {
writer.print(comptime Output.prettyFmt("<r><b>{s}<r>\n", true), .{name}) catch unreachable;
}
}
// Output.prettyErrorln("<r><red>{s}<r><d>:<r> <b>{s}<r>\n<blue>{s}<r>:{d}:{d}\n{s}", .{
// exception.name.slice(),
// exception.message.slice(),
// exception.sourceURL.slice(),
// exception.line,
// exception.column,
// exception.stack.slice(),
// });
}
}
};
@@ -411,11 +605,7 @@ pub const EventListenerMixin = struct {
var fetch_args: [1]js.JSObjectRef = undefined;
for (listeners.items) |listener| {
fetch_args[0] = js.JSObjectMake(
vm.ctx,
FetchEvent.Class.get().*,
fetch_event,
);
fetch_args[0] = FetchEvent.Class.make(vm.global, fetch_event);
_ = js.JSObjectCallAsFunction(
vm.ctx,
@@ -510,3 +700,281 @@ pub const EventListenerMixin = struct {
);
}
};
pub const ResolveError = struct {
msg: logger.Msg,
allocator: *std.mem.Allocator,
referrer: ?Fs.Path = null,
pub const Class = NewClass(
ResolveError,
.{
.name = "ResolveError",
.read_only = true,
},
.{
.@"referrer" = .{
.@"get" = getReferrer,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
.@"message" = .{
.@"get" = getMessage,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
.@"name" = .{
.@"get" = getName,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
.@"specifier" = .{
.@"get" = getSpecifier,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
.@"importKind" = .{
.@"get" = getImportKind,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
.@"position" = .{
.@"get" = getPosition,
.ro = true,
.ts = d.ts{ .@"return" = "string" },
},
},
.{},
);
pub fn create(
msg: logger.Msg,
allocator: *std.mem.Allocator,
) js.JSObjectRef {
var resolve_error = allocator.create(ResolveError) catch unreachable;
resolve_error.* = ResolveError{
.msg = msg,
.allocator = allocator,
};
return Class.make(VirtualMachine.vm.global, resolve_error);
}
pub fn getPosition(
this: *ResolveError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return BuildError.generatePositionObject(this.msg, ctx, exception);
}
pub fn getMessage(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(this.msg.data.text).toValue(VirtualMachine.vm.global);
}
pub fn getSpecifier(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(this.msg.metadata.Resolve.specifier.slice(this.msg.data.text)).toValue(VirtualMachine.vm.global);
}
pub fn getImportKind(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(@tagName(this.msg.metadata.Resolve.import_kind)).toValue(VirtualMachine.vm.global);
}
pub fn getReferrer(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
if (this.referrer) |referrer| {
return ZigString.init(referrer.text).toValue(VirtualMachine.vm.global);
} else {
return js.JSValueMakeNull(ctx);
}
}
const BuildErrorName = "ResolveError";
pub fn getName(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(BuildErrorName).toValue(VirtualMachine.vm.global);
}
};
pub const BuildError = struct {
msg: logger.Msg,
// resolve_result: resolver.Result,
allocator: *std.mem.Allocator,
pub const Class = NewClass(
BuildError,
.{
.name = "BuildError",
.read_only = true,
},
.{},
.{
.@"message" = .{
.@"get" = getMessage,
.ro = true,
},
.@"name" = .{
.@"get" = getName,
.ro = true,
},
// This is called "position" instead of "location" because "location" may be confused with Location.
.@"position" = .{
.@"get" = getPosition,
.ro = true,
},
},
);
pub fn create(
allocator: *std.mem.Allocator,
msg: *const logger.Msg,
// resolve_result: *const resolver.Result,
) js.JSObjectRef {
var build_error = allocator.create(BuildError) catch unreachable;
build_error.* = BuildError{
.msg = msg.*,
// .resolve_result = resolve_result.*,
.allocator = allocator,
};
return Class.make(VirtualMachine.vm.global, build_error);
}
pub fn getPosition(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return generatePositionObject(this.msg, ctx, exception);
}
pub const PositionProperties = struct {
const _file = ZigString.init("file");
var file_ptr: js.JSStringRef = null;
pub fn file() js.JSStringRef {
if (file_ptr == null) {
file_ptr = _file.toJSStringRef();
}
return file_ptr.?;
}
const _namespace = ZigString.init("namespace");
var namespace_ptr: js.JSStringRef = null;
pub fn namespace() js.JSStringRef {
if (namespace_ptr == null) {
namespace_ptr = _namespace.toJSStringRef();
}
return namespace_ptr.?;
}
const _line = ZigString.init("line");
var line_ptr: js.JSStringRef = null;
pub fn line() js.JSStringRef {
if (line_ptr == null) {
line_ptr = _line.toJSStringRef();
}
return line_ptr.?;
}
const _column = ZigString.init("column");
var column_ptr: js.JSStringRef = null;
pub fn column() js.JSStringRef {
if (column_ptr == null) {
column_ptr = _column.toJSStringRef();
}
return column_ptr.?;
}
const _length = ZigString.init("length");
var length_ptr: js.JSStringRef = null;
pub fn length() js.JSStringRef {
if (length_ptr == null) {
length_ptr = _length.toJSStringRef();
}
return length_ptr.?;
}
const _lineText = ZigString.init("lineText");
var lineText_ptr: js.JSStringRef = null;
pub fn lineText() js.JSStringRef {
if (lineText_ptr == null) {
lineText_ptr = _lineText.toJSStringRef();
}
return lineText_ptr.?;
}
const _offset = ZigString.init("offset");
var offset_ptr: js.JSStringRef = null;
pub fn offset() js.JSStringRef {
if (offset_ptr == null) {
offset_ptr = _offset.toJSStringRef();
}
return offset_ptr.?;
}
};
pub fn generatePositionObject(msg: logger.Msg, ctx: js.JSContextRef, exception: ExceptionValueRef) js.JSValue {
if (msg.data.location) |location| {
const ref = js.JSObjectMake(ctx, null, null);
js.JSObjectSetProperty(ctx, ref, PositionProperties.lineText(), ZigString.init(location.line_text orelse "").toJSStringRef(), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.file(), ZigString.init(location.file).toJSStringRef(), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.namespace(), ZigString.init(location.namespace).toJSStringRef(), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.line(), js.JSValueMakeNumber(ctx, location.line), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.column(), js.JSValueMakeNumber(ctx, location.column), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.length(), js.JSValueMakeNumber(ctx, location.length), 0, exception);
js.JSObjectSetProperty(ctx, ref, PositionProperties.offset(), js.JSValueMakeNumber(ctx, location.offset), 0, exception);
return ref;
}
return js.JSValueMakeNull(ctx);
}
pub fn getMessage(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(this.msg.data.text).toValue(VirtualMachine.vm.global);
}
const BuildErrorName = "BuildError";
pub fn getName(
this: *BuildError,
ctx: js.JSContextRef,
thisObject: js.JSObjectRef,
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return ZigString.init(BuildErrorName).toValue(VirtualMachine.vm.global);
}
};
pub const JSPrivateDataTag = JSPrivateDataPtr.Tag;

View File

@@ -121,13 +121,16 @@ pub const Response = struct {
// return null;
// }
var response = getAllocator(ctx).create(Response) catch return null;
var tup = Repsonse.Class.makeObject(
ctx,
getAllocator(ctx),
);
response.* = Response{
tup.ptr.* = Response{
.body = body,
.allocator = getAllocator(ctx),
};
return js.JSObjectMake(ctx, Response.Class.get().*, response);
return tup.ref;
}
};
@@ -290,7 +293,7 @@ pub const Headers = struct {
};
}
return js.JSObjectMake(ctx, Headers.Class.get().*, headers);
return Headers.Class.make(ctx, headers);
}
pub fn finalize(
@@ -922,7 +925,7 @@ pub const Request = struct {
this.headers = Headers.fromRequestCtx(getAllocator(ctx), this.request_context) catch unreachable;
}
return js.JSObjectMake(ctx, Headers.Class.get().*, &this.headers.?);
return Headers.Class.make(ctx, &this.headers.?);
}
pub fn getIntegrity(
this: *Request,
@@ -1068,7 +1071,7 @@ pub const FetchEvent = struct {
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
return js.JSObjectMake(ctx, Request.Class.get().*, &this.request);
return Request.Class.make(ctx, &this.request);
}
// https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith
@@ -1096,14 +1099,11 @@ pub const FetchEvent = struct {
return js.JSValueMakeUndefined(ctx);
}
var ptr = js.JSObjectGetPrivate(arg);
if (ptr == null) {
var response: *Response = GetJSPrivateData(Response, arg) orelse {
JSError(getAllocator(ctx), "event.respondWith()'s Response object was invalid. This may be an internal error.", .{}, ctx, exception);
this.request_context.sendInternalError(error.respondWithWasInvalid) catch {};
return js.JSValueMakeUndefined(ctx);
}
var response = @ptrCast(*Response, @alignCast(@alignOf(*Response), ptr.?));
};
var needs_mime_type = true;
var content_length: ?usize = null;