mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-18 09:50:27 +00:00
Specialize only the fixed unary case in the bytecode generator and let all other argument counts keep using the generic Call instruction. This keeps the builtin bytecode simple while still covering the common fast path. The asm interpreter handles int32 inputs directly, applies the ToUint16 mask in-place, and reuses the VM's cached ASCII single-character strings when the result is 7-bit representable. Non-ASCII single code unit results stay on the dedicated builtin path via a small helper, and the dedicated slow path still handles the generic cases.
88 lines
4 KiB
C++
88 lines
4 KiB
C++
/*
|
|
* Copyright (c) 2023, Simon Wanner <simon@skyrising.xyz>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Format.h>
|
|
#include <LibJS/Forward.h>
|
|
|
|
namespace JS::Bytecode {
|
|
|
|
// TitleCaseName, snake_case_name, base, property, argument_count
|
|
#define JS_ENUMERATE_BUILTINS(O) \
|
|
O(MathAbs, math_abs, Math, abs, 1) \
|
|
O(MathLog, math_log, Math, log, 1) \
|
|
O(MathPow, math_pow, Math, pow, 2) \
|
|
O(MathExp, math_exp, Math, exp, 1) \
|
|
O(MathCeil, math_ceil, Math, ceil, 1) \
|
|
O(MathFloor, math_floor, Math, floor, 1) \
|
|
O(MathImul, math_imul, Math, imul, 2) \
|
|
O(MathRandom, math_random, Math, random, 0) \
|
|
O(MathRound, math_round, Math, round, 1) \
|
|
O(MathSqrt, math_sqrt, Math, sqrt, 1) \
|
|
O(MathSin, math_sin, Math, sin, 1) \
|
|
O(MathCos, math_cos, Math, cos, 1) \
|
|
O(MathTan, math_tan, Math, tan, 1) \
|
|
O(RegExpPrototypeExec, regexp_prototype_exec, RegExpPrototype, exec, 1) \
|
|
O(RegExpPrototypeReplace, regexp_prototype_replace, RegExpPrototype, replace, 2) \
|
|
O(RegExpPrototypeSplit, regexp_prototype_split, RegExpPrototype, split, 2) \
|
|
O(OrdinaryHasInstance, ordinary_has_instance, InternalBuiltin, ordinary_has_instance, 1) \
|
|
O(ArrayIteratorPrototypeNext, array_iterator_prototype_next, ArrayIteratorPrototype, next, 0) \
|
|
O(MapIteratorPrototypeNext, map_iterator_prototype_next, MapIteratorPrototype, next, 0) \
|
|
O(SetIteratorPrototypeNext, set_iterator_prototype_next, SetIteratorPrototype, next, 0) \
|
|
O(StringIteratorPrototypeNext, string_iterator_prototype_next, StringIteratorPrototype, next, 0) \
|
|
O(StringFromCharCode, string_from_char_code, String, fromCharCode, 1) \
|
|
O(StringPrototypeCharCodeAt, string_prototype_char_code_at, StringPrototype, charCodeAt, 1) \
|
|
O(StringPrototypeCharAt, string_prototype_char_at, StringPrototype, charAt, 1)
|
|
|
|
enum class Builtin : u8 {
|
|
#define DEFINE_BUILTIN_ENUM(name, ...) name,
|
|
JS_ENUMERATE_BUILTINS(DEFINE_BUILTIN_ENUM)
|
|
#undef DEFINE_BUILTIN_ENUM
|
|
__Count,
|
|
};
|
|
|
|
static StringView builtin_name(Builtin value)
|
|
{
|
|
switch (value) {
|
|
#define DEFINE_BUILTIN_CASE(name, snake_case_name, base, property, ...) \
|
|
case Builtin::name: \
|
|
return #base "." #property##sv;
|
|
JS_ENUMERATE_BUILTINS(DEFINE_BUILTIN_CASE)
|
|
#undef DEFINE_BUILTIN_CASE
|
|
case Builtin::__Count:
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
|
|
inline size_t builtin_argument_count(Builtin value)
|
|
{
|
|
switch (value) {
|
|
#define DEFINE_BUILTIN_CASE(name, snake_case_name, base, property, arg_count, ...) \
|
|
case Builtin::name: \
|
|
return arg_count;
|
|
JS_ENUMERATE_BUILTINS(DEFINE_BUILTIN_CASE)
|
|
#undef DEFINE_BUILTIN_CASE
|
|
case Builtin::__Count:
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
|
|
}
|
|
|
|
namespace AK {
|
|
|
|
template<>
|
|
struct Formatter<JS::Bytecode::Builtin> : Formatter<StringView> {
|
|
ErrorOr<void> format(FormatBuilder& builder, JS::Bytecode::Builtin value)
|
|
{
|
|
return Formatter<StringView>::format(builder, builtin_name(value));
|
|
}
|
|
};
|
|
|
|
}
|