Browse Source

Implement macro for setting builtin functions

* Add make_fn macro in builtins module

* Replace all array methods with the make_fn macro

* Set builtins method with make_fn for bool, console, error, json, math, number, object, regexp and string

* Rename make_fn macro to make_builtin_fn

* Rename the actual macro rule to make_builtin_fn

* make_builtin_fn macro without length will result to length 0

* Add length property for every builtin method

* Remove duplicate definition of toString method in regexp

* Add missing length attributes to builtins methods
pull/212/head
Stupremee 5 years ago committed by Iovoslav Iovchev
parent
commit
7698873157
  1. 51
      src/lib/builtins/array.rs
  2. 4
      src/lib/builtins/boolean.rs
  3. 2
      src/lib/builtins/error.rs
  4. 4
      src/lib/builtins/json.rs
  5. 38
      src/lib/builtins/math.rs
  6. 13
      src/lib/builtins/mod.rs
  7. 18
      src/lib/builtins/number.rs
  8. 15
      src/lib/builtins/object.rs
  9. 6
      src/lib/builtins/regexp.rs
  10. 44
      src/lib/builtins/string.rs

51
src/lib/builtins/array.rs

@ -661,41 +661,26 @@ pub fn create_constructor(global: &Value) -> Value {
// Create prototype // Create prototype
let array_prototype = ValueData::new_obj(None); let array_prototype = ValueData::new_obj(None);
let length = Property::default().get(to_value(get_array_length as NativeFunctionData)); let length = Property::default().get(to_value(get_array_length as NativeFunctionData));
array_prototype.set_prop_slice("length", length); array_prototype.set_prop_slice("length", length);
let concat_func = to_value(concat as NativeFunctionData);
concat_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(concat, named "concat", with length 1, of array_prototype);
array_prototype.set_field_slice("concat", concat_func); make_builtin_fn!(push, named "push", with length 1, of array_prototype);
let push_func = to_value(push as NativeFunctionData); make_builtin_fn!(index_of, named "indexOf", with length 1, of array_prototype);
push_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(last_index_of, named "lastIndexOf", with length 1, of array_prototype);
let index_of_func = to_value(index_of as NativeFunctionData); make_builtin_fn!(includes_value, named "includes", with length 1, of array_prototype);
index_of_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(map, named "map", with length 1, of array_prototype);
let last_index_of_func = to_value(last_index_of as NativeFunctionData); make_builtin_fn!(fill, named "fill", with length 1, of array_prototype);
last_index_of_func.set_field_slice("length", to_value(1_i32));
let includes_func = to_value(includes_value as NativeFunctionData); make_builtin_fn!(pop, named "pop", of array_prototype);
includes_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(join, named "join", with length 1, of array_prototype);
let map_func = to_value(map as NativeFunctionData); make_builtin_fn!(reverse, named "reverse", of array_prototype);
map_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(shift, named "shift", of array_prototype);
let fill_func = to_value(fill as NativeFunctionData); make_builtin_fn!(unshift, named "unshift", with length 1, of array_prototype);
fill_func.set_field_slice("length", to_value(1_i32)); make_builtin_fn!(every, named "every", with length 1, of array_prototype);
make_builtin_fn!(find, named "find", with length 1, of array_prototype);
array_prototype.set_field_slice("push", push_func); make_builtin_fn!(find_index, named "findIndex", with length 1, of array_prototype);
array_prototype.set_field_slice("pop", to_value(pop as NativeFunctionData)); make_builtin_fn!(slice, named "slice", with length 2, of array_prototype);
array_prototype.set_field_slice("join", to_value(join as NativeFunctionData));
array_prototype.set_field_slice("reverse", to_value(reverse as NativeFunctionData));
array_prototype.set_field_slice("shift", to_value(shift as NativeFunctionData));
array_prototype.set_field_slice("unshift", to_value(unshift as NativeFunctionData));
array_prototype.set_field_slice("every", to_value(every as NativeFunctionData));
array_prototype.set_field_slice("find", to_value(find as NativeFunctionData));
array_prototype.set_field_slice("findIndex", to_value(find_index as NativeFunctionData));
array_prototype.set_field_slice("includes", includes_func);
array_prototype.set_field_slice("indexOf", index_of_func);
array_prototype.set_field_slice("lastIndexOf", last_index_of_func);
array_prototype.set_field_slice("fill", fill_func);
array_prototype.set_field_slice("slice", to_value(slice as NativeFunctionData));
array_prototype.set_field_slice("map", map_func);
let array = to_value(array_constructor); let array = to_value(array_constructor);
array.set_field_slice(PROTOTYPE, to_value(array_prototype.clone())); array.set_field_slice(PROTOTYPE, to_value(array_prototype.clone()));

4
src/lib/builtins/boolean.rs

@ -56,8 +56,8 @@ pub fn create_constructor(global: &Value) -> Value {
// https://tc39.es/ecma262/#sec-properties-of-the-boolean-prototype-object // https://tc39.es/ecma262/#sec-properties-of-the-boolean-prototype-object
let boolean_prototype = ValueData::new_obj(Some(global)); let boolean_prototype = ValueData::new_obj(Some(global));
boolean_prototype.set_internal_slot("BooleanData", to_boolean(&to_value(false))); boolean_prototype.set_internal_slot("BooleanData", to_boolean(&to_value(false)));
boolean_prototype.set_field_slice("toString", to_value(to_string as NativeFunctionData)); make_builtin_fn!(to_string, named "toString", of boolean_prototype);
boolean_prototype.set_field_slice("valueOf", to_value(value_of as NativeFunctionData)); make_builtin_fn!(value_of, named "valueOf", of boolean_prototype);
let boolean_value = to_value(boolean); let boolean_value = to_value(boolean);
boolean_prototype.set_field_slice("constructor", to_value(boolean_value.clone())); boolean_prototype.set_field_slice("constructor", to_value(boolean_value.clone()));

2
src/lib/builtins/error.rs

@ -36,7 +36,7 @@ pub fn _create(global: &Value) -> Value {
let prototype = ValueData::new_obj(Some(global)); let prototype = ValueData::new_obj(Some(global));
prototype.set_field_slice("message", to_value("")); prototype.set_field_slice("message", to_value(""));
prototype.set_field_slice("name", to_value("Error")); prototype.set_field_slice("name", to_value("Error"));
prototype.set_field_slice("toString", to_value(to_string as NativeFunctionData)); make_builtin_fn!(to_string, named "toString", of prototype);
let error = to_value(make_error as NativeFunctionData); let error = to_value(make_error as NativeFunctionData);
error.set_field_slice(PROTOTYPE, prototype); error.set_field_slice(PROTOTYPE, prototype);
error error

4
src/lib/builtins/json.rs

@ -33,8 +33,8 @@ pub fn create_constructor(global: &Value) -> Value {
json.kind = ObjectKind::Ordinary; json.kind = ObjectKind::Ordinary;
let prototype = ValueData::new_obj(Some(global)); let prototype = ValueData::new_obj(Some(global));
prototype.set_field_slice("parse", to_value(parse as NativeFunctionData)); make_builtin_fn!(parse, named "parse", with length 2, of prototype);
prototype.set_field_slice("stringify", to_value(stringify as NativeFunctionData)); make_builtin_fn!(stringify, named "stringify", with length 3, of prototype);
let json_value = to_value(json); let json_value = to_value(json);
json_value.set_field_slice(PROTOTYPE, prototype); json_value.set_field_slice(PROTOTYPE, prototype);

38
src/lib/builtins/math.rs

@ -203,24 +203,24 @@ pub fn create_constructor(global: &Value) -> Value {
math.set_field_slice("SQRT1_2", to_value(0.5_f64.sqrt())); math.set_field_slice("SQRT1_2", to_value(0.5_f64.sqrt()));
math.set_field_slice("SQRT2", to_value(f64::consts::SQRT_2)); math.set_field_slice("SQRT2", to_value(f64::consts::SQRT_2));
math.set_field_slice("PI", to_value(f64::consts::PI)); math.set_field_slice("PI", to_value(f64::consts::PI));
math.set_field_slice("abs", to_value(abs as NativeFunctionData)); make_builtin_fn!(abs, named "abs", with length 1, of math);
math.set_field_slice("acos", to_value(acos as NativeFunctionData)); make_builtin_fn!(acos, named "acos", with length 1, of math);
math.set_field_slice("asin", to_value(asin as NativeFunctionData)); make_builtin_fn!(asin, named "asin", with length 1, of math);
math.set_field_slice("atan", to_value(atan as NativeFunctionData)); make_builtin_fn!(atan, named "atan", with length 1, of math);
math.set_field_slice("atan2", to_value(atan2 as NativeFunctionData)); make_builtin_fn!(atan2, named "atan2", with length 2, of math);
math.set_field_slice("cbrt", to_value(cbrt as NativeFunctionData)); make_builtin_fn!(cbrt, named "cbrt", with length 1, of math);
math.set_field_slice("ceil", to_value(ceil as NativeFunctionData)); make_builtin_fn!(ceil, named "ceil", with length 1, of math);
math.set_field_slice("cos", to_value(cos as NativeFunctionData)); make_builtin_fn!(cos, named "cos", with length 1, of math);
math.set_field_slice("exp", to_value(exp as NativeFunctionData)); make_builtin_fn!(exp, named "exp", with length 1, of math);
math.set_field_slice("floor", to_value(floor as NativeFunctionData)); make_builtin_fn!(floor, named "floor", with length 1, of math);
math.set_field_slice("log", to_value(log as NativeFunctionData)); make_builtin_fn!(log, named "log", with length 1, of math);
math.set_field_slice("max", to_value(max as NativeFunctionData)); make_builtin_fn!(max, named "max", with length 2, of math);
math.set_field_slice("min", to_value(min as NativeFunctionData)); make_builtin_fn!(min, named "min", with length 2, of math);
math.set_field_slice("pow", to_value(pow as NativeFunctionData)); make_builtin_fn!(pow, named "pow", with length 2, of math);
math.set_field_slice("random", to_value(_random as NativeFunctionData)); make_builtin_fn!(_random, named "random", of math);
math.set_field_slice("round", to_value(round as NativeFunctionData)); make_builtin_fn!(round, named "round", with length 1, of math);
math.set_field_slice("sin", to_value(sin as NativeFunctionData)); make_builtin_fn!(sin, named "sin", with length 1, of math);
math.set_field_slice("sqrt", to_value(sqrt as NativeFunctionData)); make_builtin_fn!(sqrt, named "sqrt", with length 1, of math);
math.set_field_slice("tan", to_value(tan as NativeFunctionData)); make_builtin_fn!(tan, named "tan", with length 1, of math);
math math
} }

13
src/lib/builtins/mod.rs

@ -1,3 +1,16 @@
/// Macro to create a new member function of a prototype
/// If no length is provided, the length will be set to 0.
macro_rules! make_builtin_fn {
($fn:ident, named $name:expr, with length $l:tt, of $p:ident) => {
let $fn = to_value($fn as NativeFunctionData);
$fn.set_field_slice("length", to_value($l));
$p.set_field_slice($name, $fn);
};
($fn:ident, named $name:expr, of $p:ident) => {
make_builtin_fn!($fn, named $name, with length 0, of $p);
};
}
/// The global `Array` object /// The global `Array` object
pub mod array; pub mod array;
/// the global `Symbol` Object /// the global `Symbol` Object

18
src/lib/builtins/number.rs

@ -145,18 +145,12 @@ pub fn create_constructor(global: &Value) -> Value {
number_prototype.set_internal_slot("NumberData", to_value(0)); number_prototype.set_internal_slot("NumberData", to_value(0));
number_prototype.set_field_slice( make_builtin_fn!(to_exponential, named "toExponential", with length 1, of number_prototype);
"toExponential", make_builtin_fn!(to_fixed, named "toFixed", with length 1, of number_prototype);
to_value(to_exponential as NativeFunctionData), make_builtin_fn!(to_locale_string, named "toLocaleString", of number_prototype);
); make_builtin_fn!(to_precision, named "toPrecision", with length 1, of number_prototype);
number_prototype.set_field_slice("toFixed", to_value(to_fixed as NativeFunctionData)); make_builtin_fn!(to_string, named "toString", with length 1, of number_prototype);
number_prototype.set_field_slice( make_builtin_fn!(value_of, named "valueOf", of number_prototype);
"toLocaleString",
to_value(to_locale_string as NativeFunctionData),
);
number_prototype.set_field_slice("toPrecision", to_value(to_precision as NativeFunctionData));
number_prototype.set_field_slice("toString", to_value(to_string as NativeFunctionData));
number_prototype.set_field_slice("valueOf", to_value(value_of as NativeFunctionData));
let number = to_value(number_constructor); let number = to_value(number_constructor);
number_prototype.set_field_slice("constructor", number.clone()); number_prototype.set_field_slice("constructor", number.clone());

15
src/lib/builtins/object.rs

@ -565,17 +565,8 @@ pub fn create_constructor(_: &Value) -> Value {
object.set_field_slice("length", to_value(1_i32)); object.set_field_slice("length", to_value(1_i32));
object.set_field_slice(PROTOTYPE, to_value(prototype)); object.set_field_slice(PROTOTYPE, to_value(prototype));
object.set_field_slice( make_builtin_fn!(set_proto_of, named "setPrototypeOf", with length 2, of object);
"setPrototypeOf", make_builtin_fn!(get_proto_of, named "getPrototypeOf", with length 1, of object);
to_value(set_proto_of as NativeFunctionData), make_builtin_fn!(define_prop, named "defineProperty", with length 3, of object);
);
object.set_field_slice(
"getPrototypeOf",
to_value(get_proto_of as NativeFunctionData),
);
object.set_field_slice(
"defineProperty",
to_value(define_prop as NativeFunctionData),
);
object object
} }

6
src/lib/builtins/regexp.rs

@ -336,9 +336,9 @@ pub fn create_constructor(global: &Value) -> Value {
// Create prototype // Create prototype
let proto = ValueData::new_obj(Some(global)); let proto = ValueData::new_obj(Some(global));
proto.set_field_slice("test", to_value(test as NativeFunctionData)); make_builtin_fn!(test, named "test", with length 1, of proto);
proto.set_field_slice("exec", to_value(exec as NativeFunctionData)); make_builtin_fn!(exec, named "exec", with length 1, of proto);
proto.set_field_slice("toString", to_value(to_string as NativeFunctionData)); make_builtin_fn!(to_string, named "toString", of proto);
proto.set_field_slice("lastIndex", to_value(0)); proto.set_field_slice("lastIndex", to_value(0));
proto.set_prop_slice("dotAll", _make_prop(get_dot_all)); proto.set_prop_slice("dotAll", _make_prop(get_dot_all));
proto.set_prop_slice("flags", _make_prop(get_flags)); proto.set_prop_slice("flags", _make_prop(get_flags));

44
src/lib/builtins/string.rs

@ -744,28 +744,28 @@ pub fn create_constructor(global: &Value) -> Value {
let prop = Property::default().get(to_value(get_string_length as NativeFunctionData)); let prop = Property::default().get(to_value(get_string_length as NativeFunctionData));
proto.set_prop_slice("length", prop); proto.set_prop_slice("length", prop);
proto.set_field_slice("charAt", to_value(char_at as NativeFunctionData)); make_builtin_fn!(char_at, named "charAt", with length 1, of proto);
proto.set_field_slice("charCodeAt", to_value(char_code_at as NativeFunctionData)); make_builtin_fn!(char_code_at, named "charCodeAt", with length 1, of proto);
proto.set_field_slice("toString", to_value(to_string as NativeFunctionData)); make_builtin_fn!(to_string, named "toString", of proto);
proto.set_field_slice("concat", to_value(concat as NativeFunctionData)); make_builtin_fn!(concat, named "concat", with length 1, of proto);
proto.set_field_slice("repeat", to_value(repeat as NativeFunctionData)); make_builtin_fn!(repeat, named "repeat", with length 1, of proto);
proto.set_field_slice("slice", to_value(slice as NativeFunctionData)); make_builtin_fn!(slice, named "slice", with length 2, of proto);
proto.set_field_slice("startsWith", to_value(starts_with as NativeFunctionData)); make_builtin_fn!(starts_with, named "startsWith", with length 1, of proto);
proto.set_field_slice("endsWith", to_value(ends_with as NativeFunctionData)); make_builtin_fn!(ends_with, named "endsWith", with length 1, of proto);
proto.set_field_slice("includes", to_value(includes as NativeFunctionData)); make_builtin_fn!(includes, named "includes", with length 1, of proto);
proto.set_field_slice("indexOf", to_value(index_of as NativeFunctionData)); make_builtin_fn!(index_of, named "indexOf", with length 1, of proto);
proto.set_field_slice("lastIndexOf", to_value(last_index_of as NativeFunctionData)); make_builtin_fn!(last_index_of, named "lastIndexOf", with length 1, of proto);
proto.set_field_slice("match", to_value(r#match as NativeFunctionData)); make_builtin_fn!(r#match, named "match", with length 1, of proto);
proto.set_field_slice("padEnd", to_value(pad_end as NativeFunctionData)); make_builtin_fn!(pad_end, named "padEnd", with length 1, of proto);
proto.set_field_slice("padStart", to_value(pad_start as NativeFunctionData)); make_builtin_fn!(pad_start, named "padStart", with length 1, of proto);
proto.set_field_slice("trim", to_value(trim as NativeFunctionData)); make_builtin_fn!(trim, named "trim", of proto);
proto.set_field_slice("trimStart", to_value(trim_start as NativeFunctionData)); make_builtin_fn!(trim_start, named "trimStart", of proto);
proto.set_field_slice("toLowerCase", to_value(to_lowercase as NativeFunctionData)); make_builtin_fn!(to_lowercase, named "toLowerCase", of proto);
proto.set_field_slice("toUpperCase", to_value(to_uppercase as NativeFunctionData)); make_builtin_fn!(to_uppercase, named "toUpperCase", of proto);
proto.set_field_slice("substring", to_value(substring as NativeFunctionData)); make_builtin_fn!(substring, named "substring", with length 2, of proto);
proto.set_field_slice("substr", to_value(substr as NativeFunctionData)); make_builtin_fn!(substr, named "substr", with length 2, of proto);
proto.set_field_slice("valueOf", to_value(value_of as NativeFunctionData)); make_builtin_fn!(value_of, named "valueOf", of proto);
proto.set_field_slice("matchAll", to_value(match_all as NativeFunctionData)); make_builtin_fn!(match_all, named "matchAll", with length 1, of proto);
let string = to_value(string_constructor); let string = to_value(string_constructor);
proto.set_field_slice("constructor", string.clone()); proto.set_field_slice("constructor", string.clone());

Loading…
Cancel
Save