diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-11 07:38:05 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-11 07:38:05 +0000 |
commit | 04a3686acaa3ae6a6042beaa41745c4f6a77e276 (patch) | |
tree | 1df435310690642f8fd4628d6d16462d05ffc797 /src/runtime/runtime-wasm.cc | |
parent | 4928608426ecd40caa100225c58f94f7a0c17ed6 (diff) | |
parent | a938e3cdb29f70199b4dbf3a5438979f57eda327 (diff) | |
download | v8-04a3686acaa3ae6a6042beaa41745c4f6a77e276.tar.gz |
release-request-46bf7ca6-57e7-44b8-8edc-ea8830c1cb3b-for-git_oc-mr1-release-4090244 snap-temp-L07700000073092334android-wear-8.1.0_r1android-vts-8.1_r9android-vts-8.1_r8android-vts-8.1_r7android-vts-8.1_r6android-vts-8.1_r5android-vts-8.1_r4android-vts-8.1_r3android-vts-8.1_r14android-vts-8.1_r13android-vts-8.1_r12android-vts-8.1_r11android-vts-8.1_r10android-cts-8.1_r9android-cts-8.1_r8android-cts-8.1_r7android-cts-8.1_r6android-cts-8.1_r5android-cts-8.1_r4android-cts-8.1_r3android-cts-8.1_r25android-cts-8.1_r24android-cts-8.1_r23android-cts-8.1_r22android-cts-8.1_r21android-cts-8.1_r20android-cts-8.1_r2android-cts-8.1_r19android-cts-8.1_r18android-cts-8.1_r17android-cts-8.1_r16android-cts-8.1_r15android-cts-8.1_r14android-cts-8.1_r13android-cts-8.1_r12android-cts-8.1_r11android-cts-8.1_r10android-cts-8.1_r1android-8.1.0_r9android-8.1.0_r8android-8.1.0_r7android-8.1.0_r6android-8.1.0_r5android-8.1.0_r46android-8.1.0_r45android-8.1.0_r43android-8.1.0_r42android-8.1.0_r41android-8.1.0_r40android-8.1.0_r4android-8.1.0_r39android-8.1.0_r38android-8.1.0_r37android-8.1.0_r36android-8.1.0_r35android-8.1.0_r33android-8.1.0_r32android-8.1.0_r31android-8.1.0_r30android-8.1.0_r3android-8.1.0_r29android-8.1.0_r28android-8.1.0_r27android-8.1.0_r26android-8.1.0_r25android-8.1.0_r23android-8.1.0_r22android-8.1.0_r21android-8.1.0_r20android-8.1.0_r2android-8.1.0_r19android-8.1.0_r18android-8.1.0_r17android-8.1.0_r16android-8.1.0_r15android-8.1.0_r14android-8.1.0_r13android-8.1.0_r12android-8.1.0_r11android-8.1.0_r10android-8.1.0_r1oreo-mr1-wear-releaseoreo-mr1-vts-releaseoreo-mr1-s1-releaseoreo-mr1-releaseoreo-mr1-cuttlefish-testingoreo-mr1-cts-releaseoreo-m6-s4-releaseoreo-m6-s3-releaseoreo-m6-s2-releaseoreo-m5-releaseoreo-m4-s9-releaseoreo-m4-s8-releaseoreo-m4-s7-releaseoreo-m4-s6-releaseoreo-m4-s5-releaseoreo-m4-s4-releaseoreo-m4-s3-releaseoreo-m4-s2-releaseoreo-m4-s12-releaseoreo-m4-s11-releaseoreo-m4-s10-releaseoreo-m4-s1-releaseoreo-m3-releaseoreo-m2-s5-releaseoreo-m2-s4-releaseoreo-m2-s3-releaseoreo-m2-s2-releaseoreo-m2-s1-releaseoreo-m2-release
Change-Id: I584166e536b063d6b3f05eea3157dd0cc656bf51
Diffstat (limited to 'src/runtime/runtime-wasm.cc')
-rw-r--r-- | src/runtime/runtime-wasm.cc | 175 |
1 files changed, 147 insertions, 28 deletions
diff --git a/src/runtime/runtime-wasm.cc b/src/runtime/runtime-wasm.cc index ab69046c..9f125c13 100644 --- a/src/runtime/runtime-wasm.cc +++ b/src/runtime/runtime-wasm.cc @@ -14,50 +14,125 @@ #include "src/objects-inl.h" #include "src/v8memory.h" #include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-objects.h" +#include "src/wasm/wasm-opcodes.h" namespace v8 { namespace internal { +namespace { +WasmInstanceObject* GetWasmInstanceOnStackTop(Isolate* isolate) { + DisallowHeapAllocation no_allocation; + const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); + Address pc = + Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); + Code* code = isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; + DCHECK_EQ(Code::WASM_FUNCTION, code->kind()); + WasmInstanceObject* owning_instance = wasm::GetOwningWasmInstance(code); + CHECK_NOT_NULL(owning_instance); + return owning_instance; +} +Context* GetWasmContextOnStackTop(Isolate* isolate) { + return GetWasmInstanceOnStackTop(isolate) + ->compiled_module() + ->ptr_to_native_context(); +} +} // namespace + RUNTIME_FUNCTION(Runtime_WasmMemorySize) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); - Handle<JSObject> module_instance; - { - // Get the module JSObject - DisallowHeapAllocation no_allocation; - const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); - Address pc = - Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); - Code* code = - isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; - Object* owning_instance = wasm::GetOwningWasmInstance(code); - CHECK_NOT_NULL(owning_instance); - module_instance = handle(JSObject::cast(owning_instance), isolate); - } + Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), + isolate); return *isolate->factory()->NewNumberFromInt( - wasm::GetInstanceMemorySize(isolate, module_instance)); + wasm::GetInstanceMemorySize(isolate, instance)); } RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_UINT32_ARG_CHECKED(delta_pages, 0); - Handle<JSObject> module_instance; - { - // Get the module JSObject - DisallowHeapAllocation no_allocation; - const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); - Address pc = - Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); - Code* code = - isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; - Object* owning_instance = wasm::GetOwningWasmInstance(code); - CHECK_NOT_NULL(owning_instance); - module_instance = handle(JSObject::cast(owning_instance), isolate); - } + Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), + isolate); + + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(instance->compiled_module()->ptr_to_native_context()); + return *isolate->factory()->NewNumberFromInt( - wasm::GrowInstanceMemory(isolate, module_instance, delta_pages)); + wasm::GrowMemory(isolate, instance, delta_pages)); +} + +Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset, + bool patch_source_position) { + HandleScope scope(isolate); + DCHECK_NULL(isolate->context()); + isolate->set_context(GetWasmContextOnStackTop(isolate)); + Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError( + static_cast<MessageTemplate::Template>(message_id)); + + if (!patch_source_position) { + return isolate->Throw(*error_obj); + } + + // For wasm traps, the byte offset (a.k.a source position) can not be + // determined from relocation info, since the explicit checks for traps + // converge in one singe block which calls this runtime function. + // We hence pass the byte offset explicitely, and patch it into the top-most + // frame (a wasm frame) on the collected stack trace. + // TODO(wasm): This implementation is temporary, see bug #5007: + // https://bugs.chromium.org/p/v8/issues/detail?id=5007 + Handle<JSObject> error = Handle<JSObject>::cast(error_obj); + Handle<Object> stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->stack_trace_symbol()); + // Patch the stack trace (array of <receiver, function, code, position>). + if (stack_trace_obj->IsJSArray()) { + Handle<FrameArray> stack_elements( + FrameArray::cast(JSArray::cast(*stack_trace_obj)->elements())); + DCHECK(stack_elements->Code(0)->kind() == AbstractCode::WASM_FUNCTION); + DCHECK(stack_elements->Offset(0)->value() >= 0); + stack_elements->SetOffset(0, Smi::FromInt(-1 - byte_offset)); + } + + // Patch the detailed stack trace (array of JSObjects with various + // properties). + Handle<Object> detailed_stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->detailed_stack_trace_symbol()); + if (detailed_stack_trace_obj->IsJSArray()) { + Handle<FixedArray> stack_elements( + FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements())); + DCHECK_GE(stack_elements->length(), 1); + Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0))); + Handle<String> wasm_offset_key = + isolate->factory()->InternalizeOneByteString( + STATIC_CHAR_VECTOR("column")); + LookupIterator it(top_frame, wasm_offset_key, top_frame, + LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); + if (it.IsFound()) { + DCHECK(JSReceiver::GetDataProperty(&it)->IsSmi()); + // Make column number 1-based here. + Maybe<bool> data_set = JSReceiver::SetDataProperty( + &it, handle(Smi::FromInt(byte_offset + 1), isolate)); + DCHECK(data_set.IsJust() && data_set.FromJust() == true); + USE(data_set); + } + } + + return isolate->Throw(*error_obj); +} + +RUNTIME_FUNCTION(Runtime_ThrowWasmErrorFromTrapIf) { + DCHECK_EQ(1, args.length()); + CONVERT_SMI_ARG_CHECKED(message_id, 0); + return ThrowRuntimeError(isolate, message_id, 0, false); +} + +RUNTIME_FUNCTION(Runtime_ThrowWasmError) { + DCHECK_EQ(2, args.length()); + CONVERT_SMI_ARG_CHECKED(message_id, 0); + CONVERT_SMI_ARG_CHECKED(byte_offset, 1); + return ThrowRuntimeError(isolate, message_id, byte_offset, true); } RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) { @@ -75,6 +150,10 @@ RUNTIME_FUNCTION(Runtime_WasmThrow) { const int32_t thrown_value = (upper << 16) | lower; + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(GetWasmContextOnStackTop(isolate)); + return isolate->Throw(*isolate->factory()->NewNumberFromInt(thrown_value)); } @@ -89,5 +168,45 @@ RUNTIME_FUNCTION(Runtime_WasmGetCaughtExceptionValue) { return exception; } +RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { + DCHECK_EQ(3, args.length()); + HandleScope scope(isolate); + CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); + CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[1]); + CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 2); + CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); + Handle<WasmInstanceObject> instance = + Handle<WasmInstanceObject>::cast(instance_obj); + + // The arg buffer is the raw pointer to the caller's stack. It looks like a + // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just + // cast it back to the raw pointer. + CHECK(!arg_buffer_obj->IsHeapObject()); + CHECK(arg_buffer_obj->IsSmi()); + uint8_t* arg_buffer = reinterpret_cast<uint8_t*>(*arg_buffer_obj); + + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(instance->compiled_module()->ptr_to_native_context()); + + instance->debug_info()->RunInterpreter(func_index, arg_buffer); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_WasmStackGuard) { + SealHandleScope shs(isolate); + DCHECK_EQ(0, args.length()); + + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(GetWasmContextOnStackTop(isolate)); + + // Check if this is a real stack overflow. + StackLimitCheck check(isolate); + if (check.JsHasOverflowed()) return isolate->StackOverflow(); + + return isolate->stack_guard()->HandleInterrupts(); +} + } // namespace internal } // namespace v8 |