OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/wasm/wasm-objects.h" | 5 #include "src/wasm/wasm-objects.h" |
6 #include "src/utils.h" | 6 #include "src/utils.h" |
7 | 7 |
8 #include "src/debug/debug-interface.h" | 8 #include "src/debug/debug-interface.h" |
9 #include "src/wasm/module-decoder.h" | 9 #include "src/wasm/module-decoder.h" |
10 #include "src/wasm/wasm-module.h" | 10 #include "src/wasm/wasm-module.h" |
11 #include "src/wasm/wasm-text.h" | 11 #include "src/wasm/wasm-text.h" |
12 | 12 |
13 #define TRACE(...) \ | 13 #define TRACE(...) \ |
14 do { \ | 14 do { \ |
15 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ | 15 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ |
16 } while (false) | 16 } while (false) |
17 | 17 |
18 #define TRACE_CHAIN(instance) \ | 18 #define TRACE_CHAIN(instance) \ |
19 do { \ | 19 do { \ |
20 instance->PrintInstancesChain(); \ | 20 instance->PrintInstancesChain(); \ |
21 } while (false) | 21 } while (false) |
22 | 22 |
23 using namespace v8::internal; | 23 using namespace v8::internal; |
24 using namespace v8::internal::wasm; | 24 using namespace v8::internal::wasm; |
25 | 25 |
26 #define DEFINE_ACCESSORS(Container, name, field, type) \ | 26 #define DEFINE_GETTER0(getter, Container, name, field, type) \ |
27 type* Container::get_##name() { \ | 27 type* Container::name() { return type::cast(getter(field)); } |
28 return type::cast(GetInternalField(field)); \ | 28 |
29 } \ | 29 #define DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \ |
30 void Container::set_##name(type* value) { \ | 30 DEFINE_GETTER0(getter, Container, name, field, type) \ |
31 return SetInternalField(field, value); \ | 31 void Container::set_##name(type* value) { return setter(field, value); } |
| 32 |
| 33 #define DEFINE_OPTIONAL_ACCESSORS0(getter, setter, Container, name, field, \ |
| 34 type) \ |
| 35 DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \ |
| 36 bool Container::has_##name() { \ |
| 37 return !getter(field)->IsUndefined(GetIsolate()); \ |
32 } | 38 } |
33 | 39 |
34 #define DEFINE_OPTIONAL_ACCESSORS(Container, name, field, type) \ | 40 #define DEFINE_OBJ_GETTER(Container, name, field, type) \ |
35 bool Container::has_##name() { \ | 41 DEFINE_GETTER0(GetInternalField, Container, name, field, type) |
36 return !GetInternalField(field)->IsUndefined(GetIsolate()); \ | 42 #define DEFINE_OBJ_ACCESSORS(Container, name, field, type) \ |
37 } \ | 43 DEFINE_ACCESSORS0(GetInternalField, SetInternalField, Container, name, \ |
38 type* Container::get_##name() { \ | 44 field, type) |
39 return type::cast(GetInternalField(field)); \ | 45 #define DEFINE_OPTIONAL_OBJ_ACCESSORS(Container, name, field, type) \ |
40 } \ | 46 DEFINE_OPTIONAL_ACCESSORS0(GetInternalField, SetInternalField, Container, \ |
41 void Container::set_##name(type* value) { \ | 47 name, field, type) |
42 return SetInternalField(field, value); \ | 48 #define DEFINE_ARR_GETTER(Container, name, field, type) \ |
43 } | 49 DEFINE_GETTER0(get, Container, name, field, type) |
| 50 #define DEFINE_ARR_ACCESSORS(Container, name, field, type) \ |
| 51 DEFINE_ACCESSORS0(get, set, Container, name, field, type) |
| 52 #define DEFINE_OPTIONAL_ARR_ACCESSORS(Container, name, field, type) \ |
| 53 DEFINE_OPTIONAL_ACCESSORS0(get, set, Container, name, field, type) |
44 | 54 |
45 #define DEFINE_GETTER(Container, name, field, type) \ | 55 namespace { |
46 type* Container::get_##name() { return type::cast(GetInternalField(field)); } | |
47 | 56 |
48 static uint32_t SafeUint32(Object* value) { | 57 uint32_t SafeUint32(Object* value) { |
49 if (value->IsSmi()) { | 58 if (value->IsSmi()) { |
50 int32_t val = Smi::cast(value)->value(); | 59 int32_t val = Smi::cast(value)->value(); |
51 CHECK_GE(val, 0); | 60 CHECK_GE(val, 0); |
52 return static_cast<uint32_t>(val); | 61 return static_cast<uint32_t>(val); |
53 } | 62 } |
54 DCHECK(value->IsHeapNumber()); | 63 DCHECK(value->IsHeapNumber()); |
55 HeapNumber* num = HeapNumber::cast(value); | 64 HeapNumber* num = HeapNumber::cast(value); |
56 CHECK_GE(num->value(), 0.0); | 65 CHECK_GE(num->value(), 0.0); |
57 CHECK_LE(num->value(), kMaxUInt32); | 66 CHECK_LE(num->value(), kMaxUInt32); |
58 return static_cast<uint32_t>(num->value()); | 67 return static_cast<uint32_t>(num->value()); |
59 } | 68 } |
60 | 69 |
61 static int32_t SafeInt32(Object* value) { | 70 int32_t SafeInt32(Object* value) { |
62 if (value->IsSmi()) { | 71 if (value->IsSmi()) { |
63 return Smi::cast(value)->value(); | 72 return Smi::cast(value)->value(); |
64 } | 73 } |
65 DCHECK(value->IsHeapNumber()); | 74 DCHECK(value->IsHeapNumber()); |
66 HeapNumber* num = HeapNumber::cast(value); | 75 HeapNumber* num = HeapNumber::cast(value); |
67 CHECK_GE(num->value(), Smi::kMinValue); | 76 CHECK_GE(num->value(), Smi::kMinValue); |
68 CHECK_LE(num->value(), Smi::kMaxValue); | 77 CHECK_LE(num->value(), Smi::kMaxValue); |
69 return static_cast<int32_t>(num->value()); | 78 return static_cast<int32_t>(num->value()); |
70 } | 79 } |
71 | 80 |
| 81 } // namespace |
| 82 |
72 Handle<WasmModuleObject> WasmModuleObject::New( | 83 Handle<WasmModuleObject> WasmModuleObject::New( |
73 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { | 84 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { |
74 ModuleOrigin origin = compiled_module->module()->origin; | 85 ModuleOrigin origin = compiled_module->module()->origin; |
75 | 86 |
76 Handle<JSObject> module_object; | 87 Handle<JSObject> module_object; |
77 if (origin == ModuleOrigin::kWasmOrigin) { | 88 if (origin == ModuleOrigin::kWasmOrigin) { |
78 Handle<JSFunction> module_cons( | 89 Handle<JSFunction> module_cons( |
79 isolate->native_context()->wasm_module_constructor()); | 90 isolate->native_context()->wasm_module_constructor()); |
80 module_object = isolate->factory()->NewJSObject(module_cons); | 91 module_object = isolate->factory()->NewJSObject(module_cons); |
81 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); | 92 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); |
(...skipping 18 matching lines...) Expand all Loading... |
100 DCHECK(object->IsJSObject()); | 111 DCHECK(object->IsJSObject()); |
101 // TODO(titzer): brand check for WasmModuleObject. | 112 // TODO(titzer): brand check for WasmModuleObject. |
102 return reinterpret_cast<WasmModuleObject*>(object); | 113 return reinterpret_cast<WasmModuleObject*>(object); |
103 } | 114 } |
104 | 115 |
105 bool WasmModuleObject::IsWasmModuleObject(Object* object) { | 116 bool WasmModuleObject::IsWasmModuleObject(Object* object) { |
106 return object->IsJSObject() && | 117 return object->IsJSObject() && |
107 JSObject::cast(object)->GetInternalFieldCount() == kFieldCount; | 118 JSObject::cast(object)->GetInternalFieldCount() == kFieldCount; |
108 } | 119 } |
109 | 120 |
110 DEFINE_GETTER(WasmModuleObject, compiled_module, kCompiledModule, | 121 DEFINE_OBJ_GETTER(WasmModuleObject, compiled_module, kCompiledModule, |
111 WasmCompiledModule) | 122 WasmCompiledModule) |
112 | 123 |
113 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial, | 124 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial, |
114 uint32_t maximum, | 125 uint32_t maximum, |
115 Handle<FixedArray>* js_functions) { | 126 Handle<FixedArray>* js_functions) { |
116 Handle<JSFunction> table_ctor( | 127 Handle<JSFunction> table_ctor( |
117 isolate->native_context()->wasm_table_constructor()); | 128 isolate->native_context()->wasm_table_constructor()); |
118 Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor); | 129 Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor); |
119 *js_functions = isolate->factory()->NewFixedArray(initial); | 130 *js_functions = isolate->factory()->NewFixedArray(initial); |
120 Object* null = isolate->heap()->null_value(); | 131 Object* null = isolate->heap()->null_value(); |
121 for (int i = 0; i < static_cast<int>(initial); ++i) { | 132 for (int i = 0; i < static_cast<int>(initial); ++i) { |
122 (*js_functions)->set(i, null); | 133 (*js_functions)->set(i, null); |
123 } | 134 } |
124 table_obj->SetInternalField(kFunctions, *(*js_functions)); | 135 table_obj->SetInternalField(kFunctions, *(*js_functions)); |
125 table_obj->SetInternalField(kMaximum, | 136 table_obj->SetInternalField(kMaximum, |
126 static_cast<Object*>(Smi::FromInt(maximum))); | 137 static_cast<Object*>(Smi::FromInt(maximum))); |
127 | 138 |
128 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0); | 139 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0); |
129 table_obj->SetInternalField(kDispatchTables, *dispatch_tables); | 140 table_obj->SetInternalField(kDispatchTables, *dispatch_tables); |
130 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym()); | 141 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym()); |
131 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check(); | 142 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check(); |
132 return Handle<WasmTableObject>::cast(table_obj); | 143 return Handle<WasmTableObject>::cast(table_obj); |
133 } | 144 } |
134 | 145 |
135 DEFINE_GETTER(WasmTableObject, dispatch_tables, kDispatchTables, FixedArray) | 146 DEFINE_OBJ_GETTER(WasmTableObject, dispatch_tables, kDispatchTables, FixedArray) |
136 | 147 |
137 Handle<FixedArray> WasmTableObject::AddDispatchTable( | 148 Handle<FixedArray> WasmTableObject::AddDispatchTable( |
138 Isolate* isolate, Handle<WasmTableObject> table_obj, | 149 Isolate* isolate, Handle<WasmTableObject> table_obj, |
139 Handle<WasmInstanceObject> instance, int table_index, | 150 Handle<WasmInstanceObject> instance, int table_index, |
140 Handle<FixedArray> dispatch_table) { | 151 Handle<FixedArray> dispatch_table) { |
141 Handle<FixedArray> dispatch_tables( | 152 Handle<FixedArray> dispatch_tables( |
142 FixedArray::cast(table_obj->GetInternalField(kDispatchTables)), isolate); | 153 FixedArray::cast(table_obj->GetInternalField(kDispatchTables)), isolate); |
143 DCHECK_EQ(0, dispatch_tables->length() % 3); | 154 DCHECK_EQ(0, dispatch_tables->length() % 3); |
144 | 155 |
145 if (instance.is_null()) return dispatch_tables; | 156 if (instance.is_null()) return dispatch_tables; |
146 // TODO(titzer): use weak cells here to avoid leaking instances. | 157 // TODO(titzer): use weak cells here to avoid leaking instances. |
147 | 158 |
148 // Grow the dispatch table and add a new triple at the end. | 159 // Grow the dispatch table and add a new triple at the end. |
149 Handle<FixedArray> new_dispatch_tables = | 160 Handle<FixedArray> new_dispatch_tables = |
150 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3); | 161 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3); |
151 | 162 |
152 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance); | 163 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance); |
153 new_dispatch_tables->set(dispatch_tables->length() + 1, | 164 new_dispatch_tables->set(dispatch_tables->length() + 1, |
154 Smi::FromInt(table_index)); | 165 Smi::FromInt(table_index)); |
155 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table); | 166 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table); |
156 | 167 |
157 table_obj->SetInternalField(WasmTableObject::kDispatchTables, | 168 table_obj->SetInternalField(WasmTableObject::kDispatchTables, |
158 *new_dispatch_tables); | 169 *new_dispatch_tables); |
159 | 170 |
160 return new_dispatch_tables; | 171 return new_dispatch_tables; |
161 } | 172 } |
162 | 173 |
163 DEFINE_ACCESSORS(WasmTableObject, functions, kFunctions, FixedArray) | 174 DEFINE_OBJ_ACCESSORS(WasmTableObject, functions, kFunctions, FixedArray) |
164 | 175 |
165 uint32_t WasmTableObject::current_length() { return get_functions()->length(); } | 176 uint32_t WasmTableObject::current_length() { return functions()->length(); } |
166 | 177 |
167 uint32_t WasmTableObject::maximum_length() { | 178 uint32_t WasmTableObject::maximum_length() { |
168 return SafeUint32(GetInternalField(kMaximum)); | 179 return SafeUint32(GetInternalField(kMaximum)); |
169 } | 180 } |
170 | 181 |
171 WasmTableObject* WasmTableObject::cast(Object* object) { | 182 WasmTableObject* WasmTableObject::cast(Object* object) { |
172 DCHECK(object && object->IsJSObject()); | 183 DCHECK(object && object->IsJSObject()); |
173 // TODO(titzer): brand check for WasmTableObject. | 184 // TODO(titzer): brand check for WasmTableObject. |
174 return reinterpret_cast<WasmTableObject*>(object); | 185 return reinterpret_cast<WasmTableObject*>(object); |
175 } | 186 } |
176 | 187 |
177 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate, | 188 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate, |
178 Handle<JSArrayBuffer> buffer, | 189 Handle<JSArrayBuffer> buffer, |
179 int maximum) { | 190 int maximum) { |
180 Handle<JSFunction> memory_ctor( | 191 Handle<JSFunction> memory_ctor( |
181 isolate->native_context()->wasm_memory_constructor()); | 192 isolate->native_context()->wasm_memory_constructor()); |
182 Handle<JSObject> memory_obj = | 193 Handle<JSObject> memory_obj = |
183 isolate->factory()->NewJSObject(memory_ctor, TENURED); | 194 isolate->factory()->NewJSObject(memory_ctor, TENURED); |
184 memory_obj->SetInternalField(kArrayBuffer, *buffer); | 195 memory_obj->SetInternalField(kArrayBuffer, *buffer); |
185 memory_obj->SetInternalField(kMaximum, | 196 memory_obj->SetInternalField(kMaximum, |
186 static_cast<Object*>(Smi::FromInt(maximum))); | 197 static_cast<Object*>(Smi::FromInt(maximum))); |
187 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); | 198 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); |
188 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); | 199 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); |
189 return Handle<WasmMemoryObject>::cast(memory_obj); | 200 return Handle<WasmMemoryObject>::cast(memory_obj); |
190 } | 201 } |
191 | 202 |
192 DEFINE_ACCESSORS(WasmMemoryObject, buffer, kArrayBuffer, JSArrayBuffer) | 203 DEFINE_OBJ_ACCESSORS(WasmMemoryObject, buffer, kArrayBuffer, JSArrayBuffer) |
193 DEFINE_OPTIONAL_ACCESSORS(WasmMemoryObject, instances_link, kInstancesLink, | 204 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmMemoryObject, instances_link, kInstancesLink, |
194 WasmInstanceWrapper) | 205 WasmInstanceWrapper) |
195 | 206 |
196 uint32_t WasmMemoryObject::current_pages() { | 207 uint32_t WasmMemoryObject::current_pages() { |
197 return SafeUint32(get_buffer()->byte_length()) / wasm::WasmModule::kPageSize; | 208 return SafeUint32(buffer()->byte_length()) / wasm::WasmModule::kPageSize; |
198 } | 209 } |
199 | 210 |
200 int32_t WasmMemoryObject::maximum_pages() { | 211 int32_t WasmMemoryObject::maximum_pages() { |
201 return SafeInt32(GetInternalField(kMaximum)); | 212 return SafeInt32(GetInternalField(kMaximum)); |
202 } | 213 } |
203 | 214 |
204 WasmMemoryObject* WasmMemoryObject::cast(Object* object) { | 215 WasmMemoryObject* WasmMemoryObject::cast(Object* object) { |
205 DCHECK(object && object->IsJSObject()); | 216 DCHECK(object && object->IsJSObject()); |
206 // TODO(titzer): brand check for WasmMemoryObject. | 217 // TODO(titzer): brand check for WasmMemoryObject. |
207 return reinterpret_cast<WasmMemoryObject*>(object); | 218 return reinterpret_cast<WasmMemoryObject*>(object); |
208 } | 219 } |
209 | 220 |
210 void WasmMemoryObject::AddInstance(Isolate* isolate, | 221 void WasmMemoryObject::AddInstance(Isolate* isolate, |
211 Handle<WasmInstanceObject> instance) { | 222 Handle<WasmInstanceObject> instance) { |
212 Handle<WasmInstanceWrapper> instance_wrapper = | 223 Handle<WasmInstanceWrapper> instance_wrapper = |
213 handle(instance->get_instance_wrapper()); | 224 handle(instance->instance_wrapper()); |
214 if (has_instances_link()) { | 225 if (has_instances_link()) { |
215 Handle<WasmInstanceWrapper> current_wrapper(get_instances_link()); | 226 Handle<WasmInstanceWrapper> current_wrapper(instances_link()); |
216 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); | 227 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); |
217 DCHECK(!current_wrapper->has_previous()); | 228 DCHECK(!current_wrapper->has_previous()); |
218 instance_wrapper->set_next_wrapper(*current_wrapper); | 229 instance_wrapper->set_next_wrapper(*current_wrapper); |
219 current_wrapper->set_previous_wrapper(*instance_wrapper); | 230 current_wrapper->set_previous_wrapper(*instance_wrapper); |
220 } | 231 } |
221 set_instances_link(*instance_wrapper); | 232 set_instances_link(*instance_wrapper); |
222 } | 233 } |
223 | 234 |
224 void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) { | 235 void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) { |
225 Handle<Object> undefined = isolate->factory()->undefined_value(); | 236 Handle<Object> undefined = isolate->factory()->undefined_value(); |
226 SetInternalField(kInstancesLink, *undefined); | 237 SetInternalField(kInstancesLink, *undefined); |
227 } | 238 } |
228 | 239 |
229 DEFINE_ACCESSORS(WasmInstanceObject, compiled_module, kCompiledModule, | 240 DEFINE_OBJ_ACCESSORS(WasmInstanceObject, compiled_module, kCompiledModule, |
230 WasmCompiledModule) | 241 WasmCompiledModule) |
231 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, globals_buffer, | 242 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, globals_buffer, |
232 kGlobalsArrayBuffer, JSArrayBuffer) | 243 kGlobalsArrayBuffer, JSArrayBuffer) |
233 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, memory_buffer, kMemoryArrayBuffer, | 244 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_buffer, |
234 JSArrayBuffer) | 245 kMemoryArrayBuffer, JSArrayBuffer) |
235 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, memory_object, kMemoryObject, | 246 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_object, kMemoryObject, |
236 WasmMemoryObject) | 247 WasmMemoryObject) |
237 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, debug_info, kDebugInfo, | 248 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, debug_info, kDebugInfo, |
238 WasmDebugInfo) | 249 WasmDebugInfo) |
239 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, instance_wrapper, | 250 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, instance_wrapper, |
240 kWasmMemInstanceWrapper, WasmInstanceWrapper) | 251 kWasmMemInstanceWrapper, WasmInstanceWrapper) |
241 | 252 |
242 WasmModuleObject* WasmInstanceObject::module_object() { | 253 WasmModuleObject* WasmInstanceObject::module_object() { |
243 return WasmModuleObject::cast(*get_compiled_module()->wasm_module()); | 254 return *compiled_module()->wasm_module(); |
244 } | 255 } |
245 | 256 |
246 WasmModule* WasmInstanceObject::module() { | 257 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } |
247 return reinterpret_cast<WasmModuleWrapper*>( | 258 |
248 *get_compiled_module()->module_wrapper()) | 259 Handle<WasmDebugInfo> WasmInstanceObject::GetOrCreateDebugInfo( |
249 ->get(); | 260 Handle<WasmInstanceObject> instance) { |
| 261 if (instance->has_debug_info()) return handle(instance->debug_info()); |
| 262 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); |
| 263 instance->set_debug_info(*new_info); |
| 264 return new_info; |
250 } | 265 } |
251 | 266 |
252 WasmInstanceObject* WasmInstanceObject::cast(Object* object) { | 267 WasmInstanceObject* WasmInstanceObject::cast(Object* object) { |
253 DCHECK(IsWasmInstanceObject(object)); | 268 DCHECK(IsWasmInstanceObject(object)); |
254 return reinterpret_cast<WasmInstanceObject*>(object); | 269 return reinterpret_cast<WasmInstanceObject*>(object); |
255 } | 270 } |
256 | 271 |
257 bool WasmInstanceObject::IsWasmInstanceObject(Object* object) { | 272 bool WasmInstanceObject::IsWasmInstanceObject(Object* object) { |
258 if (!object->IsObject()) return false; | |
259 if (!object->IsJSObject()) return false; | 273 if (!object->IsJSObject()) return false; |
260 | 274 |
261 JSObject* obj = JSObject::cast(object); | 275 JSObject* obj = JSObject::cast(object); |
262 Isolate* isolate = obj->GetIsolate(); | 276 Isolate* isolate = obj->GetIsolate(); |
263 if (obj->GetInternalFieldCount() != kFieldCount) { | 277 if (obj->GetInternalFieldCount() != kFieldCount) { |
264 return false; | 278 return false; |
265 } | 279 } |
266 | 280 |
267 Object* mem = obj->GetInternalField(kMemoryArrayBuffer); | 281 Object* mem = obj->GetInternalField(kMemoryArrayBuffer); |
268 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || | 282 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 shared->set_internal_formal_parameter_count(arity); | 344 shared->set_internal_formal_parameter_count(arity); |
331 Handle<JSFunction> function = isolate->factory()->NewFunction( | 345 Handle<JSFunction> function = isolate->factory()->NewFunction( |
332 isolate->wasm_function_map(), name, export_wrapper); | 346 isolate->wasm_function_map(), name, export_wrapper); |
333 function->set_shared(*shared); | 347 function->set_shared(*shared); |
334 | 348 |
335 function->SetInternalField(kInstance, *instance); | 349 function->SetInternalField(kInstance, *instance); |
336 function->SetInternalField(kIndex, Smi::FromInt(func_index)); | 350 function->SetInternalField(kIndex, Smi::FromInt(func_index)); |
337 return Handle<WasmExportedFunction>::cast(function); | 351 return Handle<WasmExportedFunction>::cast(function); |
338 } | 352 } |
339 | 353 |
| 354 bool WasmSharedModuleData::IsWasmSharedModuleData(Object* object) { |
| 355 if (!object->IsFixedArray()) return false; |
| 356 FixedArray* arr = FixedArray::cast(object); |
| 357 if (arr->length() != kFieldCount) return false; |
| 358 Isolate* isolate = arr->GetIsolate(); |
| 359 if (!arr->get(kModuleWrapper)->IsForeign()) return false; |
| 360 if (!arr->get(kModuleBytes)->IsUndefined(isolate) && |
| 361 !arr->get(kModuleBytes)->IsSeqOneByteString()) |
| 362 return false; |
| 363 if (!arr->get(kScript)->IsScript()) return false; |
| 364 if (!arr->get(kAsmJsOffsetTable)->IsUndefined(isolate) && |
| 365 !arr->get(kAsmJsOffsetTable)->IsByteArray()) |
| 366 return false; |
| 367 return true; |
| 368 } |
| 369 |
| 370 WasmSharedModuleData* WasmSharedModuleData::cast(Object* object) { |
| 371 DCHECK(IsWasmSharedModuleData(object)); |
| 372 return reinterpret_cast<WasmSharedModuleData*>(object); |
| 373 } |
| 374 |
| 375 wasm::WasmModule* WasmSharedModuleData::module() { |
| 376 return reinterpret_cast<WasmModuleWrapper*>(get(kModuleWrapper))->get(); |
| 377 } |
| 378 |
| 379 DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, module_bytes, kModuleBytes, |
| 380 SeqOneByteString); |
| 381 DEFINE_ARR_GETTER(WasmSharedModuleData, script, kScript, Script); |
| 382 DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, asm_js_offset_table, |
| 383 kAsmJsOffsetTable, ByteArray); |
| 384 |
| 385 Handle<WasmSharedModuleData> WasmSharedModuleData::New( |
| 386 Isolate* isolate, Handle<Foreign> module_wrapper, |
| 387 Handle<SeqOneByteString> module_bytes, Handle<Script> script, |
| 388 Handle<ByteArray> asm_js_offset_table) { |
| 389 Handle<FixedArray> arr = |
| 390 isolate->factory()->NewFixedArray(kFieldCount, TENURED); |
| 391 |
| 392 arr->set(kModuleWrapper, *module_wrapper); |
| 393 if (!module_bytes.is_null()) { |
| 394 arr->set(kModuleBytes, *module_bytes); |
| 395 } |
| 396 if (!script.is_null()) { |
| 397 arr->set(kScript, *script); |
| 398 } |
| 399 if (!asm_js_offset_table.is_null()) { |
| 400 arr->set(kAsmJsOffsetTable, *asm_js_offset_table); |
| 401 } |
| 402 |
| 403 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*arr)); |
| 404 return Handle<WasmSharedModuleData>::cast(arr); |
| 405 } |
| 406 |
| 407 bool WasmSharedModuleData::is_asm_js() { |
| 408 bool asm_js = module()->origin == wasm::ModuleOrigin::kAsmJsOrigin; |
| 409 DCHECK_EQ(asm_js, script()->type() == Script::TYPE_NORMAL); |
| 410 DCHECK_EQ(asm_js, has_asm_js_offset_table()); |
| 411 return asm_js; |
| 412 } |
| 413 |
| 414 void WasmSharedModuleData::RecreateModuleWrapper( |
| 415 Isolate* isolate, Handle<WasmSharedModuleData> shared) { |
| 416 DCHECK(shared->get(kModuleWrapper)->IsUndefined(isolate)); |
| 417 |
| 418 WasmModule* module = nullptr; |
| 419 { |
| 420 // We parse the module again directly from the module bytes, so |
| 421 // the underlying storage must not be moved meanwhile. |
| 422 DisallowHeapAllocation no_allocation; |
| 423 SeqOneByteString* module_bytes = shared->module_bytes(); |
| 424 const byte* start = |
| 425 reinterpret_cast<const byte*>(module_bytes->GetCharsAddress()); |
| 426 const byte* end = start + module_bytes->length(); |
| 427 // TODO(titzer): remember the module origin in the compiled_module |
| 428 // For now, we assume serialized modules did not originate from asm.js. |
| 429 ModuleResult result = |
| 430 DecodeWasmModule(isolate, start, end, false, kWasmOrigin); |
| 431 CHECK(result.ok()); |
| 432 CHECK_NOT_NULL(result.val); |
| 433 module = const_cast<WasmModule*>(result.val); |
| 434 } |
| 435 |
| 436 Handle<WasmModuleWrapper> module_wrapper = |
| 437 WasmModuleWrapper::New(isolate, module); |
| 438 |
| 439 shared->set(kModuleWrapper, *module_wrapper); |
| 440 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); |
| 441 } |
| 442 |
340 Handle<WasmCompiledModule> WasmCompiledModule::New( | 443 Handle<WasmCompiledModule> WasmCompiledModule::New( |
341 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) { | 444 Isolate* isolate, Handle<WasmSharedModuleData> shared) { |
342 Handle<FixedArray> ret = | 445 Handle<FixedArray> ret = |
343 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); | 446 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); |
344 // WasmCompiledModule::cast would fail since module bytes are not set yet. | 447 // WasmCompiledModule::cast would fail since fields are not set yet. |
345 Handle<WasmCompiledModule> compiled_module( | 448 Handle<WasmCompiledModule> compiled_module( |
346 reinterpret_cast<WasmCompiledModule*>(*ret), isolate); | 449 reinterpret_cast<WasmCompiledModule*>(*ret), isolate); |
347 compiled_module->InitId(); | 450 compiled_module->InitId(); |
348 compiled_module->set_module_wrapper(module_wrapper); | 451 compiled_module->set_shared(shared); |
349 return compiled_module; | 452 return compiled_module; |
350 } | 453 } |
351 | 454 |
352 wasm::WasmModule* WasmCompiledModule::module() const { | |
353 return reinterpret_cast<WasmModuleWrapper*>(ptr_to_module_wrapper())->get(); | |
354 } | |
355 | |
356 void WasmCompiledModule::InitId() { | 455 void WasmCompiledModule::InitId() { |
357 #if DEBUG | 456 #if DEBUG |
358 static uint32_t instance_id_counter = 0; | 457 static uint32_t instance_id_counter = 0; |
359 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); | 458 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); |
360 TRACE("New compiled module id: %d\n", instance_id()); | 459 TRACE("New compiled module id: %d\n", instance_id()); |
361 #endif | 460 #endif |
362 } | 461 } |
363 | 462 |
364 MaybeHandle<String> WasmCompiledModule::ExtractUtf8StringFromModuleBytes( | 463 MaybeHandle<String> WasmCompiledModule::ExtractUtf8StringFromModuleBytes( |
365 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, | 464 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, |
366 uint32_t offset, uint32_t size) { | 465 uint32_t offset, uint32_t size) { |
367 // TODO(wasm): cache strings from modules if it's a performance win. | 466 // TODO(wasm): cache strings from modules if it's a performance win. |
368 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); | 467 Handle<SeqOneByteString> module_bytes(compiled_module->module_bytes(), |
| 468 isolate); |
369 DCHECK_GE(module_bytes->length(), offset); | 469 DCHECK_GE(module_bytes->length(), offset); |
370 DCHECK_GE(module_bytes->length() - offset, size); | 470 DCHECK_GE(module_bytes->length() - offset, size); |
371 Address raw = module_bytes->GetCharsAddress() + offset; | 471 Address raw = module_bytes->GetCharsAddress() + offset; |
372 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) | 472 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) |
373 return {}; // UTF8 decoding error for name. | 473 return {}; // UTF8 decoding error for name. |
374 DCHECK_GE(kMaxInt, offset); | 474 DCHECK_GE(kMaxInt, offset); |
375 DCHECK_GE(kMaxInt, size); | 475 DCHECK_GE(kMaxInt, size); |
376 return isolate->factory()->NewStringFromUtf8SubString( | 476 return isolate->factory()->NewStringFromUtf8SubString( |
377 module_bytes, static_cast<int>(offset), static_cast<int>(size)); | 477 module_bytes, static_cast<int>(offset), static_cast<int>(size)); |
378 } | 478 } |
379 | 479 |
380 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { | 480 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { |
381 if (!obj->IsFixedArray()) return false; | 481 if (!obj->IsFixedArray()) return false; |
382 FixedArray* arr = FixedArray::cast(obj); | 482 FixedArray* arr = FixedArray::cast(obj); |
383 if (arr->length() != PropertyIndices::Count) return false; | 483 if (arr->length() != PropertyIndices::Count) return false; |
384 Isolate* isolate = arr->GetIsolate(); | 484 Isolate* isolate = arr->GetIsolate(); |
385 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \ | 485 #define WCM_CHECK_TYPE(NAME, TYPE_CHECK) \ |
386 if (!arr->get(kID_##NAME)->IsSmi()) return false; | 486 do { \ |
387 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \ | 487 Object* obj = arr->get(kID_##NAME); \ |
388 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \ | 488 if (!(TYPE_CHECK)) return false; \ |
389 !arr->get(kID_##NAME)->Is##TYPE()) \ | 489 } while (false); |
390 return false; | 490 #define WCM_CHECK_OBJECT(TYPE, NAME) \ |
391 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) | 491 WCM_CHECK_TYPE(NAME, obj->IsUndefined(isolate) || obj->Is##TYPE()) |
392 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME) | 492 #define WCM_CHECK_WASM_OBJECT(TYPE, NAME) \ |
| 493 WCM_CHECK_TYPE(NAME, TYPE::Is##TYPE(obj)) |
| 494 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT(WeakCell, NAME) |
| 495 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) WCM_CHECK_TYPE(NAME, obj->IsSmi()) |
393 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) | 496 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) |
394 WCM_PROPERTY_TABLE(WCM_CHECK) | 497 WCM_PROPERTY_TABLE(WCM_CHECK) |
395 #undef WCM_CHECK | 498 #undef WCM_CHECK |
396 | 499 |
397 // All checks passed. | 500 // All checks passed. |
398 return true; | 501 return true; |
399 } | 502 } |
400 | 503 |
401 void WasmCompiledModule::PrintInstancesChain() { | 504 void WasmCompiledModule::PrintInstancesChain() { |
402 #if DEBUG | 505 #if DEBUG |
403 if (!FLAG_trace_wasm_instances) return; | 506 if (!FLAG_trace_wasm_instances) return; |
404 for (WasmCompiledModule* current = this; current != nullptr;) { | 507 for (WasmCompiledModule* current = this; current != nullptr;) { |
405 PrintF("->%d", current->instance_id()); | 508 PrintF("->%d", current->instance_id()); |
406 if (!current->has_weak_next_instance()) break; | 509 if (!current->has_weak_next_instance()) break; |
407 CHECK(!current->ptr_to_weak_next_instance()->cleared()); | 510 CHECK(!current->ptr_to_weak_next_instance()->cleared()); |
408 current = | 511 current = |
409 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | 512 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); |
410 } | 513 } |
411 PrintF("\n"); | 514 PrintF("\n"); |
412 #endif | 515 #endif |
413 } | 516 } |
414 | 517 |
415 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, | 518 void WasmCompiledModule::RecreateModuleWrapper( |
416 Handle<FixedArray> array) { | 519 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { |
417 Handle<WasmCompiledModule> compiled_module( | 520 // This method must only be called immediately after deserialization. |
418 reinterpret_cast<WasmCompiledModule*>(*array), isolate); | 521 // At this point, no module wrapper exists, so the shared module data is |
419 | 522 // incomplete. |
420 WasmModule* module = nullptr; | 523 Handle<WasmSharedModuleData> shared( |
421 { | 524 static_cast<WasmSharedModuleData*>(compiled_module->get(kID_shared)), |
422 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); | 525 isolate); |
423 // We parse the module again directly from the module bytes, so | 526 DCHECK(!WasmSharedModuleData::IsWasmSharedModuleData(*shared)); |
424 // the underlying storage must not be moved meanwhile. | 527 WasmSharedModuleData::RecreateModuleWrapper(isolate, shared); |
425 DisallowHeapAllocation no_allocation; | 528 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); |
426 const byte* start = | |
427 reinterpret_cast<const byte*>(module_bytes->GetCharsAddress()); | |
428 const byte* end = start + module_bytes->length(); | |
429 // TODO(titzer): remember the module origin in the compiled_module | |
430 // For now, we assume serialized modules did not originate from asm.js. | |
431 ModuleResult result = | |
432 DecodeWasmModule(isolate, start, end, false, kWasmOrigin); | |
433 CHECK(result.ok()); | |
434 CHECK_NOT_NULL(result.val); | |
435 module = const_cast<WasmModule*>(result.val); | |
436 } | |
437 | |
438 Handle<WasmModuleWrapper> module_wrapper = | |
439 WasmModuleWrapper::New(isolate, module); | |
440 | |
441 compiled_module->set_module_wrapper(module_wrapper); | |
442 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | |
443 } | 529 } |
444 | 530 |
445 uint32_t WasmCompiledModule::mem_size() const { | 531 uint32_t WasmCompiledModule::mem_size() const { |
446 return has_memory() ? memory()->byte_length()->Number() : default_mem_size(); | 532 return has_memory() ? memory()->byte_length()->Number() : default_mem_size(); |
447 } | 533 } |
448 | 534 |
449 uint32_t WasmCompiledModule::default_mem_size() const { | 535 uint32_t WasmCompiledModule::default_mem_size() const { |
450 return min_mem_pages() * WasmModule::kPageSize; | 536 return min_mem_pages() * WasmModule::kPageSize; |
451 } | 537 } |
452 | 538 |
(...skipping 12 matching lines...) Expand all Loading... |
465 MaybeHandle<String> name = | 551 MaybeHandle<String> name = |
466 GetFunctionNameOrNull(isolate, compiled_module, func_index); | 552 GetFunctionNameOrNull(isolate, compiled_module, func_index); |
467 if (!name.is_null()) return name.ToHandleChecked(); | 553 if (!name.is_null()) return name.ToHandleChecked(); |
468 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 554 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
469 } | 555 } |
470 | 556 |
471 Vector<const uint8_t> WasmCompiledModule::GetRawFunctionName( | 557 Vector<const uint8_t> WasmCompiledModule::GetRawFunctionName( |
472 uint32_t func_index) { | 558 uint32_t func_index) { |
473 DCHECK_GT(module()->functions.size(), func_index); | 559 DCHECK_GT(module()->functions.size(), func_index); |
474 WasmFunction& function = module()->functions[func_index]; | 560 WasmFunction& function = module()->functions[func_index]; |
475 SeqOneByteString* bytes = ptr_to_module_bytes(); | 561 SeqOneByteString* bytes = module_bytes(); |
476 DCHECK_GE(bytes->length(), function.name_offset); | 562 DCHECK_GE(bytes->length(), function.name_offset); |
477 DCHECK_GE(bytes->length() - function.name_offset, function.name_length); | 563 DCHECK_GE(bytes->length() - function.name_offset, function.name_length); |
478 return Vector<const uint8_t>(bytes->GetCharsAddress() + function.name_offset, | 564 return Vector<const uint8_t>(bytes->GetCharsAddress() + function.name_offset, |
479 function.name_length); | 565 function.name_length); |
480 } | 566 } |
481 | 567 |
482 int WasmCompiledModule::GetFunctionOffset(uint32_t func_index) const { | 568 int WasmCompiledModule::GetFunctionOffset(uint32_t func_index) { |
483 std::vector<WasmFunction>& functions = module()->functions; | 569 std::vector<WasmFunction>& functions = module()->functions; |
484 if (static_cast<uint32_t>(func_index) >= functions.size()) return -1; | 570 if (static_cast<uint32_t>(func_index) >= functions.size()) return -1; |
485 DCHECK_GE(kMaxInt, functions[func_index].code_start_offset); | 571 DCHECK_GE(kMaxInt, functions[func_index].code_start_offset); |
486 return static_cast<int>(functions[func_index].code_start_offset); | 572 return static_cast<int>(functions[func_index].code_start_offset); |
487 } | 573 } |
488 | 574 |
489 int WasmCompiledModule::GetContainingFunction(uint32_t byte_offset) const { | 575 int WasmCompiledModule::GetContainingFunction(uint32_t byte_offset) { |
490 std::vector<WasmFunction>& functions = module()->functions; | 576 std::vector<WasmFunction>& functions = module()->functions; |
491 | 577 |
492 // Binary search for a function containing the given position. | 578 // Binary search for a function containing the given position. |
493 int left = 0; // inclusive | 579 int left = 0; // inclusive |
494 int right = static_cast<int>(functions.size()); // exclusive | 580 int right = static_cast<int>(functions.size()); // exclusive |
495 if (right == 0) return false; | 581 if (right == 0) return false; |
496 while (right - left > 1) { | 582 while (right - left > 1) { |
497 int mid = left + (right - left) / 2; | 583 int mid = left + (right - left) / 2; |
498 if (functions[mid].code_start_offset <= byte_offset) { | 584 if (functions[mid].code_start_offset <= byte_offset) { |
499 left = mid; | 585 left = mid; |
(...skipping 29 matching lines...) Expand all Loading... |
529 | 615 |
530 enum AsmJsOffsetTableEntryLayout { | 616 enum AsmJsOffsetTableEntryLayout { |
531 kOTEByteOffset, | 617 kOTEByteOffset, |
532 kOTECallPosition, | 618 kOTECallPosition, |
533 kOTENumberConvPosition, | 619 kOTENumberConvPosition, |
534 kOTESize | 620 kOTESize |
535 }; | 621 }; |
536 | 622 |
537 Handle<ByteArray> GetDecodedAsmJsOffsetTable( | 623 Handle<ByteArray> GetDecodedAsmJsOffsetTable( |
538 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { | 624 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { |
539 DCHECK(compiled_module->has_asm_js_offset_table()); | 625 DCHECK(compiled_module->is_asm_js()); |
540 Handle<ByteArray> offset_table = compiled_module->asm_js_offset_table(); | 626 Handle<ByteArray> offset_table( |
| 627 compiled_module->shared()->asm_js_offset_table(), isolate); |
541 | 628 |
542 // The last byte in the asm_js_offset_tables ByteArray tells whether it is | 629 // The last byte in the asm_js_offset_tables ByteArray tells whether it is |
543 // still encoded (0) or decoded (1). | 630 // still encoded (0) or decoded (1). |
544 enum AsmJsTableType : int { Encoded = 0, Decoded = 1 }; | 631 enum AsmJsTableType : int { Encoded = 0, Decoded = 1 }; |
545 int table_type = offset_table->get(offset_table->length() - 1); | 632 int table_type = offset_table->get(offset_table->length() - 1); |
546 DCHECK(table_type == Encoded || table_type == Decoded); | 633 DCHECK(table_type == Encoded || table_type == Decoded); |
547 if (table_type == Decoded) return offset_table; | 634 if (table_type == Decoded) return offset_table; |
548 | 635 |
549 AsmJsOffsetsResult asm_offsets; | 636 AsmJsOffsetsResult asm_offsets; |
550 { | 637 { |
(...skipping 16 matching lines...) Expand all Loading... |
567 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - num_entries); | 654 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - num_entries); |
568 num_entries += static_cast<int>(new_size); | 655 num_entries += static_cast<int>(new_size); |
569 } | 656 } |
570 // One byte to encode that this is a decoded table. | 657 // One byte to encode that this is a decoded table. |
571 DCHECK_GE(kMaxInt, | 658 DCHECK_GE(kMaxInt, |
572 1 + static_cast<uint64_t>(num_entries) * kOTESize * kIntSize); | 659 1 + static_cast<uint64_t>(num_entries) * kOTESize * kIntSize); |
573 int total_size = 1 + num_entries * kOTESize * kIntSize; | 660 int total_size = 1 + num_entries * kOTESize * kIntSize; |
574 Handle<ByteArray> decoded_table = | 661 Handle<ByteArray> decoded_table = |
575 isolate->factory()->NewByteArray(total_size, TENURED); | 662 isolate->factory()->NewByteArray(total_size, TENURED); |
576 decoded_table->set(total_size - 1, AsmJsTableType::Decoded); | 663 decoded_table->set(total_size - 1, AsmJsTableType::Decoded); |
577 compiled_module->set_asm_js_offset_table(decoded_table); | 664 compiled_module->shared()->set_asm_js_offset_table(*decoded_table); |
578 | 665 |
579 int idx = 0; | 666 int idx = 0; |
580 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; | 667 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; |
581 for (int func = 0; func < num_functions; ++func) { | 668 for (int func = 0; func < num_functions; ++func) { |
582 std::vector<AsmJsOffsetEntry>& func_asm_offsets = asm_offsets.val[func]; | 669 std::vector<AsmJsOffsetEntry>& func_asm_offsets = asm_offsets.val[func]; |
583 if (func_asm_offsets.empty()) continue; | 670 if (func_asm_offsets.empty()) continue; |
584 int func_offset = | 671 int func_offset = |
585 wasm_funs[num_imported_functions + func].code_start_offset; | 672 wasm_funs[num_imported_functions + func].code_start_offset; |
586 for (AsmJsOffsetEntry& e : func_asm_offsets) { | 673 for (AsmJsOffsetEntry& e : func_asm_offsets) { |
587 // Byte offsets must be strictly monotonously increasing: | 674 // Byte offsets must be strictly monotonously increasing: |
588 DCHECK_IMPLIES(idx > 0, func_offset + e.byte_offset > | 675 DCHECK_IMPLIES(idx > 0, func_offset + e.byte_offset > |
589 decoded_table->get_int(idx - kOTESize)); | 676 decoded_table->get_int(idx - kOTESize)); |
590 decoded_table->set_int(idx + kOTEByteOffset, func_offset + e.byte_offset); | 677 decoded_table->set_int(idx + kOTEByteOffset, func_offset + e.byte_offset); |
591 decoded_table->set_int(idx + kOTECallPosition, e.source_position_call); | 678 decoded_table->set_int(idx + kOTECallPosition, e.source_position_call); |
592 decoded_table->set_int(idx + kOTENumberConvPosition, | 679 decoded_table->set_int(idx + kOTENumberConvPosition, |
593 e.source_position_number_conversion); | 680 e.source_position_number_conversion); |
594 idx += kOTESize; | 681 idx += kOTESize; |
595 } | 682 } |
596 } | 683 } |
597 DCHECK_EQ(total_size, idx * kIntSize + 1); | 684 DCHECK_EQ(total_size, idx * kIntSize + 1); |
598 return decoded_table; | 685 return decoded_table; |
599 } | 686 } |
| 687 |
600 } // namespace | 688 } // namespace |
601 | 689 |
602 int WasmCompiledModule::GetAsmJsSourcePosition( | 690 int WasmCompiledModule::GetAsmJsSourcePosition( |
603 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, | 691 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, |
604 uint32_t byte_offset, bool is_at_number_conversion) { | 692 uint32_t byte_offset, bool is_at_number_conversion) { |
605 Isolate* isolate = compiled_module->GetIsolate(); | 693 Isolate* isolate = compiled_module->GetIsolate(); |
606 Handle<ByteArray> offset_table = | 694 Handle<ByteArray> offset_table = |
607 GetDecodedAsmJsOffsetTable(compiled_module, isolate); | 695 GetDecodedAsmJsOffsetTable(compiled_module, isolate); |
608 | 696 |
609 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | 697 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
(...skipping 23 matching lines...) Expand all Loading... |
633 } | 721 } |
634 | 722 |
635 v8::debug::WasmDisassembly WasmCompiledModule::DisassembleFunction( | 723 v8::debug::WasmDisassembly WasmCompiledModule::DisassembleFunction( |
636 int func_index) { | 724 int func_index) { |
637 DisallowHeapAllocation no_gc; | 725 DisallowHeapAllocation no_gc; |
638 | 726 |
639 if (func_index < 0 || | 727 if (func_index < 0 || |
640 static_cast<uint32_t>(func_index) >= module()->functions.size()) | 728 static_cast<uint32_t>(func_index) >= module()->functions.size()) |
641 return {}; | 729 return {}; |
642 | 730 |
643 SeqOneByteString* module_bytes_str = ptr_to_module_bytes(); | 731 SeqOneByteString* module_bytes_str = module_bytes(); |
644 Vector<const byte> module_bytes(module_bytes_str->GetChars(), | 732 Vector<const byte> module_bytes(module_bytes_str->GetChars(), |
645 module_bytes_str->length()); | 733 module_bytes_str->length()); |
646 | 734 |
647 std::ostringstream disassembly_os; | 735 std::ostringstream disassembly_os; |
648 v8::debug::WasmDisassembly::OffsetTable offset_table; | 736 v8::debug::WasmDisassembly::OffsetTable offset_table; |
649 | 737 |
650 PrintWasmText(module(), module_bytes, static_cast<uint32_t>(func_index), | 738 PrintWasmText(module(), module_bytes, static_cast<uint32_t>(func_index), |
651 disassembly_os, &offset_table); | 739 disassembly_os, &offset_table); |
652 | 740 |
653 return {disassembly_os.str(), std::move(offset_table)}; | 741 return {disassembly_os.str(), std::move(offset_table)}; |
654 } | 742 } |
655 | 743 |
656 bool WasmCompiledModule::GetPossibleBreakpoints( | 744 bool WasmCompiledModule::GetPossibleBreakpoints( |
657 const v8::debug::Location& start, const v8::debug::Location& end, | 745 const v8::debug::Location& start, const v8::debug::Location& end, |
658 std::vector<v8::debug::Location>* locations) const { | 746 std::vector<v8::debug::Location>* locations) { |
659 DisallowHeapAllocation no_gc; | 747 DisallowHeapAllocation no_gc; |
660 | 748 |
661 std::vector<WasmFunction>& functions = module()->functions; | 749 std::vector<WasmFunction>& functions = module()->functions; |
662 if (start.GetLineNumber() < 0 || start.GetColumnNumber() < 0 || | 750 if (start.GetLineNumber() < 0 || start.GetColumnNumber() < 0 || |
663 (!end.IsEmpty() && | 751 (!end.IsEmpty() && |
664 (end.GetLineNumber() < 0 || end.GetColumnNumber() < 0))) | 752 (end.GetLineNumber() < 0 || end.GetColumnNumber() < 0))) |
665 return false; | 753 return false; |
666 | 754 |
667 // start_func_index, start_offset and end_func_index is inclusive. | 755 // start_func_index, start_offset and end_func_index is inclusive. |
668 // end_offset is exclusive. | 756 // end_offset is exclusive. |
(...skipping 24 matching lines...) Expand all Loading... |
693 } else { | 781 } else { |
694 if (end_func_index >= functions.size()) return false; | 782 if (end_func_index >= functions.size()) return false; |
695 end_offset = | 783 end_offset = |
696 functions[end_func_index].code_start_offset + end.GetColumnNumber(); | 784 functions[end_func_index].code_start_offset + end.GetColumnNumber(); |
697 if (end_offset > functions[end_func_index].code_end_offset) return false; | 785 if (end_offset > functions[end_func_index].code_end_offset) return false; |
698 } | 786 } |
699 } | 787 } |
700 | 788 |
701 AccountingAllocator alloc; | 789 AccountingAllocator alloc; |
702 Zone tmp(&alloc, ZONE_NAME); | 790 Zone tmp(&alloc, ZONE_NAME); |
703 const byte* module_start = ptr_to_module_bytes()->GetChars(); | 791 const byte* module_start = module_bytes()->GetChars(); |
704 | 792 |
705 for (uint32_t func_idx = start_func_index; func_idx <= end_func_index; | 793 for (uint32_t func_idx = start_func_index; func_idx <= end_func_index; |
706 ++func_idx) { | 794 ++func_idx) { |
707 WasmFunction& func = functions[func_idx]; | 795 WasmFunction& func = functions[func_idx]; |
708 if (func.code_start_offset == func.code_end_offset) continue; | 796 if (func.code_start_offset == func.code_end_offset) continue; |
709 | 797 |
710 AstLocalDecls locals(&tmp); | 798 AstLocalDecls locals(&tmp); |
711 BytecodeIterator iterator(module_start + func.code_start_offset, | 799 BytecodeIterator iterator(module_start + func.code_start_offset, |
712 module_start + func.code_end_offset, &locals); | 800 module_start + func.code_end_offset, &locals); |
713 DCHECK_LT(0u, locals.decls_encoded_size); | 801 DCHECK_LT(0u, locals.decls_encoded_size); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) | 835 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) |
748 return false; | 836 return false; |
749 return true; | 837 return true; |
750 } | 838 } |
751 | 839 |
752 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, | 840 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, |
753 Isolate* isolate) { | 841 Isolate* isolate) { |
754 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); | 842 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); |
755 set(kWrapperInstanceObject, *cell); | 843 set(kWrapperInstanceObject, *cell); |
756 } | 844 } |
OLD | NEW |