Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_WASM_WASM_OBJECTS_INL_H_
6 : #define V8_WASM_WASM_OBJECTS_INL_H_
7 :
8 : #include "src/wasm/wasm-objects.h"
9 :
10 : #include "src/contexts-inl.h"
11 : #include "src/heap/heap-write-barrier-inl.h"
12 : #include "src/objects/foreign-inl.h"
13 : #include "src/objects/heap-number-inl.h"
14 : #include "src/objects/js-array-buffer-inl.h"
15 : #include "src/objects/js-objects-inl.h"
16 : #include "src/objects/managed.h"
17 : #include "src/objects/oddball-inl.h"
18 : #include "src/objects/script-inl.h"
19 : #include "src/roots.h"
20 : #include "src/v8memory.h"
21 : #include "src/wasm/wasm-code-manager.h"
22 : #include "src/wasm/wasm-module.h"
23 :
24 : // Has to be the last include (doesn't have include guards)
25 : #include "src/objects/object-macros.h"
26 :
27 : namespace v8 {
28 : namespace internal {
29 :
30 : OBJECT_CONSTRUCTORS_IMPL(WasmExceptionObject, JSObject)
31 : OBJECT_CONSTRUCTORS_IMPL(WasmExceptionTag, Struct)
32 : OBJECT_CONSTRUCTORS_IMPL(WasmExportedFunctionData, Struct)
33 : OBJECT_CONSTRUCTORS_IMPL(WasmDebugInfo, Struct)
34 : OBJECT_CONSTRUCTORS_IMPL(WasmGlobalObject, JSObject)
35 : OBJECT_CONSTRUCTORS_IMPL(WasmInstanceObject, JSObject)
36 : OBJECT_CONSTRUCTORS_IMPL(WasmMemoryObject, JSObject)
37 : OBJECT_CONSTRUCTORS_IMPL(WasmModuleObject, JSObject)
38 : OBJECT_CONSTRUCTORS_IMPL(WasmTableObject, JSObject)
39 : OBJECT_CONSTRUCTORS_IMPL(AsmWasmData, Struct)
40 :
41 : NEVER_READ_ONLY_SPACE_IMPL(WasmDebugInfo)
42 :
43 : CAST_ACCESSOR(WasmDebugInfo)
44 : CAST_ACCESSOR(WasmExceptionObject)
45 : CAST_ACCESSOR(WasmExceptionTag)
46 : CAST_ACCESSOR(WasmExportedFunctionData)
47 : CAST_ACCESSOR(WasmGlobalObject)
48 : CAST_ACCESSOR(WasmInstanceObject)
49 : CAST_ACCESSOR(WasmMemoryObject)
50 : CAST_ACCESSOR(WasmModuleObject)
51 : CAST_ACCESSOR(WasmTableObject)
52 : CAST_ACCESSOR(AsmWasmData)
53 :
54 : #define OPTIONAL_ACCESSORS(holder, name, type, offset) \
55 : bool holder::has_##name() { \
56 : return !READ_FIELD(*this, offset)->IsUndefined(); \
57 : } \
58 : ACCESSORS(holder, name, type, offset)
59 :
60 : #define PRIMITIVE_ACCESSORS(holder, name, type, offset) \
61 : type holder::name() const { \
62 : if (COMPRESS_POINTERS_BOOL && alignof(type) > kTaggedSize) { \
63 : /* TODO(ishell, v8:8875): When pointer compression is enabled 8-byte */ \
64 : /* size fields (external pointers, doubles and BigInt data) are only */ \
65 : /* kTaggedSize aligned so we have to use unaligned pointer friendly */ \
66 : /* way of accessing them in order to avoid undefined behavior in C++ */ \
67 : /* code. */ \
68 : return ReadUnalignedValue<type>(FIELD_ADDR(*this, offset)); \
69 : } else { \
70 : return *reinterpret_cast<type const*>(FIELD_ADDR(*this, offset)); \
71 : } \
72 : } \
73 : void holder::set_##name(type value) { \
74 : if (COMPRESS_POINTERS_BOOL && alignof(type) > kTaggedSize) { \
75 : /* TODO(ishell, v8:8875): When pointer compression is enabled 8-byte */ \
76 : /* size fields (external pointers, doubles and BigInt data) are only */ \
77 : /* kTaggedSize aligned so we have to use unaligned pointer friendly */ \
78 : /* way of accessing them in order to avoid undefined behavior in C++ */ \
79 : /* code. */ \
80 : WriteUnalignedValue<type>(FIELD_ADDR(*this, offset), value); \
81 : } else { \
82 : *reinterpret_cast<type*>(FIELD_ADDR(*this, offset)) = value; \
83 : } \
84 : }
85 :
86 : // WasmModuleObject
87 18252239 : ACCESSORS(WasmModuleObject, managed_native_module, Managed<wasm::NativeModule>,
88 : kNativeModuleOffset)
89 6349921 : ACCESSORS(WasmModuleObject, export_wrappers, FixedArray, kExportWrappersOffset)
90 6342322 : ACCESSORS(WasmModuleObject, script, Script, kScriptOffset)
91 13572747 : ACCESSORS(WasmModuleObject, weak_instance_list, WeakArrayList,
92 : kWeakInstanceListOffset)
93 26574 : OPTIONAL_ACCESSORS(WasmModuleObject, asm_js_offset_table, ByteArray,
94 : kAsmJsOffsetTableOffset)
95 135787 : OPTIONAL_ACCESSORS(WasmModuleObject, breakpoint_infos, FixedArray,
96 : kBreakPointInfosOffset)
97 11903662 : wasm::NativeModule* WasmModuleObject::native_module() const {
98 23821908 : return managed_native_module()->raw();
99 : }
100 : const std::shared_ptr<wasm::NativeModule>&
101 : WasmModuleObject::shared_native_module() const {
102 310690 : return managed_native_module()->get();
103 : }
104 : const wasm::WasmModule* WasmModuleObject::module() const {
105 : // TODO(clemensh): Remove this helper (inline in callers).
106 5209499 : return native_module()->module();
107 : }
108 : void WasmModuleObject::reset_breakpoint_infos() {
109 : WRITE_FIELD(*this, kBreakPointInfosOffset,
110 : GetReadOnlyRoots().undefined_value());
111 : }
112 : bool WasmModuleObject::is_asm_js() {
113 155087 : bool asm_js = module()->origin == wasm::kAsmJsOrigin;
114 : DCHECK_EQ(asm_js, script()->IsUserJavaScript());
115 : DCHECK_EQ(asm_js, has_asm_js_offset_table());
116 : return asm_js;
117 : }
118 :
119 : // WasmTableObject
120 2187340 : ACCESSORS(WasmTableObject, elements, FixedArray, kElementsOffset)
121 25049 : ACCESSORS(WasmTableObject, maximum_length, Object, kMaximumLengthOffset)
122 61920 : ACCESSORS(WasmTableObject, dispatch_tables, FixedArray, kDispatchTablesOffset)
123 21701 : SMI_ACCESSORS(WasmTableObject, raw_type, kRawTypeOffset)
124 :
125 : // WasmMemoryObject
126 11456344 : ACCESSORS(WasmMemoryObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
127 62725 : SMI_ACCESSORS(WasmMemoryObject, maximum_pages, kMaximumPagesOffset)
128 389527 : OPTIONAL_ACCESSORS(WasmMemoryObject, instances, WeakArrayList, kInstancesOffset)
129 :
130 : // WasmGlobalObject
131 55688 : ACCESSORS(WasmGlobalObject, untagged_buffer, JSArrayBuffer,
132 : kUntaggedBufferOffset)
133 4848 : ACCESSORS(WasmGlobalObject, tagged_buffer, FixedArray, kTaggedBufferOffset)
134 27880 : SMI_ACCESSORS(WasmGlobalObject, offset, kOffsetOffset)
135 37376 : SMI_ACCESSORS(WasmGlobalObject, flags, kFlagsOffset)
136 32656 : BIT_FIELD_ACCESSORS(WasmGlobalObject, flags, type, WasmGlobalObject::TypeBits)
137 36012 : BIT_FIELD_ACCESSORS(WasmGlobalObject, flags, is_mutable,
138 : WasmGlobalObject::IsMutableBit)
139 :
140 : int WasmGlobalObject::type_size() const {
141 : return wasm::ValueTypes::ElementSizeInBytes(type());
142 : }
143 :
144 : Address WasmGlobalObject::address() const {
145 : DCHECK_NE(type(), wasm::kWasmAnyRef);
146 : DCHECK_LE(offset() + type_size(), untagged_buffer()->byte_length());
147 36016 : return Address(untagged_buffer()->backing_store()) + offset();
148 : }
149 :
150 : int32_t WasmGlobalObject::GetI32() {
151 : return ReadLittleEndianValue<int32_t>(address());
152 : }
153 :
154 : int64_t WasmGlobalObject::GetI64() {
155 : return ReadLittleEndianValue<int64_t>(address());
156 : }
157 :
158 : float WasmGlobalObject::GetF32() {
159 : return ReadLittleEndianValue<float>(address());
160 : }
161 :
162 : double WasmGlobalObject::GetF64() {
163 : return ReadLittleEndianValue<double>(address());
164 : }
165 :
166 832 : Handle<Object> WasmGlobalObject::GetRef() {
167 : // We use this getter for anyref, anyfunc, and except_ref.
168 : DCHECK(wasm::ValueTypes::IsReferenceType(type()));
169 832 : return handle(tagged_buffer()->get(offset()), GetIsolate());
170 : }
171 :
172 3584 : void WasmGlobalObject::SetI32(int32_t value) {
173 : WriteLittleEndianValue<int32_t>(address(), value);
174 3584 : }
175 :
176 88 : void WasmGlobalObject::SetI64(int64_t value) {
177 : WriteLittleEndianValue<int64_t>(address(), value);
178 88 : }
179 :
180 3904 : void WasmGlobalObject::SetF32(float value) {
181 : WriteLittleEndianValue<float>(address(), value);
182 3904 : }
183 :
184 1800 : void WasmGlobalObject::SetF64(double value) {
185 : WriteLittleEndianValue<double>(address(), value);
186 1800 : }
187 :
188 384 : void WasmGlobalObject::SetAnyRef(Handle<Object> value) {
189 : // We use this getter anyref and except_ref.
190 : DCHECK(type() == wasm::kWasmAnyRef || type() == wasm::kWasmExceptRef);
191 384 : tagged_buffer()->set(offset(), *value);
192 384 : }
193 :
194 160 : bool WasmGlobalObject::SetAnyFunc(Isolate* isolate, Handle<Object> value) {
195 : DCHECK_EQ(type(), wasm::kWasmAnyFunc);
196 240 : if (!value->IsNull(isolate) &&
197 80 : !WasmExportedFunction::IsWasmExportedFunction(*value)) {
198 : return false;
199 : }
200 128 : tagged_buffer()->set(offset(), *value);
201 128 : return true;
202 : }
203 :
204 : // WasmInstanceObject
205 7473874 : PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_start, byte*, kMemoryStartOffset)
206 7478518 : PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_size, size_t, kMemorySizeOffset)
207 7459427 : PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_mask, size_t, kMemoryMaskOffset)
208 1231090 : PRIMITIVE_ACCESSORS(WasmInstanceObject, isolate_root, Address,
209 : kIsolateRootOffset)
210 1231090 : PRIMITIVE_ACCESSORS(WasmInstanceObject, stack_limit_address, Address,
211 : kStackLimitAddressOffset)
212 1231090 : PRIMITIVE_ACCESSORS(WasmInstanceObject, real_stack_limit_address, Address,
213 : kRealStackLimitAddressOffset)
214 1360224 : PRIMITIVE_ACCESSORS(WasmInstanceObject, imported_function_targets, Address*,
215 : kImportedFunctionTargetsOffset)
216 3136877 : PRIMITIVE_ACCESSORS(WasmInstanceObject, globals_start, byte*,
217 : kGlobalsStartOffset)
218 1231778 : PRIMITIVE_ACCESSORS(WasmInstanceObject, imported_mutable_globals, Address*,
219 : kImportedMutableGlobalsOffset)
220 1285613 : PRIMITIVE_ACCESSORS(WasmInstanceObject, indirect_function_table_size, uint32_t,
221 : kIndirectFunctionTableSizeOffset)
222 21521518 : PRIMITIVE_ACCESSORS(WasmInstanceObject, indirect_function_table_sig_ids,
223 : uint32_t*, kIndirectFunctionTableSigIdsOffset)
224 21517881 : PRIMITIVE_ACCESSORS(WasmInstanceObject, indirect_function_table_targets,
225 : Address*, kIndirectFunctionTableTargetsOffset)
226 1231090 : PRIMITIVE_ACCESSORS(WasmInstanceObject, jump_table_start, Address,
227 : kJumpTableStartOffset)
228 1231290 : PRIMITIVE_ACCESSORS(WasmInstanceObject, data_segment_starts, Address*,
229 : kDataSegmentStartsOffset)
230 1231290 : PRIMITIVE_ACCESSORS(WasmInstanceObject, data_segment_sizes, uint32_t*,
231 : kDataSegmentSizesOffset)
232 1231314 : PRIMITIVE_ACCESSORS(WasmInstanceObject, dropped_data_segments, byte*,
233 : kDroppedDataSegmentsOffset)
234 1233415 : PRIMITIVE_ACCESSORS(WasmInstanceObject, dropped_elem_segments, byte*,
235 : kDroppedElemSegmentsOffset)
236 :
237 9904054 : ACCESSORS(WasmInstanceObject, module_object, WasmModuleObject,
238 : kModuleObjectOffset)
239 43887386 : ACCESSORS(WasmInstanceObject, exports_object, JSObject, kExportsObjectOffset)
240 6198938 : ACCESSORS(WasmInstanceObject, native_context, Context, kNativeContextOffset)
241 307678 : OPTIONAL_ACCESSORS(WasmInstanceObject, memory_object, WasmMemoryObject,
242 : kMemoryObjectOffset)
243 17527 : OPTIONAL_ACCESSORS(WasmInstanceObject, untagged_globals_buffer, JSArrayBuffer,
244 : kUntaggedGlobalsBufferOffset)
245 2624 : OPTIONAL_ACCESSORS(WasmInstanceObject, tagged_globals_buffer, FixedArray,
246 : kTaggedGlobalsBufferOffset)
247 2008 : OPTIONAL_ACCESSORS(WasmInstanceObject, imported_mutable_globals_buffers,
248 : FixedArray, kImportedMutableGlobalsBuffersOffset)
249 1924637 : OPTIONAL_ACCESSORS(WasmInstanceObject, debug_info, WasmDebugInfo,
250 : kDebugInfoOffset)
251 6175343 : OPTIONAL_ACCESSORS(WasmInstanceObject, tables, FixedArray, kTablesOffset)
252 6284582 : ACCESSORS(WasmInstanceObject, imported_function_refs, FixedArray,
253 : kImportedFunctionRefsOffset)
254 20300771 : OPTIONAL_ACCESSORS(WasmInstanceObject, indirect_function_table_refs, FixedArray,
255 : kIndirectFunctionTableRefsOffset)
256 6158719 : OPTIONAL_ACCESSORS(WasmInstanceObject, managed_native_allocations, Foreign,
257 : kManagedNativeAllocationsOffset)
258 5476572 : OPTIONAL_ACCESSORS(WasmInstanceObject, exceptions_table, FixedArray,
259 : kExceptionsTableOffset)
260 6155440 : ACCESSORS(WasmInstanceObject, undefined_value, Oddball, kUndefinedValueOffset)
261 6155442 : ACCESSORS(WasmInstanceObject, null_value, Oddball, kNullValueOffset)
262 6155450 : ACCESSORS(WasmInstanceObject, centry_stub, Code, kCEntryStubOffset)
263 1463843 : OPTIONAL_ACCESSORS(WasmInstanceObject, wasm_exported_functions, FixedArray,
264 : kWasmExportedFunctionsOffset)
265 :
266 : inline bool WasmInstanceObject::has_indirect_function_table() {
267 : return indirect_function_table_sig_ids() != nullptr;
268 : }
269 :
270 : void WasmInstanceObject::clear_padding() {
271 : if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
272 : DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
273 1231090 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
274 : FIELD_SIZE(kOptionalPaddingOffset));
275 : }
276 : }
277 :
278 : IndirectFunctionTableEntry::IndirectFunctionTableEntry(
279 : Handle<WasmInstanceObject> instance, int index)
280 20283638 : : instance_(instance), index_(index) {
281 : DCHECK_GE(index, 0);
282 : DCHECK_LT(index, instance->indirect_function_table_size());
283 : }
284 :
285 : ImportedFunctionEntry::ImportedFunctionEntry(
286 : Handle<WasmInstanceObject> instance, int index)
287 129142 : : instance_(instance), index_(index) {
288 : DCHECK_GE(index, 0);
289 : DCHECK_LT(index, instance->module()->num_imported_functions);
290 : }
291 :
292 : // WasmExceptionObject
293 536 : ACCESSORS(WasmExceptionObject, serialized_signature, PodArray<wasm::ValueType>,
294 : kSerializedSignatureOffset)
295 528 : ACCESSORS(WasmExceptionObject, exception_tag, HeapObject, kExceptionTagOffset)
296 :
297 : // WasmExportedFunction
298 : WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) {
299 : SLOW_DCHECK(IsWasmExportedFunction(*this));
300 : }
301 : CAST_ACCESSOR(WasmExportedFunction)
302 :
303 : // WasmExportedFunctionData
304 1432985 : ACCESSORS(WasmExportedFunctionData, wrapper_code, Code, kWrapperCodeOffset)
305 1520587 : ACCESSORS(WasmExportedFunctionData, instance, WasmInstanceObject,
306 : kInstanceOffset)
307 238831 : SMI_ACCESSORS(WasmExportedFunctionData, jump_table_offset,
308 : kJumpTableOffsetOffset)
309 456288 : SMI_ACCESSORS(WasmExportedFunctionData, function_index, kFunctionIndexOffset)
310 :
311 : // WasmDebugInfo
312 2974839 : ACCESSORS(WasmDebugInfo, wasm_instance, WasmInstanceObject, kInstanceOffset)
313 1929831 : ACCESSORS(WasmDebugInfo, interpreter_handle, Object, kInterpreterHandleOffset)
314 1834321 : ACCESSORS(WasmDebugInfo, interpreted_functions, FixedArray,
315 : kInterpretedFunctionsOffset)
316 1284 : OPTIONAL_ACCESSORS(WasmDebugInfo, locals_names, FixedArray, kLocalsNamesOffset)
317 24177 : OPTIONAL_ACCESSORS(WasmDebugInfo, c_wasm_entries, FixedArray,
318 : kCWasmEntriesOffset)
319 15936 : OPTIONAL_ACCESSORS(WasmDebugInfo, c_wasm_entry_map, Managed<wasm::SignatureMap>,
320 : kCWasmEntryMapOffset)
321 :
322 : #undef OPTIONAL_ACCESSORS
323 : #undef READ_PRIMITIVE_FIELD
324 : #undef WRITE_PRIMITIVE_FIELD
325 : #undef PRIMITIVE_ACCESSORS
326 :
327 8252 : uint32_t WasmTableObject::current_length() { return elements()->length(); }
328 :
329 : wasm::ValueType WasmTableObject::type() {
330 16976 : return static_cast<wasm::ValueType>(raw_type());
331 : }
332 :
333 : bool WasmMemoryObject::has_maximum_pages() { return maximum_pages() >= 0; }
334 :
335 : // WasmExceptionTag
336 692 : SMI_ACCESSORS(WasmExceptionTag, index, kIndexOffset)
337 :
338 : // AsmWasmData
339 17363 : ACCESSORS(AsmWasmData, managed_native_module, Managed<wasm::NativeModule>,
340 : kManagedNativeModuleOffset)
341 17363 : ACCESSORS(AsmWasmData, export_wrappers, FixedArray, kExportWrappersOffset)
342 17363 : ACCESSORS(AsmWasmData, asm_js_offset_table, ByteArray, kAsmJsOffsetTableOffset)
343 17363 : ACCESSORS(AsmWasmData, uses_bitset, HeapNumber, kUsesBitsetOffset)
344 :
345 : #include "src/objects/object-macros-undef.h"
346 :
347 : } // namespace internal
348 : } // namespace v8
349 :
350 : #endif // V8_WASM_WASM_OBJECTS_INL_H_
|