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/asmjs/asm-js.h" | 5 #include "src/asmjs/asm-js.h" |
6 | 6 |
7 #include "src/api-natives.h" | 7 #include "src/api-natives.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/asmjs/asm-parser.h" |
9 #include "src/asmjs/asm-typer.h" | 10 #include "src/asmjs/asm-typer.h" |
10 #include "src/asmjs/asm-wasm-builder.h" | 11 #include "src/asmjs/asm-wasm-builder.h" |
11 #include "src/assert-scope.h" | 12 #include "src/assert-scope.h" |
12 #include "src/base/platform/elapsed-timer.h" | 13 #include "src/base/platform/elapsed-timer.h" |
13 #include "src/compilation-info.h" | 14 #include "src/compilation-info.h" |
14 #include "src/execution.h" | 15 #include "src/execution.h" |
15 #include "src/factory.h" | 16 #include "src/factory.h" |
16 #include "src/handles.h" | 17 #include "src/handles.h" |
17 #include "src/isolate.h" | 18 #include "src/isolate.h" |
18 #include "src/objects-inl.h" | 19 #include "src/objects-inl.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 #undef STDLIB_MATH_CONST | 159 #undef STDLIB_MATH_CONST |
159 default: { UNREACHABLE(); } | 160 default: { UNREACHABLE(); } |
160 } | 161 } |
161 return false; | 162 return false; |
162 } | 163 } |
163 | 164 |
164 } // namespace | 165 } // namespace |
165 | 166 |
166 MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { | 167 MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { |
167 ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); | 168 ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); |
| 169 wasm::ZoneBuffer* module = nullptr; |
| 170 wasm::ZoneBuffer* asm_offsets = nullptr; |
| 171 Handle<FixedArray> uses_array; |
| 172 Handle<FixedArray> foreign_globals; |
168 base::ElapsedTimer asm_wasm_timer; | 173 base::ElapsedTimer asm_wasm_timer; |
169 asm_wasm_timer.Start(); | 174 asm_wasm_timer.Start(); |
170 wasm::AsmWasmBuilder builder(info); | 175 wasm::AsmWasmBuilder builder(info); |
171 Handle<FixedArray> foreign_globals; | 176 if (FLAG_fast_validate_asm) { |
172 auto asm_wasm_result = builder.Run(&foreign_globals); | 177 wasm::AsmJsParser parser(info->isolate(), info->zone(), info->script(), |
173 if (!asm_wasm_result.success) { | 178 info->literal()->start_position(), |
174 DCHECK(!info->isolate()->has_pending_exception()); | 179 info->literal()->end_position()); |
175 if (!FLAG_suppress_asm_messages) { | 180 if (!parser.Run()) { |
176 MessageHandler::ReportMessage(info->isolate(), | 181 DCHECK(!info->isolate()->has_pending_exception()); |
177 builder.typer()->message_location(), | 182 if (!FLAG_suppress_asm_messages) { |
178 builder.typer()->error_message()); | 183 MessageLocation location(info->script(), parser.failure_location(), |
| 184 parser.failure_location()); |
| 185 Handle<String> message = |
| 186 info->isolate() |
| 187 ->factory() |
| 188 ->NewStringFromUtf8(CStrVector(parser.failure_message())) |
| 189 .ToHandleChecked(); |
| 190 Handle<JSMessageObject> error_message = |
| 191 MessageHandler::MakeMessageObject( |
| 192 info->isolate(), MessageTemplate::kAsmJsInvalid, &location, |
| 193 message, Handle<JSArray>::null()); |
| 194 error_message->set_error_level(v8::Isolate::kMessageWarning); |
| 195 MessageHandler::ReportMessage(info->isolate(), &location, |
| 196 error_message); |
| 197 } |
| 198 return MaybeHandle<FixedArray>(); |
179 } | 199 } |
180 return MaybeHandle<FixedArray>(); | 200 Zone* zone = info->zone(); |
| 201 module = new (zone) wasm::ZoneBuffer(zone); |
| 202 parser.module_builder()->WriteTo(*module); |
| 203 asm_offsets = new (zone) wasm::ZoneBuffer(zone); |
| 204 parser.module_builder()->WriteAsmJsOffsetTable(*asm_offsets); |
| 205 // TODO(bradnelson): Remove foreign_globals plumbing (as we don't need it |
| 206 // for the new parser). |
| 207 foreign_globals = info->isolate()->factory()->NewFixedArray(0); |
| 208 uses_array = info->isolate()->factory()->NewFixedArray( |
| 209 static_cast<int>(parser.stdlib_uses()->size())); |
| 210 int count = 0; |
| 211 for (auto i : *parser.stdlib_uses()) { |
| 212 uses_array->set(count++, Smi::FromInt(i)); |
| 213 } |
| 214 } else { |
| 215 auto asm_wasm_result = builder.Run(&foreign_globals); |
| 216 if (!asm_wasm_result.success) { |
| 217 DCHECK(!info->isolate()->has_pending_exception()); |
| 218 if (!FLAG_suppress_asm_messages) { |
| 219 MessageHandler::ReportMessage(info->isolate(), |
| 220 builder.typer()->message_location(), |
| 221 builder.typer()->error_message()); |
| 222 } |
| 223 return MaybeHandle<FixedArray>(); |
| 224 } |
| 225 module = asm_wasm_result.module_bytes; |
| 226 asm_offsets = asm_wasm_result.asm_offset_table; |
| 227 wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses(); |
| 228 uses_array = info->isolate()->factory()->NewFixedArray( |
| 229 static_cast<int>(uses.size())); |
| 230 int count = 0; |
| 231 for (auto i : uses) { |
| 232 uses_array->set(count++, Smi::FromInt(i)); |
| 233 } |
181 } | 234 } |
| 235 |
182 double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF(); | 236 double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF(); |
183 | |
184 wasm::ZoneBuffer* module = asm_wasm_result.module_bytes; | |
185 wasm::ZoneBuffer* asm_offsets = asm_wasm_result.asm_offset_table; | |
186 Vector<const byte> asm_offsets_vec(asm_offsets->begin(), | 237 Vector<const byte> asm_offsets_vec(asm_offsets->begin(), |
187 static_cast<int>(asm_offsets->size())); | 238 static_cast<int>(asm_offsets->size())); |
188 | 239 |
189 base::ElapsedTimer compile_timer; | 240 base::ElapsedTimer compile_timer; |
190 compile_timer.Start(); | 241 compile_timer.Start(); |
191 MaybeHandle<JSObject> compiled = SyncCompileTranslatedAsmJs( | 242 MaybeHandle<JSObject> compiled = SyncCompileTranslatedAsmJs( |
192 info->isolate(), &thrower, | 243 info->isolate(), &thrower, |
193 wasm::ModuleWireBytes(module->begin(), module->end()), info->script(), | 244 wasm::ModuleWireBytes(module->begin(), module->end()), info->script(), |
194 asm_offsets_vec); | 245 asm_offsets_vec); |
195 DCHECK(!compiled.is_null()); | 246 DCHECK(!compiled.is_null()); |
196 double compile_time = compile_timer.Elapsed().InMillisecondsF(); | 247 double compile_time = compile_timer.Elapsed().InMillisecondsF(); |
197 DCHECK_GE(module->end(), module->begin()); | 248 DCHECK_GE(module->end(), module->begin()); |
198 uintptr_t wasm_size = module->end() - module->begin(); | 249 uintptr_t wasm_size = module->end() - module->begin(); |
199 | 250 |
200 wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses(); | |
201 Handle<FixedArray> uses_array = | |
202 info->isolate()->factory()->NewFixedArray(static_cast<int>(uses.size())); | |
203 int count = 0; | |
204 for (auto i : uses) { | |
205 uses_array->set(count++, Smi::FromInt(i)); | |
206 } | |
207 | |
208 Handle<FixedArray> result = | 251 Handle<FixedArray> result = |
209 info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); | 252 info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); |
210 result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked()); | 253 result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked()); |
211 result->set(kWasmDataForeignGlobals, *foreign_globals); | 254 result->set(kWasmDataForeignGlobals, *foreign_globals); |
212 result->set(kWasmDataUsesArray, *uses_array); | 255 result->set(kWasmDataUsesArray, *uses_array); |
213 result->set(kWasmDataScript, *info->script()); | 256 result->set(kWasmDataScript, *info->script()); |
214 result->set(kWasmDataScriptPosition, | 257 result->set(kWasmDataScriptPosition, |
215 Smi::FromInt(info->literal()->position())); | 258 Smi::FromInt(info->literal()->position())); |
216 | 259 |
217 MessageLocation location(info->script(), info->literal()->position(), | 260 MessageLocation location(info->script(), info->literal()->position(), |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 foreign, NONE); | 319 foreign, NONE); |
277 } | 320 } |
278 | 321 |
279 i::MaybeHandle<i::Object> maybe_module_object = | 322 i::MaybeHandle<i::Object> maybe_module_object = |
280 i::wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory); | 323 i::wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory); |
281 if (maybe_module_object.is_null()) { | 324 if (maybe_module_object.is_null()) { |
282 return MaybeHandle<Object>(); | 325 return MaybeHandle<Object>(); |
283 } | 326 } |
284 i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); | 327 i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); |
285 | 328 |
286 i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String( | 329 if (!FLAG_fast_validate_asm) { |
287 wasm::AsmWasmBuilder::foreign_init_name)); | 330 i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String( |
288 i::Handle<i::Object> init = | 331 wasm::AsmWasmBuilder::foreign_init_name)); |
289 i::Object::GetProperty(module_object, init_name).ToHandleChecked(); | 332 i::Handle<i::Object> init = |
| 333 i::Object::GetProperty(module_object, init_name).ToHandleChecked(); |
290 | 334 |
291 i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate); | 335 i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate); |
292 i::Handle<i::Object>* foreign_args_array = | 336 i::Handle<i::Object>* foreign_args_array = |
293 new i::Handle<i::Object>[foreign_globals->length()]; | 337 new i::Handle<i::Object>[foreign_globals->length()]; |
294 for (int j = 0; j < foreign_globals->length(); j++) { | 338 for (int j = 0; j < foreign_globals->length(); j++) { |
295 if (!foreign.is_null()) { | 339 if (!foreign.is_null()) { |
296 i::MaybeHandle<i::Name> name = i::Object::ToName( | 340 i::MaybeHandle<i::Name> name = i::Object::ToName( |
297 isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate)); | 341 isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate)); |
298 if (!name.is_null()) { | 342 if (!name.is_null()) { |
299 i::MaybeHandle<i::Object> val = | 343 i::MaybeHandle<i::Object> val = |
300 i::Object::GetProperty(foreign, name.ToHandleChecked()); | 344 i::Object::GetProperty(foreign, name.ToHandleChecked()); |
301 if (!val.is_null()) { | 345 if (!val.is_null()) { |
302 foreign_args_array[j] = val.ToHandleChecked(); | 346 foreign_args_array[j] = val.ToHandleChecked(); |
303 continue; | 347 continue; |
| 348 } |
304 } | 349 } |
305 } | 350 } |
| 351 foreign_args_array[j] = undefined; |
306 } | 352 } |
307 foreign_args_array[j] = undefined; | 353 i::MaybeHandle<i::Object> retval = |
| 354 i::Execution::Call(isolate, init, undefined, foreign_globals->length(), |
| 355 foreign_args_array); |
| 356 delete[] foreign_args_array; |
| 357 DCHECK(!retval.is_null()); |
308 } | 358 } |
309 i::MaybeHandle<i::Object> retval = i::Execution::Call( | |
310 isolate, init, undefined, foreign_globals->length(), foreign_args_array); | |
311 delete[] foreign_args_array; | |
312 DCHECK(!retval.is_null()); | |
313 | 359 |
314 i::Handle<i::Name> single_function_name( | 360 i::Handle<i::Name> single_function_name( |
315 isolate->factory()->InternalizeUtf8String( | 361 isolate->factory()->InternalizeUtf8String( |
316 wasm::AsmWasmBuilder::single_function_name)); | 362 wasm::AsmWasmBuilder::single_function_name)); |
317 i::MaybeHandle<i::Object> single_function = | 363 i::MaybeHandle<i::Object> single_function = |
318 i::Object::GetProperty(module_object, single_function_name); | 364 i::Object::GetProperty(module_object, single_function_name); |
319 if (!single_function.is_null() && | 365 if (!single_function.is_null() && |
320 !single_function.ToHandleChecked()->IsUndefined(isolate)) { | 366 !single_function.ToHandleChecked()->IsUndefined(isolate)) { |
321 return single_function; | 367 return single_function; |
322 } | 368 } |
(...skipping 23 matching lines...) Expand all Loading... |
346 MessageHandler::ReportMessage(isolate, &location, message); | 392 MessageHandler::ReportMessage(isolate, &location, message); |
347 } | 393 } |
348 | 394 |
349 Handle<String> exports_name = | 395 Handle<String> exports_name = |
350 isolate->factory()->InternalizeUtf8String("exports"); | 396 isolate->factory()->InternalizeUtf8String("exports"); |
351 return i::Object::GetProperty(module_object, exports_name); | 397 return i::Object::GetProperty(module_object, exports_name); |
352 } | 398 } |
353 | 399 |
354 } // namespace internal | 400 } // namespace internal |
355 } // namespace v8 | 401 } // namespace v8 |
OLD | NEW |