mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
refactor(napi/oxlint, napi/parser): remove source length from RawTransferMetadata (#12483)
Refactor to oxlint JS plugins and raw transfer. Remove source text length field from `RawTransferMetadata`. It's not necessary - source text is part of `Program`, so the length can be obtained from there, it doesn't need to be duplicated.
This commit is contained in:
1 parent
7c75dba281
commit
f0b1f0d485
12 files changed
+68
-72
No files matched your search
@@ -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 }),
|
||||
@@ -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 }),
|
||||
|
||||
@@ -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")))]
|
||||
|
||||
@@ -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`.
|
||||
@@ -318,10 +316,8 @@ 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")))]
|
||||
@@ -329,8 +325,8 @@ 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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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 =
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -1029,13 +1032,12 @@ 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!("
|
||||
@@ -1043,16 +1045,16 @@ fn generate_constants(consts: Constants) -> (String, TokenStream) {
|
||||
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,
|
||||
}};
|
||||
");
|
||||
|
||||
@@ -1085,7 +1087,6 @@ 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);
|
||||
@@ -1093,13 +1094,11 @@ fn get_constants(schema: &Schema) -> Constants {
|
||||
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;
|
||||
|
||||
@@ -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")
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user