1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#[cfg(test)]
mod tests;
use crate::{
builtins::{
function::NativeFunctionData,
object::{internal_methods_trait::ObjectInternalMethods, Object, ObjectKind, PROTOTYPE},
value::{to_value, ResultValue, Value, ValueData},
},
exec::Interpreter,
};
use std::{borrow::Borrow, ops::Deref};
pub fn construct_boolean(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.set_kind(ObjectKind::Boolean);
if let Some(ref value) = args.get(0) {
this.set_internal_slot("BooleanData", to_boolean(value));
} else {
this.set_internal_slot("BooleanData", to_boolean(&to_value(false)));
}
Ok(this.clone())
}
pub fn call_boolean(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
match args.get(0) {
Some(ref value) => Ok(to_boolean(value)),
None => Ok(to_boolean(&to_value(false))),
}
}
pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
let b = this_boolean_value(this);
Ok(to_value(b.to_string()))
}
pub fn value_of(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(this_boolean_value(this))
}
pub fn create_constructor(global: &Value) -> Value {
let mut boolean = Object::default();
boolean.kind = ObjectKind::Function;
boolean.set_internal_method("construct", construct_boolean);
boolean.set_internal_method("call", call_boolean);
let boolean_prototype = ValueData::new_obj(Some(global));
boolean_prototype.set_internal_slot("BooleanData", to_boolean(&to_value(false)));
make_builtin_fn!(to_string, named "toString", of boolean_prototype);
make_builtin_fn!(value_of, named "valueOf", of boolean_prototype);
let boolean_value = to_value(boolean);
boolean_prototype.set_field_slice("constructor", to_value(boolean_value.clone()));
boolean_value.set_field_slice(PROTOTYPE, boolean_prototype);
boolean_value
}
pub fn to_boolean(value: &Value) -> Value {
match *value.deref().borrow() {
ValueData::Object(_) => to_value(true),
ValueData::String(ref s) if !s.is_empty() => to_value(true),
ValueData::Number(n) if n != 0.0 && !n.is_nan() => to_value(true),
ValueData::Integer(n) if n != 0 => to_value(true),
ValueData::Boolean(v) => to_value(v),
_ => to_value(false),
}
}
pub fn this_boolean_value(value: &Value) -> Value {
match *value.deref().borrow() {
ValueData::Boolean(v) => to_value(v),
ValueData::Object(ref v) => (v).deref().borrow().get_internal_slot("BooleanData"),
_ => to_value(false),
}
}