Skip to content

Commit d1fcb39

Browse files
committed
Refactor: store wasm error code in-line (no pointer)
I want to avoid storing the "E1234" string in memory permanently. This means the lifetime of qljs_web_demo_diagnostic::code will be temporary. Simplify lifetimes by having qljs_web_demo_diagnostic::code store a copy of the error code string instead of storing a pointer. Copying also fixes a TODO regarding no guarantee of null termination. This commit should not change behavior.
1 parent 81f5fd4 commit d1fcb39

File tree

4 files changed

+25
-16
lines changed

4 files changed

+25
-16
lines changed

src/c-api-error-reporter.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (C) 2020 Matthew "strager" Glazar
22
// See end of file for extended copyright information.
33

4+
#include <algorithm>
45
#include <memory>
56
#include <quick-lint-js/c-api-error-reporter.h>
67
#include <quick-lint-js/c-api.h>
@@ -111,8 +112,10 @@ void c_api_error_formatter<Diagnostic, Locator>::write_after_message(
111112
diag.begin_offset = narrow_cast<int>(r.begin);
112113
diag.end_offset = narrow_cast<int>(r.end);
113114
}
114-
// FIXME(strager): code is not guaranteed to be null-terminated.
115-
diag.code = code.data();
115+
116+
char *code_end = std::copy(code.begin(), code.end(), &diag.code[0]);
117+
*code_end = '\0';
118+
116119
diag.message = reinterpret_cast<const char *>(
117120
this->reporter_->allocate_c_string(this->current_message_));
118121
diag.severity = diag_severity;

src/quick-lint-js/c-api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ typedef enum qljs_severity {
1818
typedef struct qljs_web_demo_document qljs_web_demo_document;
1919
struct qljs_web_demo_diagnostic {
2020
const char* message;
21-
const char* code;
21+
char code[6]; // null-terminated
2222
qljs_severity severity;
2323
// Offsets count UTF-16 code units.
2424
int begin_offset;

test/test-c-api.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ TEST(test_c_api_web_demo, lint_error_after_text_insertion) {
2222
const qljs_web_demo_diagnostic* diagnostics = qljs_web_demo_lint(p);
2323
EXPECT_NE(diagnostics[0].message, nullptr);
2424
EXPECT_EQ(diagnostics[1].message, nullptr);
25-
EXPECT_EQ(diagnostics[1].code, nullptr);
25+
EXPECT_STREQ(diagnostics[1].code, "");
2626

2727
EXPECT_STREQ(diagnostics[0].message, "redeclaration of variable: x");
2828
EXPECT_STREQ(diagnostics[0].code, "E0034");
@@ -45,7 +45,7 @@ TEST(test_c_api_web_demo, lint_new_error_after_second_text_insertion) {
4545
diagnostics = qljs_web_demo_lint(p);
4646
EXPECT_NE(diagnostics[0].message, nullptr);
4747
EXPECT_EQ(diagnostics[1].message, nullptr);
48-
EXPECT_EQ(diagnostics[1].code, nullptr);
48+
EXPECT_STREQ(diagnostics[1].code, "");
4949

5050
EXPECT_STREQ(diagnostics[0].message, "redeclaration of variable: x");
5151
EXPECT_STREQ(diagnostics[0].code, "E0034");
@@ -66,7 +66,7 @@ TEST(test_c_api_web_demo, linting_uses_config) {
6666

6767
const qljs_web_demo_diagnostic* diagnostics = qljs_web_demo_lint(p);
6868
EXPECT_EQ(diagnostics[0].message, nullptr);
69-
EXPECT_EQ(diagnostics[0].code, nullptr);
69+
EXPECT_STREQ(diagnostics[0].code, "");
7070

7171
qljs_web_demo_destroy_document(p);
7272
}

website/wasm/quick-lint-js.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class DocumentForWebDemo {
288288
}
289289

290290
_parseDiagnostics(diagnosticsPointer) {
291+
let rawDiagnostics = new Uint8Array(
292+
this._process._heap,
293+
diagnosticsPointer
294+
);
291295
let rawDiagnosticsU32 = new Uint32Array(
292296
this._process._heap,
293297
diagnosticsPointer
@@ -298,30 +302,32 @@ class DocumentForWebDemo {
298302
);
299303
// struct qljs_web_demo_diagnostic {
300304
// const char* message;
301-
// const char* code;
305+
// char code[6];
302306
// qljs_vscode_severity severity;
303307
// int begin_offset;
304308
// int end_offset;
305309
// };
306310
let ERROR = {
307311
message: 0,
308-
code: 1,
309-
severity: 2,
310-
begin_offset: 3,
311-
end_offset: 4,
312-
313-
_ptr_size: 5,
314-
_u32_size: 5,
312+
code: 4,
313+
severity: 3,
314+
begin_offset: 4,
315+
end_offset: 5,
316+
317+
_byte_size: 6 * 4,
318+
_ptr_size: 6,
319+
_u32_size: 6,
315320
};
316321
let diagnostics = [];
317322
for (let i = 0; ; ++i) {
318323
let messagePtr = rawDiagnosticsPtr[i * ERROR._ptr_size + ERROR.message];
319324
if (messagePtr === 0) {
320325
break;
321326
}
322-
let codePtr = rawDiagnosticsPtr[i * ERROR._ptr_size + ERROR.code];
323327
diagnostics.push({
324-
code: decodeUTF8CString(new Uint8Array(this._process._heap, codePtr)),
328+
code: decodeUTF8CString(
329+
rawDiagnostics.slice(i * ERROR._byte_size + ERROR.code)
330+
),
325331
message: decodeUTF8CString(
326332
new Uint8Array(this._process._heap, messagePtr)
327333
),

0 commit comments

Comments
 (0)