bytecodealliance / bytecodealliance/endive

Redline: a mutable global reaching a second instance gets a copy

Đang mở
#175 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Java
Star
300
Fork
21
Merge trung bình
2 ngày 4 giờ
Pull request đã merge (30 ngày)
34

Mô tả

Redline shares a mutable global with the first instance that receives it. If the same global reaches a second instance, that instance gets a copy instead, so writes by one are not visible to the other. Every other execution mode shares it.

### Reproducing

Module `A` exports a mutable global, module `B` imports it and increments it, then `A` reads it back:

```
interpreter: exporter reads 101
redline: exporter reads 100
```

The same happens without any exporting module, by passing one host-created global to two instances: after each of them increments it, the host object reads `11` rather than `12`.

A global used by a single instance is shared correctly, and memories and tables are unaffected — they are reached through a pointer, so an importing machine simply uses the same one.

### Cause

`CtxBuffer.GLOBALS_PTR` points at one contiguous array of 8-byte slots per machine, indexed by global index, and compiled code reads a global with a single load:

```
globalsPtr = load_i64(ctxPtr, GLOBALS_PTR);
rawVal = load_i64(globalsPtr, globalIdx * 8);
```

A global's storage therefore has to live inside *that* machine's array at *that* module's index, and two machines cannot both hold the same global at their own index. `initializeImportGlobals` adopts a global that is not yet bound to any machine, and copies the value for one that is.

### Suggested fix

Add indirection for imported globals only. Their slot would hold a pointer to the real storage rather than the value, making `global.get` two loads:

```
slot = load_i64(globalsPtr, idx * 8);
val = load_i64(slot, 0);
```

Imports occupy indices `[0, importGlobalCount)`, so the compiler knows statically which globals need the extra load. Module-defined globals — the common case — keep the single-load fast path and cost nothing.

Touches `emitGlobalGet`/`emitGlobalSet` in `NativeEmitters`, the context layout, and `initializeImportGlobals` in both runners. It changes the compiled-code ABI, so it needs the full spec suite behind it.

### Impact

Marginal in practice: it needs two instances plus a shared *mutable* global. Not a regression — the copy predates the current import work, which fixed the single-instance case.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với emitGlobalGet và emitGlobalSet trong NativeEmitters, sau đó kiểm tra bố cục context và initializeImportGlobals trong cả hai runner. Theo dõi cách các global được import được biểu diễn giữa hai instance và chạy toàn bộ spec suite. Hoàn tất khi một global mutable được chia sẻ vẫn được chia sẻ giữa các instance mà không thay đổi fast path của các global do module định nghĩa.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
java, wasm
Lĩnh vực
compilers
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
52/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.