Skip to content

Commit a8d91e2

Browse files
authored
chore: Split up js-compute-builtins.cpp more (#158)
#158
1 parent 0a927bb commit a8d91e2

File tree

10 files changed

+249
-187
lines changed

10 files changed

+249
-187
lines changed

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

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -3,95 +3,6 @@
33

44
#include "js-compute-builtins.h"
55

6-
/* Returns false if an exception is set on `cx` and the caller should
7-
immediately return to propagate the exception. */
8-
static inline bool handle_fastly_result(JSContext *cx, int result, int line, const char *func) {
9-
switch (result) {
10-
case 0:
11-
return true;
12-
case 1:
13-
JS_ReportErrorUTF8(cx,
14-
"%s: Generic error value. This means that some unexpected error "
15-
"occurred during a hostcall. - Fastly error code %d\n",
16-
func, result);
17-
return false;
18-
case 2:
19-
JS_ReportErrorUTF8(cx, "%s: Invalid argument. - Fastly error code %d\n", func, result);
20-
return false;
21-
case 3:
22-
JS_ReportErrorUTF8(cx,
23-
"%s: Invalid handle. Thrown when a request, response, dictionary, or "
24-
"body handle is not valid. - Fastly error code %d\n",
25-
func, result);
26-
return false;
27-
case 4:
28-
JS_ReportErrorUTF8(cx, "%s: Buffer length error. Buffer is too long. - Fastly error code %d\n",
29-
func, result);
30-
return false;
31-
case 5:
32-
JS_ReportErrorUTF8(cx,
33-
"%s: Unsupported operation error. This error is thrown "
34-
"when some operation cannot be performed, because it is "
35-
"not supported. - Fastly error code %d\n",
36-
func, result);
37-
return false;
38-
case 6:
39-
JS_ReportErrorUTF8(cx,
40-
"%s: Alignment error. This is thrown when a pointer does not point to "
41-
"a properly aligned slice of memory. - Fastly error code %d\n",
42-
func, result);
43-
return false;
44-
case 7:
45-
JS_ReportErrorUTF8(cx,
46-
"%s: HTTP parse error. This can be thrown when a method, URI, header, "
47-
"or status is not valid. This can also be thrown if a message head is "
48-
"too large. - Fastly error code %d\n",
49-
func, result);
50-
return false;
51-
case 8:
52-
JS_ReportErrorUTF8(cx,
53-
"%s: HTTP user error. This is thrown in cases where user code caused "
54-
"an HTTP error. For example, attempt to send a 1xx response code, or a "
55-
"request with a non-absolute URI. This can also be caused by an "
56-
"unexpected header: both `content-length` and `transfer-encoding`, for "
57-
"example. - Fastly error code %d\n",
58-
func, result);
59-
return false;
60-
case 9:
61-
JS_ReportErrorUTF8(cx,
62-
"%s: HTTP incomplete message error. A stream ended "
63-
"unexpectedly. - Fastly error code %d\n",
64-
func, result);
65-
return false;
66-
case 10:
67-
JS_ReportErrorUTF8(cx,
68-
"%s: A `None` error. This status code is used to "
69-
"indicate when an optional value did not exist, as "
70-
"opposed to an empty value. - Fastly error code %d\n",
71-
func, result);
72-
return false;
73-
case 11:
74-
JS_ReportErrorUTF8(cx,
75-
"%s: HTTP head too large error. This error will be thrown when the "
76-
"message head is too large. - Fastly error code %d\n",
77-
func, result);
78-
return false;
79-
case 12:
80-
JS_ReportErrorUTF8(cx,
81-
"%s: HTTP invalid status error. This error will be "
82-
"thrown when the HTTP message contains an invalid "
83-
"status code. - Fastly error code %d\n",
84-
func, result);
85-
return false;
86-
default:
87-
fprintf(stdout, __FILE__ ":%d (%s) - Fastly error code %d\n", line, func, result);
88-
JS_ReportErrorUTF8(cx, "Fastly error code %d", result);
89-
return false;
90-
}
91-
}
92-
93-
#define HANDLE_RESULT(cx, result) handle_fastly_result(cx, result, __LINE__, __func__)
94-
956
#define DBG(...) \
967
printf("%s#%d: ", __func__, __LINE__); \
978
printf(__VA_ARGS__); \
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
#include "env.h"
3+
4+
namespace Env {
5+
6+
namespace {
7+
8+
bool env_get(JSContext *cx, unsigned argc, JS::Value *vp) {
9+
JS::CallArgs args = CallArgsFromVp(argc, vp);
10+
if (!args.requireAtLeast(cx, "fastly.env.get", 1))
11+
return false;
12+
13+
size_t var_name_len;
14+
JS::UniqueChars var_name_chars = encode(cx, args[0], &var_name_len);
15+
if (!var_name_chars) {
16+
return false;
17+
}
18+
JS::RootedString env_var(cx, JS_NewStringCopyZ(cx, getenv(var_name_chars.get())));
19+
if (!env_var)
20+
return false;
21+
22+
args.rval().setString(env_var);
23+
return true;
24+
}
25+
26+
const JSFunctionSpec methods[] = {JS_FN("get", env_get, 1, JSPROP_ENUMERATE), JS_FS_END};
27+
28+
} // namespace
29+
30+
JSObject *create(JSContext *cx) {
31+
JS::RootedObject env(cx, JS_NewPlainObject(cx));
32+
if (!env || !JS_DefineFunctions(cx, env, methods))
33+
return nullptr;
34+
return env;
35+
}
36+
} // namespace Env
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef JS_COMPUTE_RUNTIME_BUILTIN_ENV_H
2+
#define JS_COMPUTE_RUNTIME_BUILTIN_ENV_H
3+
4+
#include "builtin.h"
5+
6+
namespace Env {
7+
JSObject *create(JSContext *cx);
8+
}
9+
10+
#endif

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "logger.h"
2-
#include "xqd.h"
2+
#include "host_call.h"
33

44
namespace Logger {
55
namespace Slots {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <arpa/inet.h>
2+
3+
#include "geo_ip.h"
4+
#include "host_call.h"
5+
#include "js-compute-builtins.h" // for encode
6+
#include "xqd.h"
7+
8+
JSString *get_geo_info(JSContext *cx, JS::HandleString address_str) {
9+
size_t address_len;
10+
JS::UniqueChars address = encode(cx, address_str, &address_len);
11+
if (!address)
12+
return nullptr;
13+
14+
int format = AF_INET;
15+
size_t octets_len = 4;
16+
const char *caddress = address.get();
17+
for (size_t i = 0; i < address_len; i++) {
18+
if (caddress[i] == ':') {
19+
format = AF_INET6;
20+
octets_len = 16;
21+
break;
22+
}
23+
}
24+
25+
char octets[sizeof(struct in6_addr)];
26+
if (inet_pton(format, caddress, octets) != 1) {
27+
// While get_geo_info can be invoked through FetchEvent#client.geo, too,
28+
// that path can't result in an invalid address here, so we can be more
29+
// specific in the error message.
30+
JS_ReportErrorLatin1(cx, "Invalid address passed to fastly.getGeolocationForIpAddress");
31+
return nullptr;
32+
}
33+
34+
OwnedHostCallBuffer buffer;
35+
size_t nwritten = 0;
36+
if (!HANDLE_RESULT(
37+
cx, xqd_geo_lookup(octets, octets_len, buffer.get(), HOSTCALL_BUFFER_LEN, &nwritten))) {
38+
return nullptr;
39+
}
40+
41+
return JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(buffer.get(), nwritten));
42+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef JS_COMPUTE_RUNTIME_GEO_IP_H
2+
#define JS_COMPUTE_RUNTIME_GEO_IP_H
3+
4+
// TODO: remove these once the warnings are fixed
5+
#pragma clang diagnostic push
6+
#pragma clang diagnostic ignored "-Winvalid-offsetof"
7+
8+
#include "jsapi.h"
9+
#include "jsfriendapi.h"
10+
11+
#pragma clang diagnostic pop
12+
13+
JSString *get_geo_info(JSContext *cx, JS::HandleString address_str);
14+
15+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
#include "host_call.h"
3+
4+
bool OwnedHostCallBuffer::initialize(JSContext *cx) {
5+
// Ensure the buffer is all zeros so it doesn't add too much to the
6+
// snapshot.
7+
hostcall_buffer = (char *)js_calloc(HOSTCALL_BUFFER_LEN);
8+
return !!hostcall_buffer;
9+
}
10+
11+
OwnedHostCallBuffer::OwnedHostCallBuffer() {
12+
MOZ_RELEASE_ASSERT(hostcall_buffer != nullptr);
13+
borrowed_buffer = hostcall_buffer;
14+
hostcall_buffer = nullptr;
15+
}
16+
17+
char *OwnedHostCallBuffer::get() { return borrowed_buffer; }
18+
19+
OwnedHostCallBuffer::~OwnedHostCallBuffer() {
20+
// TODO: consider adding a build config that makes this zero the buffer.
21+
hostcall_buffer = borrowed_buffer;
22+
}
23+
24+
char *OwnedHostCallBuffer::hostcall_buffer;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#ifndef JS_COMPUTE_RUNTIME_HOST_CALL_H
2+
#define JS_COMPUTE_RUNTIME_HOST_CALL_H
3+
4+
#include "js-compute-builtins.h"
5+
6+
#include "xqd.h"
7+
8+
/* Returns false if an exception is set on `cx` and the caller should
9+
immediately return to propagate the exception. */
10+
static inline bool handle_fastly_result(JSContext *cx, int result, int line, const char *func) {
11+
switch (result) {
12+
case 0:
13+
return true;
14+
case 1:
15+
JS_ReportErrorUTF8(cx,
16+
"%s: Generic error value. This means that some unexpected error "
17+
"occurred during a hostcall. - Fastly error code %d\n",
18+
func, result);
19+
return false;
20+
case 2:
21+
JS_ReportErrorUTF8(cx, "%s: Invalid argument. - Fastly error code %d\n", func, result);
22+
return false;
23+
case 3:
24+
JS_ReportErrorUTF8(cx,
25+
"%s: Invalid handle. Thrown when a request, response, dictionary, or "
26+
"body handle is not valid. - Fastly error code %d\n",
27+
func, result);
28+
return false;
29+
case 4:
30+
JS_ReportErrorUTF8(cx, "%s: Buffer length error. Buffer is too long. - Fastly error code %d\n",
31+
func, result);
32+
return false;
33+
case 5:
34+
JS_ReportErrorUTF8(cx,
35+
"%s: Unsupported operation error. This error is thrown "
36+
"when some operation cannot be performed, because it is "
37+
"not supported. - Fastly error code %d\n",
38+
func, result);
39+
return false;
40+
case 6:
41+
JS_ReportErrorUTF8(cx,
42+
"%s: Alignment error. This is thrown when a pointer does not point to "
43+
"a properly aligned slice of memory. - Fastly error code %d\n",
44+
func, result);
45+
return false;
46+
case 7:
47+
JS_ReportErrorUTF8(cx,
48+
"%s: HTTP parse error. This can be thrown when a method, URI, header, "
49+
"or status is not valid. This can also be thrown if a message head is "
50+
"too large. - Fastly error code %d\n",
51+
func, result);
52+
return false;
53+
case 8:
54+
JS_ReportErrorUTF8(cx,
55+
"%s: HTTP user error. This is thrown in cases where user code caused "
56+
"an HTTP error. For example, attempt to send a 1xx response code, or a "
57+
"request with a non-absolute URI. This can also be caused by an "
58+
"unexpected header: both `content-length` and `transfer-encoding`, for "
59+
"example. - Fastly error code %d\n",
60+
func, result);
61+
return false;
62+
case 9:
63+
JS_ReportErrorUTF8(cx,
64+
"%s: HTTP incomplete message error. A stream ended "
65+
"unexpectedly. - Fastly error code %d\n",
66+
func, result);
67+
return false;
68+
case 10:
69+
JS_ReportErrorUTF8(cx,
70+
"%s: A `None` error. This status code is used to "
71+
"indicate when an optional value did not exist, as "
72+
"opposed to an empty value. - Fastly error code %d\n",
73+
func, result);
74+
return false;
75+
case 11:
76+
JS_ReportErrorUTF8(cx,
77+
"%s: HTTP head too large error. This error will be thrown when the "
78+
"message head is too large. - Fastly error code %d\n",
79+
func, result);
80+
return false;
81+
case 12:
82+
JS_ReportErrorUTF8(cx,
83+
"%s: HTTP invalid status error. This error will be "
84+
"thrown when the HTTP message contains an invalid "
85+
"status code. - Fastly error code %d\n",
86+
func, result);
87+
return false;
88+
default:
89+
fprintf(stdout, __FILE__ ":%d (%s) - Fastly error code %d\n", line, func, result);
90+
JS_ReportErrorUTF8(cx, "Fastly error code %d", result);
91+
return false;
92+
}
93+
}
94+
95+
#define HANDLE_RESULT(cx, result) handle_fastly_result(cx, result, __LINE__, __func__)
96+
97+
#define HOSTCALL_BUFFER_LEN HEADER_MAX_LEN
98+
99+
class OwnedHostCallBuffer {
100+
static char *hostcall_buffer;
101+
char *borrowed_buffer;
102+
103+
public:
104+
static bool initialize(JSContext *cx);
105+
106+
OwnedHostCallBuffer();
107+
~OwnedHostCallBuffer();
108+
109+
char *get();
110+
};
111+
112+
#endif

0 commit comments

Comments
 (0)