Skip to content

Commit

Permalink
Implement Latin1 JsString (#3450)
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored May 1, 2024
1 parent 6febf7e commit 3f6ee22
Show file tree
Hide file tree
Showing 151 changed files with 3,778 additions and 2,495 deletions.
9 changes: 4 additions & 5 deletions cli/src/debug/function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use boa_engine::{
builtins::function::OrdinaryFunction,
js_string,
js_str, js_string,
object::ObjectInitializer,
vm::flowgraph::{Direction, Graph},
Context, JsArgs, JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
Expand Down Expand Up @@ -68,10 +68,9 @@ fn flowgraph(_this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResu
let mut direction = Direction::LeftToRight;
if let Some(arguments) = args.get(1) {
if let Some(arguments) = arguments.as_object() {
format = flowgraph_parse_format_option(&arguments.get(js_string!("format"), context)?)?;
direction = flowgraph_parse_direction_option(
&arguments.get(js_string!("direction"), context)?,
)?;
format = flowgraph_parse_format_option(&arguments.get(js_str!("format"), context)?)?;
direction =
flowgraph_parse_direction_option(&arguments.get(js_str!("direction"), context)?)?;
} else if value.is_string() {
format = flowgraph_parse_format_option(value)?;
} else {
Expand Down
20 changes: 10 additions & 10 deletions cli/src/debug/limits.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use boa_engine::{
js_string,
js_str,
object::{FunctionObjectBuilder, ObjectInitializer},
property::Attribute,
Context, JsArgs, JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
Expand Down Expand Up @@ -51,51 +51,51 @@ fn set_recursion(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResu
pub(super) fn create_object(context: &mut Context) -> JsObject {
let get_loop =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_loop))
.name("get loop")
.name(js_str!("get loop"))
.length(0)
.build();
let set_loop =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_loop))
.name("set loop")
.name(js_str!("set loop"))
.length(1)
.build();

let get_stack =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_stack))
.name("get stack")
.name(js_str!("get stack"))
.length(0)
.build();
let set_stack =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_stack))
.name("set stack")
.name(js_str!("set stack"))
.length(1)
.build();

let get_recursion =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_recursion))
.name("get recursion")
.name(js_str!("get recursion"))
.length(0)
.build();
let set_recursion =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_recursion))
.name("set recursion")
.name(js_str!("set recursion"))
.length(1)
.build();
ObjectInitializer::new(context)
.accessor(
js_string!("loop"),
js_str!("loop"),
Some(get_loop),
Some(set_loop),
Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
)
.accessor(
js_string!("stack"),
js_str!("stack"),
Some(get_stack),
Some(set_stack),
Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
)
.accessor(
js_string!("recursion"),
js_str!("recursion"),
Some(get_recursion),
Some(set_recursion),
Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
Expand Down
25 changes: 16 additions & 9 deletions cli/src/debug/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Allow lint so it, doesn't warn about `JsResult<>` unneeded return on functions.
#![allow(clippy::unnecessary_wraps)]

use boa_engine::{js_string, object::ObjectInitializer, property::Attribute, Context, JsObject};
use boa_engine::{js_str, object::ObjectInitializer, property::Attribute, Context, JsObject};

mod function;
mod gc;
Expand All @@ -10,6 +10,7 @@ mod object;
mod optimizer;
mod realm;
mod shape;
mod string;

fn create_boa_object(context: &mut Context) -> JsObject {
let function_module = function::create_object(context);
Expand All @@ -19,43 +20,49 @@ fn create_boa_object(context: &mut Context) -> JsObject {
let gc_module = gc::create_object(context);
let realm_module = realm::create_object(context);
let limits_module = limits::create_object(context);
let string_module = string::create_string(context);

ObjectInitializer::new(context)
.property(
js_string!("function"),
js_str!("function"),
function_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("object"),
js_str!("object"),
object_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("shape"),
js_str!("shape"),
shape_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("optimizer"),
js_str!("optimizer"),
optimizer_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("gc"),
js_str!("gc"),
gc_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("realm"),
js_str!("realm"),
realm_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_string!("limits"),
js_str!("limits"),
limits_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
js_str!("string"),
string_module,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.build()
}

Expand All @@ -64,7 +71,7 @@ pub(crate) fn init_boa_debug_object(context: &mut Context) {
let boa_object = create_boa_object(context);
context
.register_global_property(
js_string!("$boa"),
js_str!("$boa"),
boa_object,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
Expand Down
6 changes: 3 additions & 3 deletions cli/src/debug/optimizer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use boa_engine::{
js_string,
js_str,
object::{FunctionObjectBuilder, ObjectInitializer},
optimizer::OptimizerOptions,
property::Attribute,
Expand Down Expand Up @@ -64,13 +64,13 @@ pub(super) fn create_object(context: &mut Context) -> JsObject {
.build();
ObjectInitializer::new(context)
.accessor(
js_string!("constantFolding"),
js_str!("constantFolding"),
Some(get_constant_folding),
Some(set_constant_folding),
Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
)
.accessor(
js_string!("statistics"),
js_str!("statistics"),
Some(get_statistics),
Some(set_statistics),
Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
Expand Down
93 changes: 93 additions & 0 deletions cli/src/debug/string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use boa_engine::{
js_string, object::ObjectInitializer, property::Attribute, string::JsStrVariant, Context,
JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
};

fn storage(_: &JsValue, args: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
let Some(value) = args.first() else {
return Err(JsNativeError::typ()
.with_message("expected string argument")
.into());
};

let Some(string) = value.as_string() else {
return Err(JsNativeError::typ()
.with_message(format!("expected string, got {}", value.type_of()))
.into());
};

let storage = if string.is_static() { "static" } else { "heap" };
Ok(js_string!(storage).into())
}

fn encoding(_: &JsValue, args: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
let Some(value) = args.first() else {
return Err(JsNativeError::typ()
.with_message("expected string argument")
.into());
};

let Some(string) = value.as_string() else {
return Err(JsNativeError::typ()
.with_message(format!("expected string, got {}", value.type_of()))
.into());
};

let str = string.as_str();
let encoding = match str.variant() {
JsStrVariant::Latin1(_) => "latin1",
JsStrVariant::Utf16(_) => "utf16",
};
Ok(js_string!(encoding).into())
}

fn summary(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
let Some(value) = args.first() else {
return Err(JsNativeError::typ()
.with_message("expected string argument")
.into());
};

let Some(string) = value.as_string() else {
return Err(JsNativeError::typ()
.with_message(format!("expected string, got {}", value.type_of()))
.into());
};

let storage = if string.is_static() { "static" } else { "heap" };
let encoding = match string.as_str().variant() {
JsStrVariant::Latin1(_) => "latin1",
JsStrVariant::Utf16(_) => "utf16",
};

let summary = ObjectInitializer::new(context)
.property(js_string!("storage"), js_string!(storage), Attribute::all())
.property(
js_string!("encoding"),
js_string!(encoding),
Attribute::all(),
)
.build();

Ok(summary.into())
}

pub(super) fn create_string(context: &mut Context) -> JsObject {
ObjectInitializer::new(context)
.function(
NativeFunction::from_fn_ptr(storage),
js_string!("storage"),
1,
)
.function(
NativeFunction::from_fn_ptr(encoding),
js_string!("encoding"),
1,
)
.function(
NativeFunction::from_fn_ptr(summary),
js_string!("summary"),
1,
)
.build()
}
18 changes: 17 additions & 1 deletion core/engine/src/bigint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Boa's implementation of ECMAScript's bigint primitive type.

use crate::{builtins::Number, error::JsNativeError, JsData, JsResult};
use crate::{builtins::Number, error::JsNativeError, JsData, JsResult, JsString};
use boa_gc::{Finalize, Trace};
use num_integer::Integer;
use num_traits::{pow::Pow, FromPrimitive, One, ToPrimitive, Zero};
Expand Down Expand Up @@ -89,6 +89,22 @@ impl JsBigInt {
})
}

/// Abstract operation `StringToBigInt ( str )`
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-stringtobigint
pub(crate) fn from_js_string(string: &JsString) -> Option<JsBigInt> {
// 1. Let text be ! StringToCodePoints(str).
// 2. Let literal be ParseText(text, StringIntegerLiteral).
// 3. If literal is a List of errors, return undefined.
// 4. Let mv be the MV of literal.
// 5. Assert: mv is an integer.
// 6. Return ℤ(mv).
JsBigInt::from_string(string.to_std_string().ok().as_ref()?)
}

/// This function takes a string and converts it to `BigInt` type.
///
/// More information:
Expand Down
3 changes: 2 additions & 1 deletion core/engine/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
Context, JsData, JsResult,
};
use boa_gc::{Finalize, Trace};
use boa_macros::js_str;
use boa_profiler::Profiler;

/// The Array Iterator object represents an iteration over an array. It implements the iterator protocol.
Expand Down Expand Up @@ -52,7 +53,7 @@ impl IntrinsicObject for ArrayIterator {
.static_method(Self::next, js_string!("next"), 0)
.static_property(
JsSymbol::to_string_tag(),
js_string!("Array Iterator"),
js_str!("Array Iterator"),
Attribute::CONFIGURABLE,
)
.build();
Expand Down
Loading

0 comments on commit 3f6ee22

Please sign in to comment.