Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/oxc_ast_macros/src/generated/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub static STRUCTS: phf::Map<&'static str, StructDetails> = ::phf::Map {
("DebuggerStatement", StructDetails { field_order: None }),
("CommentNodeId", StructDetails { field_order: None }),
("Character", StructDetails { field_order: Some(&[0, 2, 1]) }),
("RawTransferMetadata2", StructDetails { field_order: Some(&[0, 3, 1, 2]) }),
("RawTransferMetadata2", StructDetails { field_order: Some(&[1, 2, 0]) }),
("StringLiteral", StructDetails { field_order: None }),
("TSInferType", StructDetails { field_order: None }),
("TSThisType", StructDetails { field_order: None }),
Expand Down Expand Up @@ -243,7 +243,7 @@ pub static STRUCTS: phf::Map<&'static str, StructDetails> = ::phf::Map {
("SpreadElement", StructDetails { field_order: None }),
("MetaProperty", StructDetails { field_order: None }),
("TSIntersectionType", StructDetails { field_order: None }),
("RawTransferMetadata", StructDetails { field_order: Some(&[0, 3, 1, 2]) }),
("RawTransferMetadata", StructDetails { field_order: Some(&[1, 2, 0]) }),
("ConditionalExpression", StructDetails { field_order: None }),
("PrivateInExpression", StructDetails { field_order: None }),
("TSStringKeyword", StructDetails { field_order: None }),
Expand Down
14 changes: 6 additions & 8 deletions crates/oxc_linter/src/generated/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@ use crate::*;
const _: () = {
// Padding: 3 bytes
assert!(size_of::<RawTransferMetadata2>() == 16);
assert!(align_of::<RawTransferMetadata2>() == 4);
assert!(offset_of!(RawTransferMetadata2, data_offset) == 0);
assert!(align_of::<RawTransferMetadata2>() == 8);
assert!(offset_of!(RawTransferMetadata2, data_offset) == 8);
assert!(offset_of!(RawTransferMetadata2, is_ts) == 12);
assert!(offset_of!(RawTransferMetadata2, source_len) == 4);
assert!(offset_of!(RawTransferMetadata2, _padding) == 8);
assert!(offset_of!(RawTransferMetadata2, _padding) == 0);
};

#[cfg(target_pointer_width = "32")]
const _: () = {
// Padding: 3 bytes
assert!(size_of::<RawTransferMetadata2>() == 16);
assert!(align_of::<RawTransferMetadata2>() == 4);
assert!(offset_of!(RawTransferMetadata2, data_offset) == 0);
assert!(align_of::<RawTransferMetadata2>() == 8);
assert!(offset_of!(RawTransferMetadata2, data_offset) == 8);
assert!(offset_of!(RawTransferMetadata2, is_ts) == 12);
assert!(offset_of!(RawTransferMetadata2, source_len) == 4);
assert!(offset_of!(RawTransferMetadata2, _padding) == 8);
assert!(offset_of!(RawTransferMetadata2, _padding) == 0);
};

#[cfg(not(any(target_pointer_width = "64", target_pointer_width = "32")))]
Expand Down
14 changes: 5 additions & 9 deletions crates/oxc_linter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,11 @@ impl Linter {
// `external_linter` always exists when `oxlint2` feature is enabled
let external_linter = self.external_linter.as_ref().unwrap();

// Write offset of `Program` and source text length in metadata at end of buffer
// Write offset of `Program` in metadata at end of buffer
let program = semantic.nodes().program().unwrap();
let program_offset = ptr::from_ref(program) as u32;
#[expect(clippy::cast_possible_truncation)]
let source_len = program.source_text.len() as u32;

let metadata = RawTransferMetadata::new(program_offset, source_len);
let metadata = RawTransferMetadata::new(program_offset);
let metadata_ptr = allocator.end_ptr().cast::<RawTransferMetadata>();
// SAFETY: `Allocator` was created by `FixedSizeAllocator` which reserved space after `end_ptr`
// for a `RawTransferMetadata`. `end_ptr` is aligned for `FixedSizeAllocator`.
Expand Down Expand Up @@ -318,19 +316,17 @@ struct RawTransferMetadata2 {
pub data_offset: u32,
/// `true` if AST is TypeScript.
pub is_ts: bool,
/// Offset of `u32` containing source text length within buffer.
pub(crate) source_len: u32,
/// Padding to pad struct to size 16.
pub(crate) _padding: u32,
pub(crate) _padding: u64,
}

#[cfg(all(feature = "oxlint2", not(feature = "disable_oxlint2")))]
use RawTransferMetadata2 as RawTransferMetadata;

#[cfg(all(feature = "oxlint2", not(feature = "disable_oxlint2")))]
impl RawTransferMetadata {
pub fn new(data_offset: u32, source_len: u32) -> Self {
Self { data_offset, is_ts: false, source_len, _padding: 0 }
pub fn new(data_offset: u32) -> Self {
Self { data_offset, is_ts: false, _padding: 0 }
}
}

Expand Down
8 changes: 4 additions & 4 deletions napi/oxlint2/src-js/generated/constants.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

const BUFFER_SIZE = 2147483616,
BUFFER_ALIGN = 4294967296,
DATA_POINTER_POS_32 = 536870900,
DATA_POINTER_POS_32 = 536870902,
IS_TS_FLAG_POS = 2147483612,
SOURCE_LEN_POS_32 = 536870901,
PROGRAM_OFFSET = 0;
PROGRAM_OFFSET = 0,
SOURCE_LEN_OFFSET = 16;

module.exports = {
BUFFER_SIZE,
BUFFER_ALIGN,
DATA_POINTER_POS_32,
IS_TS_FLAG_POS,
SOURCE_LEN_POS_32,
PROGRAM_OFFSET,
SOURCE_LEN_OFFSET,
};
7 changes: 4 additions & 3 deletions napi/oxlint2/src-js/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createRequire } from 'node:module';
import { lint } from './bindings.js';
import { DATA_POINTER_POS_32, SOURCE_LEN_POS_32 } from './generated/constants.cjs';
import { DATA_POINTER_POS_32, SOURCE_LEN_OFFSET } from './generated/constants.cjs';
import { getErrorMessage } from './utils.js';
import { addVisitorToCompiled, compiledVisitor, finalizeCompiledVisitor, initCompiledVisitor } from './visitor.js';

Expand Down Expand Up @@ -167,8 +167,9 @@ function lintFile([filePath, bufferId, buffer, ruleIds]) {
// Some rules seen in the wild return an empty visitor object from `create` if some initial check fails
// e.g. file extension is not one the rule acts on.
if (needsVisit) {
const programPos = buffer.uint32[DATA_POINTER_POS_32],
sourceByteLen = buffer.uint32[SOURCE_LEN_POS_32];
const { uint32 } = buffer,
programPos = uint32[DATA_POINTER_POS_32],
sourceByteLen = uint32[(programPos + SOURCE_LEN_OFFSET) >> 2];

const sourceText = textDecoder.decode(buffer.subarray(0, sourceByteLen));
const sourceIsAscii = sourceText.length === sourceByteLen;
Expand Down
8 changes: 4 additions & 4 deletions napi/parser/generated/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

const BUFFER_SIZE = 2147483616,
BUFFER_ALIGN = 4294967296,
DATA_POINTER_POS_32 = 536870900,
DATA_POINTER_POS_32 = 536870902,
IS_TS_FLAG_POS = 2147483612,
SOURCE_LEN_POS_32 = 536870901,
PROGRAM_OFFSET = 0;
PROGRAM_OFFSET = 0,
SOURCE_LEN_OFFSET = 16;

module.exports = {
BUFFER_SIZE,
BUFFER_ALIGN,
DATA_POINTER_POS_32,
IS_TS_FLAG_POS,
SOURCE_LEN_POS_32,
PROGRAM_OFFSET,
SOURCE_LEN_OFFSET,
};
12 changes: 6 additions & 6 deletions napi/parser/generated/deserialize/js.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function deserialize(buffer, sourceTextInput, sourceByteLenInput) {
sourceByteLen = sourceByteLenInput;
sourceIsAscii = sourceText.length === sourceByteLen;

const data = deserializeRawTransferData(uint32[536870900]);
const data = deserializeRawTransferData(uint32[536870902]);

uint8 =
uint32 =
Expand Down Expand Up @@ -5238,16 +5238,16 @@ function deserializeBoxTSExternalModuleReference(pos) {
return deserializeTSExternalModuleReference(uint32[pos >> 2]);
}

function deserializeOptionNameSpan(pos) {
if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null;
return deserializeNameSpan(pos);
}

function deserializeU64(pos) {
const pos32 = pos >> 2;
return uint32[pos32] + uint32[pos32 + 1] * 4294967296;
}

function deserializeOptionNameSpan(pos) {
if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null;
return deserializeNameSpan(pos);
}

function deserializeOptionU64(pos) {
if (uint8[pos] === 0) return null;
return deserializeU64(pos + 8);
Expand Down
12 changes: 6 additions & 6 deletions napi/parser/generated/deserialize/ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function deserialize(buffer, sourceTextInput, sourceByteLenInput) {
sourceByteLen = sourceByteLenInput;
sourceIsAscii = sourceText.length === sourceByteLen;

const data = deserializeRawTransferData(uint32[536870900]);
const data = deserializeRawTransferData(uint32[536870902]);

uint8 =
uint32 =
Expand Down Expand Up @@ -5369,16 +5369,16 @@ function deserializeBoxTSExternalModuleReference(pos) {
return deserializeTSExternalModuleReference(uint32[pos >> 2]);
}

function deserializeOptionNameSpan(pos) {
if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null;
return deserializeNameSpan(pos);
}

function deserializeU64(pos) {
const pos32 = pos >> 2;
return uint32[pos32] + uint32[pos32 + 1] * 4294967296;
}

function deserializeOptionNameSpan(pos) {
if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null;
return deserializeNameSpan(pos);
}

function deserializeOptionU64(pos) {
if (uint8[pos] === 0) return null;
return deserializeU64(pos + 8);
Expand Down
10 changes: 5 additions & 5 deletions napi/parser/generated/lazy/constructors.js
Original file line number Diff line number Diff line change
Expand Up @@ -13752,17 +13752,17 @@ function constructBoxTSExternalModuleReference(pos, ast) {
return new TSExternalModuleReference(ast.buffer.uint32[pos >> 2], ast);
}

function constructOptionNameSpan(pos, ast) {
if (ast.buffer.uint32[(pos + 8) >> 2] === 0 && ast.buffer.uint32[(pos + 12) >> 2] === 0) return null;
return new NameSpan(pos, ast);
}

function constructU64(pos, ast) {
const { uint32 } = ast.buffer,
pos32 = pos >> 2;
return uint32[pos32] + uint32[pos32 + 1] * 4294967296;
}

function constructOptionNameSpan(pos, ast) {
if (ast.buffer.uint32[(pos + 8) >> 2] === 0 && ast.buffer.uint32[(pos + 12) >> 2] === 0) return null;
return new NameSpan(pos, ast);
}

function constructOptionU64(pos, ast) {
if (ast.buffer[pos] === 0) return null;
return constructU64(pos + 8, ast);
Expand Down
14 changes: 6 additions & 8 deletions napi/parser/src/generated/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ const _: () = {

// Padding: 3 bytes
assert!(size_of::<RawTransferMetadata>() == 16);
assert!(align_of::<RawTransferMetadata>() == 4);
assert!(offset_of!(RawTransferMetadata, data_offset) == 0);
assert!(align_of::<RawTransferMetadata>() == 8);
assert!(offset_of!(RawTransferMetadata, data_offset) == 8);
assert!(offset_of!(RawTransferMetadata, is_ts) == 12);
assert!(offset_of!(RawTransferMetadata, source_len) == 4);
assert!(offset_of!(RawTransferMetadata, _padding) == 8);
assert!(offset_of!(RawTransferMetadata, _padding) == 0);

// Padding: 7 bytes
assert!(size_of::<Error>() == 80);
Expand Down Expand Up @@ -78,11 +77,10 @@ const _: () = {

// Padding: 3 bytes
assert!(size_of::<RawTransferMetadata>() == 16);
assert!(align_of::<RawTransferMetadata>() == 4);
assert!(offset_of!(RawTransferMetadata, data_offset) == 0);
assert!(align_of::<RawTransferMetadata>() == 8);
assert!(offset_of!(RawTransferMetadata, data_offset) == 8);
assert!(offset_of!(RawTransferMetadata, is_ts) == 12);
assert!(offset_of!(RawTransferMetadata, source_len) == 4);
assert!(offset_of!(RawTransferMetadata, _padding) == 8);
assert!(offset_of!(RawTransferMetadata, _padding) == 0);

// Padding: 3 bytes
assert!(size_of::<Error>() == 44);
Expand Down
7 changes: 2 additions & 5 deletions napi/parser/src/raw_transfer_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,13 @@ pub struct RawTransferMetadata {
pub data_offset: u32,
/// `true` if AST is TypeScript.
pub is_ts: bool,
/// Offset of `u32` containing source text length within buffer.
/// Not used in this implementation. Used by `napi/oxlint2`.
pub(crate) source_len: u32,
/// Padding to pad struct to size 16.
pub(crate) _padding: u32,
pub(crate) _padding: u64,
}

impl RawTransferMetadata {
pub fn new(data_offset: u32, is_ts: bool) -> Self {
Self { data_offset, is_ts, source_len: 0, _padding: 0 }
Self { data_offset, is_ts, _padding: 0 }
}
}

Expand Down
30 changes: 18 additions & 12 deletions tasks/ast_tools/src/generators/raw_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ use crate::{

use super::define_generator;

/// Offset of length field in `&str`
const STR_LEN_OFFSET: u32 = 8;

/// Bytes reserved for `malloc`'s metadata
const MALLOC_RESERVED_SIZE: u32 = 16;

Expand Down Expand Up @@ -1015,10 +1018,10 @@ struct Constants {
data_pointer_pos: u32,
/// Offset within buffer of `bool` indicating if AST is TS or JS
is_ts_pos: u32,
/// Offset within buffer of `u32` containing position of `u32` containing source text length
source_len_pos: u32,
/// Offset of `Program` in buffer, relative to position of `RawTransferData`
program_offset: u32,
/// Offset of `u32` source text length, relative to position of `Program`
source_len_offset: u32,
/// Size of `RawTransferData` in bytes
raw_metadata_size: u32,
}
Expand All @@ -1029,30 +1032,29 @@ fn generate_constants(consts: Constants) -> (String, TokenStream) {
buffer_size,
data_pointer_pos,
is_ts_pos,
source_len_pos,
program_offset,
source_len_offset,
raw_metadata_size,
} = consts;

let data_pointer_pos_32 = data_pointer_pos / 4;
let source_len_pos_32 = source_len_pos / 4;

#[rustfmt::skip]
let js_output = format!("
const BUFFER_SIZE = {buffer_size},
BUFFER_ALIGN = {BLOCK_ALIGN},
DATA_POINTER_POS_32 = {data_pointer_pos_32},
IS_TS_FLAG_POS = {is_ts_pos},
SOURCE_LEN_POS_32 = {source_len_pos_32},
PROGRAM_OFFSET = {program_offset};
PROGRAM_OFFSET = {program_offset},
SOURCE_LEN_OFFSET = {source_len_offset};

module.exports = {{
BUFFER_SIZE,
BUFFER_ALIGN,
DATA_POINTER_POS_32,
IS_TS_FLAG_POS,
SOURCE_LEN_POS_32,
PROGRAM_OFFSET,
SOURCE_LEN_OFFSET,
}};
");

Expand Down Expand Up @@ -1085,21 +1087,18 @@ fn get_constants(schema: &Schema) -> Constants {

let mut data_offset_field = None;
let mut is_ts_field = None;
let mut source_len_field = None;
for (field1, field2) in raw_metadata_struct.fields.iter().zip(&raw_metadata2_struct.fields) {
assert_eq!(field1.name(), field2.name());
assert_eq!(field1.type_id, field2.type_id);
assert_eq!(field1.offset_64(), field2.offset_64());
match field1.name() {
"data_offset" => data_offset_field = Some(field1),
"is_ts" => is_ts_field = Some(field1),
"source_len" => source_len_field = Some(field1),
_ => {}
}
}
let data_offset_field = data_offset_field.unwrap();
let is_ts_field = is_ts_field.unwrap();
let source_len_field = source_len_field.unwrap();

let raw_metadata_size = raw_metadata_struct.layout_64().size;

Expand All @@ -1115,7 +1114,6 @@ fn get_constants(schema: &Schema) -> Constants {
let raw_metadata_pos = buffer_size - raw_metadata_size;
let data_pointer_pos = raw_metadata_pos + data_offset_field.offset_64();
let is_ts_pos = raw_metadata_pos + is_ts_field.offset_64();
let source_len_pos = raw_metadata_pos + source_len_field.offset_64();

let program_offset = schema
.type_by_name("RawTransferData")
Expand All @@ -1124,12 +1122,20 @@ fn get_constants(schema: &Schema) -> Constants {
.field_by_name("program")
.offset_64();

let source_len_offset = schema
.type_by_name("Program")
.as_struct()
.unwrap()
.field_by_name("source_text")
.offset_64()
+ STR_LEN_OFFSET;

Constants {
buffer_size,
data_pointer_pos,
is_ts_pos,
source_len_pos,
program_offset,
source_len_offset,
raw_metadata_size,
}
}
Loading