LCOV - code coverage report
Current view: top level - src/wasm - wasm-result.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 72 81 88.9 %
Date: 2017-10-20 Functions: 12 14 85.7 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/wasm/wasm-result.h"
       6             : 
       7             : #include "src/factory.h"
       8             : #include "src/heap/heap.h"
       9             : #include "src/isolate-inl.h"
      10             : #include "src/objects.h"
      11             : 
      12             : #include "src/base/platform/platform.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : namespace wasm {
      17             : 
      18             : namespace {
      19             : 
      20             : PRINTF_FORMAT(3, 0)
      21       49254 : void VPrintFToString(std::string& str, size_t str_offset, const char* format,
      22             :                      va_list args) {
      23             :   DCHECK_LE(str_offset, str.size());
      24       49254 :   size_t len = str_offset + strlen(format);
      25             :   // Allocate increasingly large buffers until the message fits.
      26      111619 :   for (;; len = base::bits::RoundUpToPowerOfTwo64(len + 1)) {
      27             :     DCHECK_GE(kMaxInt, len);
      28             :     str.resize(len);
      29             :     va_list args_copy;
      30      160873 :     va_copy(args_copy, args);
      31             :     int written = VSNPrintF(Vector<char>(&str.front() + str_offset,
      32             :                                          static_cast<int>(len - str_offset)),
      33      482619 :                             format, args_copy);
      34      160873 :     va_end(args_copy);
      35      272492 :     if (written < 0) continue;  // not enough space.
      36       49254 :     str.resize(str_offset + written);
      37       49254 :     return;
      38      111619 :   }
      39             : }
      40             : 
      41             : PRINTF_FORMAT(3, 4)
      42       24627 : void PrintFToString(std::string& str, size_t str_offset, const char* format,
      43             :                     ...) {
      44             :   va_list args;
      45       24627 :   va_start(args, format);
      46       24627 :   VPrintFToString(str, str_offset, format, args);
      47       24627 :   va_end(args);
      48       24627 : }
      49             : 
      50             : }  // namespace
      51             : 
      52       41339 : void ResultBase::error(uint32_t offset, std::string error_msg) {
      53             :   // The error message must not be empty, otherwise Result::failed() will be
      54             :   // false.
      55             :   DCHECK(!error_msg.empty());
      56       41339 :   error_offset_ = offset;
      57       41339 :   error_msg_ = std::move(error_msg);
      58       41339 : }
      59             : 
      60           0 : void ResultBase::verror(const char* format, va_list args) {
      61           0 :   VPrintFToString(error_msg_, 0, format, args);
      62             :   // Assign default message such that ok() and failed() work.
      63           0 :   if (error_msg_.empty() == 0) error_msg_.assign("Error");
      64           0 : }
      65             : 
      66       30704 : void ErrorThrower::Format(ErrorType type, const char* format, va_list args) {
      67             :   DCHECK_NE(kNone, type);
      68             :   // Only report the first error.
      69       61408 :   if (error()) return;
      70             : 
      71             :   size_t context_len = 0;
      72       24627 :   if (context_) {
      73       24627 :     PrintFToString(error_msg_, 0, "%s: ", context_);
      74             :     context_len = error_msg_.size();
      75             :   }
      76       24627 :   VPrintFToString(error_msg_, context_len, format, args);
      77       24627 :   error_type_ = type;
      78             : }
      79             : 
      80        9085 : void ErrorThrower::TypeError(const char* format, ...) {
      81             :   va_list arguments;
      82        9085 :   va_start(arguments, format);
      83        9085 :   Format(kTypeError, format, arguments);
      84        9085 :   va_end(arguments);
      85        9085 : }
      86             : 
      87        1290 : void ErrorThrower::RangeError(const char* format, ...) {
      88             :   va_list arguments;
      89        1290 :   va_start(arguments, format);
      90        1290 :   Format(kRangeError, format, arguments);
      91        1290 :   va_end(arguments);
      92        1290 : }
      93             : 
      94       18866 : void ErrorThrower::CompileError(const char* format, ...) {
      95             :   va_list arguments;
      96       18866 :   va_start(arguments, format);
      97       18866 :   Format(kCompileError, format, arguments);
      98       18866 :   va_end(arguments);
      99       18866 : }
     100             : 
     101        1403 : void ErrorThrower::LinkError(const char* format, ...) {
     102             :   va_list arguments;
     103        1403 :   va_start(arguments, format);
     104        1403 :   Format(kLinkError, format, arguments);
     105        1403 :   va_end(arguments);
     106        1403 : }
     107             : 
     108          60 : void ErrorThrower::RuntimeError(const char* format, ...) {
     109             :   va_list arguments;
     110          60 :   va_start(arguments, format);
     111          60 :   Format(kRuntimeError, format, arguments);
     112          60 :   va_end(arguments);
     113          60 : }
     114             : 
     115       24534 : Handle<Object> ErrorThrower::Reify() {
     116             :   Handle<JSFunction> constructor;
     117       24534 :   switch (error_type_) {
     118             :     case kNone:
     119           0 :       UNREACHABLE();
     120             :     case kTypeError:
     121        9067 :       constructor = isolate_->type_error_function();
     122        9067 :       break;
     123             :     case kRangeError:
     124        1290 :       constructor = isolate_->range_error_function();
     125        1290 :       break;
     126             :     case kCompileError:
     127       12945 :       constructor = isolate_->wasm_compile_error_function();
     128       12945 :       break;
     129             :     case kLinkError:
     130        1172 :       constructor = isolate_->wasm_link_error_function();
     131        1172 :       break;
     132             :     case kRuntimeError:
     133          60 :       constructor = isolate_->wasm_runtime_error_function();
     134          60 :       break;
     135             :   }
     136             :   Vector<const char> msg_vec(error_msg_.data(), error_msg_.size());
     137             :   Handle<String> message =
     138       49068 :       isolate_->factory()->NewStringFromUtf8(msg_vec).ToHandleChecked();
     139             :   Reset();
     140       24534 :   return isolate_->factory()->NewError(constructor, message);
     141             : }
     142             : 
     143        1609 : void ErrorThrower::Reset() {
     144       26143 :   error_type_ = kNone;
     145       26143 :   error_msg_.clear();
     146        1609 : }
     147             : 
     148           0 : ErrorThrower::ErrorThrower(ErrorThrower&& other)
     149             :     : isolate_(other.isolate_),
     150             :       context_(other.context_),
     151             :       error_type_(other.error_type_),
     152           0 :       error_msg_(other.error_msg_) {
     153           0 :   other.error_type_ = kNone;
     154           0 : }
     155             : 
     156    26955645 : ErrorThrower::~ErrorThrower() {
     157    26955645 :   if (error() && !isolate_->has_pending_exception()) {
     158             :     // We don't want to mix pending exceptions and scheduled exceptions, hence
     159             :     // an existing exception should be pending, never scheduled.
     160             :     DCHECK(!isolate_->has_scheduled_exception());
     161         172 :     isolate_->Throw(*Reify());
     162             :   }
     163    26955645 : }
     164             : 
     165             : }  // namespace wasm
     166             : }  // namespace internal
     167             : }  // namespace v8

Generated by: LCOV version 1.10