Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specification compliant ToString (to_string) #425

Merged
merged 1 commit into from
Jun 1, 2020
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
26 changes: 13 additions & 13 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,17 +311,17 @@ impl Array {
///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.join
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
pub(crate) fn join(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub(crate) fn join(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let separator = if args.is_empty() {
String::from(",")
} else {
args.get(0).expect("Could not get argument").to_string()
ctx.to_string(args.get(0).expect("Could not get argument"))?
};

let mut elem_strs: Vec<String> = Vec::new();
let length = i32::from(&this.get_field("length"));
for n in 0..length {
let elem_str: String = this.get_field(n.to_string()).to_string();
let elem_str: String = ctx.to_string(&this.get_field(n.to_string()))?;
elem_strs.push(elem_str);
}

Expand All @@ -344,15 +344,15 @@ impl Array {
pub(crate) fn to_string(
this: &mut Value,
_args: &[Value],
_ctx: &mut Interpreter,
ctx: &mut Interpreter,
) -> ResultValue {
let method_name = "join";
let mut arguments = vec![Value::from(",")];
// 2.
let mut method = this.get_field(method_name);
// 3.
if !method.is_function() {
method = _ctx
method = ctx
.realm
.global_obj
.get_field("Object")
Expand All @@ -362,15 +362,15 @@ impl Array {
arguments = Vec::new();
}
// 4.
let join_result = _ctx.call(&method, this, &arguments);
let match_string = match join_result {
Ok(v) => match *v {
ValueData::String(ref s) => (*s).clone(),
_ => "".to_string(),
},
Err(v) => format!("error: {}", v),
let join = ctx.call(&method, this, &arguments)?;

let string = if let ValueData::String(ref s) = join.data() {
Value::from(s.as_str())
} else {
Value::from("")
};
Ok(Value::from(match_string))

Ok(string)
}

/// `Array.prototype.reverse()`
Expand Down
21 changes: 17 additions & 4 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl BigInt {
return Err(RangeError::run_new(
format!(
"{} can't be converted to BigInt because it isn't an integer",
value
ctx.to_string(value)?
),
ctx,
)?);
Expand All @@ -64,6 +64,18 @@ impl BigInt {
Ok(data)
}

#[inline]
#[allow(clippy::wrong_self_convention)]
HalidOdat marked this conversation as resolved.
Show resolved Hide resolved
pub(crate) fn to_native_string_radix(bigint: &AstBigInt, radix: u32) -> String {
bigint.to_str_radix(radix)
}

#[inline]
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_native_string(bigint: &AstBigInt) -> String {
bigint.to_string()
}

/// `BigInt.prototype.toString( [radix] )`
///
/// The `toString()` method returns a string representing the specified BigInt object.
Expand Down Expand Up @@ -91,9 +103,10 @@ impl BigInt {
ctx,
)?);
}
Ok(Value::from(
this.to_bigint().unwrap().to_str_radix(radix as u32),
))
Ok(Value::from(Self::to_native_string_radix(
&this.to_bigint().unwrap(),
radix as u32,
)))
}

/// `BigInt.prototype.valueOf()`
Expand Down
102 changes: 68 additions & 34 deletions boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ pub fn logger(msg: LogMessage, console_state: &ConsoleState) {
}

/// This represents the `console` formatter.
pub fn formatter(data: &[Value]) -> String {
let target = get_arg_at_index::<String>(data, 0).unwrap_or_default();
pub fn formatter(data: &[Value], ctx: &mut Interpreter) -> Result<String, Value> {
let target = ctx.to_string(&data.get(0).cloned().unwrap_or_default())?;
match data.len() {
0 => String::new(),
1 => target,
0 => Ok(String::new()),
1 => Ok(target),
_ => {
let mut formatted = String::new();
let mut arg_index = 1;
Expand Down Expand Up @@ -103,7 +103,7 @@ pub fn formatter(data: &[Value]) -> String {
/* string */
's' => {
let arg =
get_arg_at_index::<String>(data, arg_index).unwrap_or_default();
ctx.to_string(&data.get(arg_index).cloned().unwrap_or_default())?;
formatted.push_str(&arg);
arg_index += 1
}
Expand All @@ -124,7 +124,7 @@ pub fn formatter(data: &[Value]) -> String {
formatted.push_str(&format!(" {}", rest))
}

formatted
Ok(formatted)
}
}
}
Expand All @@ -140,7 +140,7 @@ pub fn formatter(data: &[Value]) -> String {
///
/// [spec]: https://console.spec.whatwg.org/#assert
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/assert
pub fn assert(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub fn assert(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let assertion = get_arg_at_index::<bool>(args, 0).unwrap_or_default();

if !assertion {
Expand All @@ -155,9 +155,10 @@ pub fn assert(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVa
args[0] = Value::from(concat);
}

this.with_internal_state_ref(|state| {
logger(LogMessage::Error(formatter(&args[..])), state)
});
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Error(formatter(&args, ctx)?), state);
Ok(())
})?;
}

Ok(Value::undefined())
Expand Down Expand Up @@ -191,8 +192,11 @@ pub fn clear(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue
///
/// [spec]: https://console.spec.whatwg.org/#debug
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/debug
pub fn debug(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref(|state| logger(LogMessage::Log(formatter(&args[..])), state));
pub fn debug(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Ok(())
})?;
Ok(Value::undefined())
}

Expand All @@ -206,8 +210,11 @@ pub fn debug(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVal
///
/// [spec]: https://console.spec.whatwg.org/#error
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/error
pub fn error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref(|state| logger(LogMessage::Error(formatter(&args[..])), state));
pub fn error(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Error(formatter(args, ctx)?), state);
Ok(())
})?;
Ok(Value::undefined())
}

Expand All @@ -221,8 +228,11 @@ pub fn error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVal
///
/// [spec]: https://console.spec.whatwg.org/#info
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/info
pub fn info(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref(|state| logger(LogMessage::Info(formatter(&args[..])), state));
pub fn info(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Info(formatter(args, ctx)?), state);
Ok(())
})?;
Ok(Value::undefined())
}

Expand All @@ -236,8 +246,11 @@ pub fn info(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValu
///
/// [spec]: https://console.spec.whatwg.org/#log
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/log
pub fn log(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref(|state| logger(LogMessage::Log(formatter(&args[..])), state));
pub fn log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Ok(())
})?;
Ok(Value::undefined())
}

Expand All @@ -251,9 +264,12 @@ pub fn log(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue
///
/// [spec]: https://console.spec.whatwg.org/#trace
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/trace
pub fn trace(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub fn trace(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.with_internal_state_ref(|state| logger(LogMessage::Log(formatter(&args[..])), state));
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Ok(())
})?;

/* TODO: get and print stack trace */
this.with_internal_state_ref(|state| {
Expand All @@ -277,8 +293,11 @@ pub fn trace(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVal
///
/// [spec]: https://console.spec.whatwg.org/#warn
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/warn
pub fn warn(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref(|state| logger(LogMessage::Warn(formatter(&args[..])), state));
pub fn warn(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Warn(formatter(args, ctx)?), state);
Ok(())
})?;
Ok(Value::undefined())
}

Expand All @@ -292,8 +311,11 @@ pub fn warn(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValu
///
/// [spec]: https://console.spec.whatwg.org/#count
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/count
pub fn count(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let label = get_arg_at_index::<String>(args, 0).unwrap_or_else(|| "default".to_string());
pub fn count(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
let msg = format!("count {}:", &label);
Expand All @@ -316,8 +338,11 @@ pub fn count(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVal
///
/// [spec]: https://console.spec.whatwg.org/#countreset
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/countReset
pub fn count_reset(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let label = get_arg_at_index::<String>(args, 0).unwrap_or_else(|| "default".to_string());
pub fn count_reset(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
state.count_map.remove(&label);
Expand Down Expand Up @@ -346,8 +371,11 @@ fn system_time_in_ms() -> u128 {
///
/// [spec]: https://console.spec.whatwg.org/#time
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/time
pub fn time(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let label = get_arg_at_index::<String>(args, 0).unwrap_or_else(|| "default".to_string());
pub fn time(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
if state.timer_map.get(&label).is_some() {
Expand All @@ -374,8 +402,11 @@ pub fn time(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValu
///
/// [spec]: https://console.spec.whatwg.org/#timelog
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeLog
pub fn time_log(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let label = get_arg_at_index::<String>(args, 0).unwrap_or_else(|| "default".to_string());
pub fn time_log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
if let Some(t) = state.timer_map.get(&label) {
Expand Down Expand Up @@ -406,8 +437,11 @@ pub fn time_log(this: &mut Value, args: &[Value], _: &mut Interpreter) -> Result
///
/// [spec]: https://console.spec.whatwg.org/#timeend
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeEnd
pub fn time_end(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let label = get_arg_at_index::<String>(args, 0).unwrap_or_else(|| "default".to_string());
pub fn time_end(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
if let Some(t) = state.timer_map.remove(&label) {
Expand Down Expand Up @@ -437,8 +471,8 @@ pub fn time_end(this: &mut Value, args: &[Value], _: &mut Interpreter) -> Result
///
/// [spec]: https://console.spec.whatwg.org/#group
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/group
pub fn group(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let group_label = formatter(args);
pub fn group(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let group_label = formatter(args, ctx)?;

this.with_internal_state_mut(|state: &mut ConsoleState| {
logger(LogMessage::Info(format!("group: {}", &group_label)), state);
Expand Down
Loading