Skip to content

Commit c5933ea

Browse files
author
Guy Bedford
authored
fix: modular builtin separation (#426)
1 parent 8683b72 commit c5933ea

27 files changed

+150
-42
lines changed

c-dependencies/js-compute-runtime/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ $(OBJ_DIR)/js-compute-runtime-component.wasm: $(OBJ_DIR)/xqd-world/xqd_world_ada
279279
shared-builtins.a: $(OBJ_DIR)/shared-builtins.a
280280
$(call cmd,cp,$@)
281281

282-
$(OBJ_DIR)/shared-builtins.a: $(OBJ_DIR)/builtins/shared/console.o
282+
$(OBJ_DIR)/shared-builtins.a: $(OBJ_DIR)/builtins/shared/console.o $(OBJ_DIR)/builtin.o
283283
$(call cmd,wasi_ar,$@)
284284

285285
# These two rules copy the built artifacts into the $(FSM_SRC) directory, and
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Our own version of spidermonkey/js/friend/ErrorNumbers.msg
3+
* where we can add our own custom error messages for use within the runtime
4+
*/
5+
6+
/*
7+
* This is our JavaScript error message file.
8+
*
9+
* The format for each JS error message is:
10+
*
11+
* MSG_DEF(<SYMBOLIC_NAME>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
12+
* <FORMAT_STRING>)
13+
*
14+
* where ;
15+
* <SYMBOLIC_NAME> is a legal C identifer that will be used in the
16+
* JS engine source.
17+
*
18+
* <ARGUMENT_COUNT> is an integer literal specifying the total number of
19+
* replaceable arguments in the following format string.
20+
*
21+
* <EXCEPTION_NAME> is an enum JSExnType value, defined in js/ErrorReport.h.
22+
*
23+
* <FORMAT_STRING> is a string literal, optionally containing sequences
24+
* {X} where X is an integer representing the argument number that will
25+
* be replaced with a string value when the error is reported.
26+
*
27+
* e.g.
28+
*
29+
* MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_TYPEERROR,
30+
* "{0} is not a member of the {1} family")
31+
*
32+
* can be used:
33+
*
34+
* JS_ReportErrorNumberASCII(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
35+
*
36+
* to report:
37+
*
38+
* "TypeError: Rhino is not a member of the Monkey family"
39+
*/
40+
41+
// clang-format off
42+
MSG_DEF(JSMSG_BUILTIN_NOT_AN_ERROR, 0, JSEXN_ERR, "<Error #0 is reserved>")
43+
MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden")
44+
MSG_DEF(JSMSG_ILLEGAL_CTOR, 0, JSEXN_TYPEERR, "Illegal constructor")
45+
MSG_DEF(JSMSG_INVALID_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}")
46+
MSG_DEF(JSMSG_INCOMPATIBLE_INSTANCE, 2, JSEXN_TYPEERR, "Method {0} called on receiver that's not an instance of {1}")
47+
//clang-format on
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "builtin.h"
2+
3+
const JSErrorFormatString *GetErrorMessageBuiltin(void *userRef, unsigned errorNumber) {
4+
if (errorNumber > 0 && errorNumber < JSBuiltinErrNum_Limit) {
5+
return &js_ErrorFormatStringBuiltin[errorNumber];
6+
}
7+
8+
return nullptr;
9+
}
10+
11+
JS::UniqueChars encode(JSContext *cx, JS::HandleString str, size_t *encoded_len) {
12+
JS::UniqueChars text = JS_EncodeStringToUTF8(cx, str);
13+
if (!text)
14+
return nullptr;
15+
16+
// This shouldn't fail, since the encode operation ensured `str` is linear.
17+
JSLinearString *linear = JS_EnsureLinearString(cx, str);
18+
*encoded_len = JS::GetDeflatedUTF8StringLength(linear);
19+
return text;
20+
}
21+
22+
JS::UniqueChars encode(JSContext *cx, JS::HandleValue val, size_t *encoded_len) {
23+
JS::RootedString str(cx, JS::ToString(cx, val));
24+
if (!str)
25+
return nullptr;
26+
27+
return encode(cx, str, encoded_len);
28+
}
29+
30+
jsurl::SpecString encode(JSContext *cx, JS::HandleValue val) {
31+
jsurl::SpecString slice(nullptr, 0, 0);
32+
auto chars = encode(cx, val, &slice.len);
33+
if (!chars)
34+
return slice;
35+
slice.data = (uint8_t *)chars.release();
36+
slice.cap = slice.len;
37+
return slice;
38+
}

c-dependencies/js-compute-runtime/builtin.h

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,43 @@
33

44
#include <tuple>
55

6-
#include "js-compute-builtins.h"
6+
// TODO: remove these once the warnings are fixed
7+
#pragma clang diagnostic push
8+
#pragma clang diagnostic ignored "-Winvalid-offsetof"
9+
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"
10+
#include "js/Conversions.h"
11+
#include "js/ForOfIterator.h"
12+
#include "js/Object.h"
13+
#include "js/Promise.h"
14+
#include "jsapi.h"
15+
#include "jsfriendapi.h"
16+
#include "rust-url/rust-url.h"
17+
18+
#pragma clang diagnostic pop
19+
20+
// TODO(performance): introduce a version that writes into an existing buffer, and use that
21+
// with the hostcall buffer where possible.
22+
// https://github.com/fastly/js-compute-runtime/issues/215
23+
JS::UniqueChars encode(JSContext *cx, JS::HandleString str, size_t *encoded_len);
24+
25+
JS::UniqueChars encode(JSContext *cx, JS::HandleValue val, size_t *encoded_len);
26+
27+
jsurl::SpecString encode(JSContext *cx, JS::HandleValue val);
28+
29+
enum JSBuiltinErrNum {
30+
#define MSG_DEF(name, count, exception, format) name,
31+
#include "./builtin-error-numbers.msg"
32+
#undef MSG_DEF
33+
JSBuiltinErrNum_Limit
34+
};
35+
36+
const JSErrorFormatString js_ErrorFormatStringBuiltin[JSBuiltinErrNum_Limit] = {
37+
#define MSG_DEF(name, count, exception, format) {#name, format, count, exception},
38+
#include "./builtin-error-numbers.msg"
39+
#undef MSG_DEF
40+
};
41+
42+
const JSErrorFormatString *GetErrorMessageBuiltin(void *userRef, unsigned errorNumber);
743

844
#define DBG(...) \
945
printf("%s#%d: ", __func__, __LINE__); \
@@ -45,7 +81,7 @@
4581
\
4682
bool check_receiver(JSContext *cx, JS::HandleValue receiver, const char *method_name) { \
4783
if (!is_instance(receiver)) { \
48-
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_INSTANCE, \
84+
JS_ReportErrorNumberASCII(cx, GetErrorMessageBuiltin, nullptr, JSMSG_INCOMPATIBLE_INSTANCE, \
4985
method_name, class_.name); \
5086
return false; \
5187
} \
@@ -131,7 +167,8 @@ inline bool ThrowIfNotConstructing(JSContext *cx, const JS::CallArgs &args,
131167
return true;
132168
}
133169

134-
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BUILTIN_CTOR_NO_NEW, builtinName);
170+
JS_ReportErrorNumberASCII(cx, GetErrorMessageBuiltin, nullptr, JSMSG_BUILTIN_CTOR_NO_NEW,
171+
builtinName);
135172
return false;
136173
}
137174
namespace builtins {
@@ -172,7 +209,7 @@ template <typename Impl> class BuiltinImpl {
172209

173210
static bool check_receiver(JSContext *cx, JS::HandleValue receiver, const char *method_name) {
174211
if (!Impl::is_instance(receiver)) {
175-
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_INSTANCE,
212+
JS_ReportErrorNumberASCII(cx, GetErrorMessageBuiltin, nullptr, JSMSG_INCOMPATIBLE_INSTANCE,
176213
method_name, Impl::class_.name);
177214
return false;
178215
}

c-dependencies/js-compute-runtime/builtins/backend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "backend.h"
2121
#include "host_call.h"
22+
#include "js-compute-builtins.h"
2223
#include "js/Conversions.h"
2324

2425
enum class Authentication : uint8_t {

c-dependencies/js-compute-runtime/builtins/backend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JS_COMPUTE_RUNTIME_BACKEND_H
33

44
#include "builtin.h"
5+
#include "js-compute-builtins.h"
56

67
namespace builtins {
78

c-dependencies/js-compute-runtime/builtins/cache-override.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JS_COMPUTE_RUNTIME_CACHE_OVERRIDE_H
33

44
#include "builtin.h"
5+
#include "js-compute-builtins.h"
56

67
namespace builtins {
78

c-dependencies/js-compute-runtime/builtins/compression-stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JS_COMPUTE_RUNTIME_COMPRESSION_STREAM_H
33

44
#include "builtin.h"
5+
#include "js-compute-builtins.h"
56

67
namespace builtins {
78

c-dependencies/js-compute-runtime/builtins/config-store.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JS_COMPUTE_RUNTIME_CONFIG_STORE_H
33

44
#include "builtin.h"
5+
#include "js-compute-builtins.h"
56

67
namespace builtins {
78

c-dependencies/js-compute-runtime/builtins/crypto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JS_COMPUTE_RUNTIME_BUILTIN_CRYPTO_H
33

44
#include "builtin.h"
5+
#include "js-compute-builtins.h"
56

67
namespace builtins {
78

0 commit comments

Comments
 (0)