Skip to content

Commit dae748d

Browse files
authored
Added Support for External Latin1 Strings (#481)
* Added Support for External Latin1 Strings Signed-off-by: Redfire <redfire75369@hotmail.com> * Reformatted C++ Files with clang-format Added 80 Column Limit to .clang-format Signed-off-by: Redfire <redfire75369@hotmail.com> * Bumped mozjs-sys Version Fixed Some Compiler Warnings Signed-off-by: Redfire <redfire75369@hotmail.com> * Added External String Tests Signed-off-by: Redfire <redfire75369@hotmail.com> --------- Signed-off-by: Redfire <redfire75369@hotmail.com>
1 parent 69c3a51 commit dae748d

File tree

6 files changed

+136
-23
lines changed

6 files changed

+136
-23
lines changed

.clang-format

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# Taken from https://searchfox.org/mozilla-central/rev/aa1bb4f0ca8bfda4b117d1befca47b72d5dd6d5d/.clang-format
1+
# Adapted from https://hg.mozilla.org/mozilla-central/file/12bd668f66103e727d3198e600cb25aa4ea8b6dc/.clang-format
22

33
BasedOnStyle: Google
4+
ColumnLimit: 80
45

56
IndentPPDirectives: AfterHash
67
StatementMacros: [MARKUPMAP, ASSERT_TRUE, ASSERT_FALSE, TEST, CHECK]
78

89
DerivePointerAlignment: false
9-
PointerAlignment: Left
10+
PointerAlignment: Left

mozjs-sys/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "mozjs_sys"
33
description = "System crate for the Mozilla SpiderMonkey JavaScript engine."
44
repository.workspace = true
5-
version = "0.128.0-7"
5+
version = "0.128.0-8"
66
authors = ["Mozilla"]
77
links = "mozjs"
88
build = "build.rs"

mozjs-sys/src/jsglue.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,13 @@ class RustReadableStreamUnderlyingSource
144144
};
145145

146146
struct JSExternalStringCallbacksTraps {
147-
void (*finalize)(const void* privateData, char16_t* chars);
148-
size_t (*sizeOfBuffer)(const void* privateData, const char16_t* chars,
149-
mozilla::MallocSizeOf mallocSizeOf);
147+
void (*latin1Finalize)(const void* privateData, JS::Latin1Char* chars);
148+
void (*utf16Finalize)(const void* privateData, char16_t* chars);
149+
size_t (*latin1SizeOfBuffer)(const void* privateData,
150+
const JS::Latin1Char* chars,
151+
mozilla::MallocSizeOf mallocSizeOf);
152+
size_t (*utf16SizeOfBuffer)(const void* privateData, const char16_t* chars,
153+
mozilla::MallocSizeOf mallocSizeOf);
150154
};
151155

152156
class RustJSExternalStringCallbacks final : public JSExternalStringCallbacks {
@@ -158,26 +162,22 @@ class RustJSExternalStringCallbacks final : public JSExternalStringCallbacks {
158162
void* privateData)
159163
: mTraps(aTraps), privateData(privateData) {}
160164

161-
void finalize(char16_t* chars) const override {
162-
return mTraps.finalize(privateData, chars);
165+
void finalize(JS::Latin1Char* chars) const override {
166+
return mTraps.latin1Finalize(privateData, chars);
163167
}
164168

165-
size_t sizeOfBuffer(const char16_t* chars,
166-
mozilla::MallocSizeOf mallocSizeOf) const override {
167-
return mTraps.sizeOfBuffer(privateData, chars, mallocSizeOf);
169+
void finalize(char16_t* chars) const override {
170+
return mTraps.utf16Finalize(privateData, chars);
168171
}
169172

170-
void finalize(JS::Latin1Char* chars) const override {
171-
MOZ_ASSERT(
172-
false,
173-
"Latin1Char is not implemented for RustJSExternalStringCallbacks");
173+
size_t sizeOfBuffer(const JS::Latin1Char* chars,
174+
mozilla::MallocSizeOf mallocSizeOf) const override {
175+
return mTraps.latin1SizeOfBuffer(privateData, chars, mallocSizeOf);
174176
}
175177

176-
size_t sizeOfBuffer(const JS::Latin1Char* chars,
178+
size_t sizeOfBuffer(const char16_t* chars,
177179
mozilla::MallocSizeOf mallocSizeOf) const override {
178-
MOZ_ASSERT(
179-
false,
180-
"Latin1Char is not implemented for RustJSExternalStringCallbacks");
180+
return mTraps.utf16SizeOfBuffer(privateData, chars, mallocSizeOf);
181181
}
182182
};
183183

mozjs/src/error.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use crate::jsapi::{JSContext, JSErrorFormatString, JSExnType, JS_ReportErrorNumberUTF8};
1010
use libc;
1111
use std::ffi::CString;
12+
use std::ptr::addr_of;
1213
use std::{mem, os, ptr};
1314

1415
/// Format string used to throw javascript errors.
@@ -43,8 +44,8 @@ unsafe extern "C" fn get_error_message(
4344
) -> *const JSErrorFormatString {
4445
let num: JSExnType = mem::transmute(error_number);
4546
match num {
46-
JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
47-
JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
47+
JSExnType::JSEXN_TYPEERR => addr_of!(TYPE_ERROR_FORMAT_STRING),
48+
JSExnType::JSEXN_RANGEERR => addr_of!(RANGE_ERROR_FORMAT_STRING),
4849
_ => panic!(
4950
"Bad js error number given to get_error_message: {}",
5051
error_number

mozjs/src/rust.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use crate::jsapi::MutableHandleIdVector as RawMutableHandleIdVector;
4444
use crate::jsapi::{already_AddRefed, jsid};
4545
use crate::jsapi::{BuildStackString, CaptureCurrentStack, StackFormat};
4646
use crate::jsapi::{Evaluate2, HandleValueArray, StencilRelease};
47-
use crate::jsapi::{InitSelfHostedCode, InstantiationStorage, IsWindowSlow};
47+
use crate::jsapi::{InitSelfHostedCode, IsWindowSlow};
4848
use crate::jsapi::{
4949
JSAutoRealm, JS_SetGCParameter, JS_SetNativeStackQuota, JS_WrapObject, JS_WrapValue,
5050
};
@@ -498,7 +498,7 @@ unsafe impl Sync for Stencil {}*/
498498

499499
impl Drop for Stencil {
500500
fn drop(&mut self) {
501-
if (self.is_null()) {
501+
if self.is_null() {
502502
return;
503503
}
504504
unsafe {

mozjs/tests/external_string.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
use std::ffi::c_void;
6+
use std::ptr;
7+
8+
use mozjs::conversions::jsstr_to_string;
9+
use mozjs::glue::{CreateJSExternalStringCallbacks, JSExternalStringCallbacksTraps};
10+
use mozjs::jsapi::{
11+
JSAutoRealm, JS_NewExternalStringLatin1, JS_NewExternalUCString, JS_NewGlobalObject,
12+
OnNewGlobalHookOption,
13+
};
14+
use mozjs::rooted;
15+
use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS};
16+
17+
#[test]
18+
fn external_string() {
19+
let engine = JSEngine::init().unwrap();
20+
let runtime = Runtime::new(engine.handle());
21+
let context = runtime.cx();
22+
let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
23+
let c_option = RealmOptions::default();
24+
25+
unsafe {
26+
rooted!(in(context) let global = JS_NewGlobalObject(
27+
context,
28+
&SIMPLE_GLOBAL_CLASS,
29+
ptr::null_mut(),
30+
h_option,
31+
&*c_option,
32+
));
33+
let _ac = JSAutoRealm::new(context, global.get());
34+
35+
let latin1_base = "test latin-1";
36+
let latin1_boxed = latin1_base.as_bytes().to_vec().into_boxed_slice();
37+
let latin1_chars = Box::into_raw(latin1_boxed).cast::<u8>();
38+
39+
let callbacks = CreateJSExternalStringCallbacks(
40+
&EXTERNAL_STRING_CALLBACKS_TRAPS,
41+
latin1_base.len() as *mut c_void,
42+
);
43+
rooted!(in(context) let latin1_jsstr = JS_NewExternalStringLatin1(
44+
context,
45+
latin1_chars,
46+
latin1_base.len(),
47+
callbacks
48+
));
49+
assert_eq!(jsstr_to_string(context, latin1_jsstr.get()), latin1_base);
50+
51+
let utf16_base = "test utf-16 $€ \u{10437}\u{24B62}";
52+
let utf16_boxed = utf16_base
53+
.encode_utf16()
54+
.collect::<Vec<_>>()
55+
.into_boxed_slice();
56+
let utf16_len = utf16_boxed.len();
57+
let utf16_chars = Box::into_raw(utf16_boxed).cast::<u16>();
58+
59+
let callbacks = CreateJSExternalStringCallbacks(
60+
&EXTERNAL_STRING_CALLBACKS_TRAPS,
61+
utf16_len as *mut c_void,
62+
);
63+
rooted!(in(context) let utf16_jsstr = JS_NewExternalUCString(
64+
context,
65+
utf16_chars,
66+
utf16_len,
67+
callbacks
68+
));
69+
assert_eq!(jsstr_to_string(context, utf16_jsstr.get()), utf16_base);
70+
}
71+
}
72+
73+
static EXTERNAL_STRING_CALLBACKS_TRAPS: JSExternalStringCallbacksTraps =
74+
JSExternalStringCallbacksTraps {
75+
latin1Finalize: Some(latin1::finalize),
76+
latin1SizeOfBuffer: Some(latin1::size_of),
77+
utf16Finalize: Some(utf16::finalize),
78+
utf16SizeOfBuffer: Some(utf16::size_of),
79+
};
80+
81+
mod latin1 {
82+
use std::ffi::c_void;
83+
use std::slice;
84+
85+
use mozjs::jsapi::mozilla::MallocSizeOf;
86+
87+
pub unsafe extern "C" fn finalize(data: *const c_void, chars: *mut u8) {
88+
let slice = slice::from_raw_parts_mut(chars, data as usize);
89+
let _ = Box::from_raw(slice);
90+
}
91+
92+
pub unsafe extern "C" fn size_of(data: *const c_void, _: *const u8, _: MallocSizeOf) -> usize {
93+
data as usize
94+
}
95+
}
96+
97+
mod utf16 {
98+
use std::ffi::c_void;
99+
use std::slice;
100+
101+
use mozjs::jsapi::mozilla::MallocSizeOf;
102+
103+
pub unsafe extern "C" fn finalize(data: *const c_void, chars: *mut u16) {
104+
let slice = slice::from_raw_parts_mut(chars, data as usize);
105+
let _ = Box::from_raw(slice);
106+
}
107+
108+
pub unsafe extern "C" fn size_of(data: *const c_void, _: *const u16, _: MallocSizeOf) -> usize {
109+
data as usize
110+
}
111+
}

0 commit comments

Comments
 (0)