| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gin/function_template.h" |
| |
| #include "base/strings/strcat.h" |
| |
| namespace gin { |
| |
| namespace internal { |
| |
| CallbackHolderBase::CallbackHolderBase(v8::Isolate* isolate) |
| : v8_ref_(isolate, v8::External::New(isolate, this)) { |
| v8_ref_.SetWeak(this, &CallbackHolderBase::FirstWeakCallback, |
| v8::WeakCallbackType::kParameter); |
| } |
| |
| CallbackHolderBase::~CallbackHolderBase() { |
| DCHECK(v8_ref_.IsEmpty()); |
| } |
| |
| v8::Local<v8::External> CallbackHolderBase::GetHandle(v8::Isolate* isolate) { |
| return v8::Local<v8::External>::New(isolate, v8_ref_); |
| } |
| |
| // static |
| void CallbackHolderBase::FirstWeakCallback( |
| const v8::WeakCallbackInfo<CallbackHolderBase>& data) { |
| data.GetParameter()->v8_ref_.Reset(); |
| data.SetSecondPassCallback(SecondWeakCallback); |
| } |
| |
| // static |
| void CallbackHolderBase::SecondWeakCallback( |
| const v8::WeakCallbackInfo<CallbackHolderBase>& data) { |
| delete data.GetParameter(); |
| } |
| |
| void ThrowConversionError(Arguments* args, |
| const InvokerOptions& invoker_options, |
| size_t index) { |
| if (index == 0 && invoker_options.holder_is_first_argument) { |
| // Failed to get the appropriate `this` object. This can happen if a |
| // method is invoked using Function.prototype.[call|apply] and passed an |
| // invalid (or null) `this` argument. |
| std::string error = |
| invoker_options.holder_type |
| ? base::StrCat({"Illegal invocation: Function must be " |
| "called on an object of type ", |
| invoker_options.holder_type}) |
| : "Illegal invocation"; |
| args->ThrowTypeError(error); |
| } else { |
| // Otherwise, this failed parsing on a different argument. |
| // Arguments::ThrowError() will try to include appropriate information. |
| // Ideally we would include the expected c++ type in the error message |
| // here, too (which we can access via typeid(ArgType).name()), however we |
| // compile with no-rtti, which disables typeid. |
| args->ThrowError(); |
| } |
| } |
| |
| } // namespace internal |
| |
| } // namespace gin |