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/base/atomic-utils.h" | 5 #include "src/base/atomic-utils.h" |
6 #include "src/macro-assembler.h" | 6 #include "src/macro-assembler.h" |
7 #include "src/objects.h" | 7 #include "src/objects.h" |
8 #include "src/property-descriptor.h" | 8 #include "src/property-descriptor.h" |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
11 #include "src/simulator.h" | 11 #include "src/simulator.h" |
12 | 12 |
13 #include "src/wasm/ast-decoder.h" | 13 #include "src/wasm/ast-decoder.h" |
14 #include "src/wasm/module-decoder.h" | 14 #include "src/wasm/module-decoder.h" |
| 15 #include "src/wasm/wasm-debug.h" |
15 #include "src/wasm/wasm-function-name-table.h" | 16 #include "src/wasm/wasm-function-name-table.h" |
16 #include "src/wasm/wasm-module.h" | 17 #include "src/wasm/wasm-module.h" |
17 #include "src/wasm/wasm-result.h" | 18 #include "src/wasm/wasm-result.h" |
18 | 19 |
19 #include "src/compiler/wasm-compiler.h" | 20 #include "src/compiler/wasm-compiler.h" |
20 | 21 |
21 namespace v8 { | 22 namespace v8 { |
22 namespace internal { | 23 namespace internal { |
23 namespace wasm { | 24 namespace wasm { |
24 | 25 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 199 } |
199 if (modified) { | 200 if (modified) { |
200 Assembler::FlushICache(isolate_, code->instruction_start(), | 201 Assembler::FlushICache(isolate_, code->instruction_start(), |
201 code->instruction_size()); | 202 code->instruction_size()); |
202 } | 203 } |
203 } | 204 } |
204 }; | 205 }; |
205 | 206 |
206 namespace { | 207 namespace { |
207 // Internal constants for the layout of the module object. | 208 // Internal constants for the layout of the module object. |
208 const int kWasmModuleInternalFieldCount = 5; | |
209 const int kWasmModuleFunctionTable = 0; | 209 const int kWasmModuleFunctionTable = 0; |
210 const int kWasmModuleCodeTable = 1; | 210 const int kWasmModuleCodeTable = 1; |
211 const int kWasmMemArrayBuffer = 2; | 211 const int kWasmMemArrayBuffer = 2; |
212 const int kWasmGlobalsArrayBuffer = 3; | 212 const int kWasmGlobalsArrayBuffer = 3; |
| 213 // TODO(clemensh): Remove function name array, extract names from module bytes. |
213 const int kWasmFunctionNamesArray = 4; | 214 const int kWasmFunctionNamesArray = 4; |
| 215 const int kWasmModuleBytesString = 5; |
| 216 const int kWasmDebugInfo = 6; |
| 217 const int kWasmModuleInternalFieldCount = 7; |
214 | 218 |
215 void LoadDataSegments(const WasmModule* module, byte* mem_addr, | 219 void LoadDataSegments(const WasmModule* module, byte* mem_addr, |
216 size_t mem_size) { | 220 size_t mem_size) { |
217 for (const WasmDataSegment& segment : module->data_segments) { | 221 for (const WasmDataSegment& segment : module->data_segments) { |
218 if (!segment.init) continue; | 222 if (!segment.init) continue; |
219 if (!segment.source_size) continue; | 223 if (!segment.source_size) continue; |
220 CHECK_LT(segment.dest_addr, mem_size); | 224 CHECK_LT(segment.dest_addr, mem_size); |
221 CHECK_LE(segment.source_size, mem_size); | 225 CHECK_LE(segment.source_size, mem_size); |
222 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); | 226 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); |
223 byte* addr = mem_addr + segment.dest_addr; | 227 byte* addr = mem_addr + segment.dest_addr; |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 //------------------------------------------------------------------------- | 698 //------------------------------------------------------------------------- |
695 Handle<Map> map = factory->NewMap( | 699 Handle<Map> map = factory->NewMap( |
696 JS_OBJECT_TYPE, | 700 JS_OBJECT_TYPE, |
697 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); | 701 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); |
698 WasmModuleInstance instance(this); | 702 WasmModuleInstance instance(this); |
699 instance.context = isolate->native_context(); | 703 instance.context = isolate->native_context(); |
700 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); | 704 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); |
701 Handle<FixedArray> code_table = | 705 Handle<FixedArray> code_table = |
702 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); | 706 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); |
703 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); | 707 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); |
| 708 int module_bytes_len = static_cast<int>(instance.module->module_end - |
| 709 instance.module->module_start); |
| 710 DCHECK_EQ(instance.module->module_end - instance.module->module_start, |
| 711 module_bytes_len); |
| 712 Vector<const uint8_t> module_bytes_vec(instance.module->module_start, |
| 713 module_bytes_len); |
| 714 Handle<String> module_bytes_string = |
| 715 factory->NewStringFromOneByte(module_bytes_vec, TENURED) |
| 716 .ToHandleChecked(); |
| 717 instance.js_object->SetInternalField(kWasmModuleBytesString, |
| 718 *module_bytes_string); |
704 | 719 |
705 //------------------------------------------------------------------------- | 720 //------------------------------------------------------------------------- |
706 // Allocate and initialize the linear memory. | 721 // Allocate and initialize the linear memory. |
707 //------------------------------------------------------------------------- | 722 //------------------------------------------------------------------------- |
708 isolate->counters()->wasm_min_mem_pages_count()->AddSample( | 723 isolate->counters()->wasm_min_mem_pages_count()->AddSample( |
709 instance.module->min_mem_pages); | 724 instance.module->min_mem_pages); |
710 isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 725 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
711 instance.module->max_mem_pages); | 726 instance.module->max_mem_pages); |
712 if (memory.is_null()) { | 727 if (memory.is_null()) { |
713 if (!AllocateMemory(&thrower, isolate, &instance)) { | 728 if (!AllocateMemory(&thrower, isolate, &instance)) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 //------------------------------------------------------------------------- | 851 //------------------------------------------------------------------------- |
837 // Attach an array with function names and an array with offsets into that | 852 // Attach an array with function names and an array with offsets into that |
838 // first array. | 853 // first array. |
839 //------------------------------------------------------------------------- | 854 //------------------------------------------------------------------------- |
840 instance.js_object->SetInternalField( | 855 instance.js_object->SetInternalField( |
841 kWasmFunctionNamesArray, | 856 kWasmFunctionNamesArray, |
842 *BuildFunctionNamesTable(isolate, module_env.module)); | 857 *BuildFunctionNamesTable(isolate, module_env.module)); |
843 | 858 |
844 code_stats.Report(); | 859 code_stats.Report(); |
845 | 860 |
| 861 if (isolate->debug()->is_active()) { |
| 862 // Trigger creation of the debug info, this will inform the debugger about |
| 863 // the new module. |
| 864 wasm::GetDebugInfo(*instance.js_object); |
| 865 } |
| 866 |
846 // Run the start function if one was specified. | 867 // Run the start function if one was specified. |
847 if (this->start_function_index >= 0) { | 868 if (this->start_function_index >= 0) { |
848 HandleScope scope(isolate); | 869 HandleScope scope(isolate); |
849 uint32_t index = static_cast<uint32_t>(this->start_function_index); | 870 uint32_t index = static_cast<uint32_t>(this->start_function_index); |
850 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); | 871 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); |
851 Handle<Code> code = instance.function_code[index]; | 872 Handle<Code> code = instance.function_code[index]; |
852 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( | 873 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( |
853 isolate, &module_env, name, code, instance.js_object, index); | 874 isolate, &module_env, name, code, instance.js_object, index); |
854 | 875 |
855 // Call the JS function. | 876 // Call the JS function. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 } | 1022 } |
1002 | 1023 |
1003 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, | 1024 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, |
1004 uint32_t func_index) { | 1025 uint32_t func_index) { |
1005 Handle<Object> name_or_null = | 1026 Handle<Object> name_or_null = |
1006 GetWasmFunctionNameOrNull(isolate, wasm, func_index); | 1027 GetWasmFunctionNameOrNull(isolate, wasm, func_index); |
1007 if (!name_or_null->IsNull()) return Handle<String>::cast(name_or_null); | 1028 if (!name_or_null->IsNull()) return Handle<String>::cast(name_or_null); |
1008 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 1029 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
1009 } | 1030 } |
1010 | 1031 |
1011 bool IsWasmObject(Handle<JSObject> object) { | 1032 bool IsWasmObject(Object* object) { |
1012 // TODO(clemensh): Check wasm byte header once we store a copy of the bytes. | 1033 if (!object->IsJSObject()) return false; |
1013 return object->GetInternalFieldCount() == kWasmModuleInternalFieldCount && | 1034 JSObject* obj = JSObject::cast(object); |
1014 object->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() && | 1035 if (obj->GetInternalFieldCount() != kWasmModuleInternalFieldCount || |
1015 object->GetInternalField(kWasmMemArrayBuffer)->IsJSArrayBuffer() && | 1036 !obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() || |
1016 object->GetInternalField(kWasmFunctionNamesArray)->IsByteArray(); | 1037 !obj->GetInternalField(kWasmMemArrayBuffer)->IsJSArrayBuffer() || |
| 1038 !obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray() || |
| 1039 !obj->GetInternalField(kWasmModuleBytesString)->IsSeqOneByteString()) { |
| 1040 return false; |
| 1041 } |
| 1042 DisallowHeapAllocation no_gc; |
| 1043 SeqOneByteString* bytes = |
| 1044 SeqOneByteString::cast(obj->GetInternalField(kWasmModuleBytesString)); |
| 1045 if (bytes->length() < 4) return false; |
| 1046 if (memcmp(bytes->GetChars(), "\0asm", 4)) return false; |
| 1047 |
| 1048 // All checks passed. |
| 1049 return true; |
| 1050 } |
| 1051 |
| 1052 SeqOneByteString* GetWasmBytes(JSObject* wasm) { |
| 1053 return SeqOneByteString::cast(wasm->GetInternalField(kWasmModuleBytesString)); |
| 1054 } |
| 1055 |
| 1056 WasmDebugInfo* GetDebugInfo(JSObject* wasm) { |
| 1057 Object* info = wasm->GetInternalField(kWasmDebugInfo); |
| 1058 if (!info->IsUndefined()) return WasmDebugInfo::cast(info); |
| 1059 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm)); |
| 1060 wasm->SetInternalField(kWasmDebugInfo, *new_info); |
| 1061 return *new_info; |
1017 } | 1062 } |
1018 | 1063 |
1019 } // namespace wasm | 1064 } // namespace wasm |
1020 } // namespace internal | 1065 } // namespace internal |
1021 } // namespace v8 | 1066 } // namespace v8 |
OLD | NEW |