// 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 CallbackHolderBase::GetHandle(v8::Isolate* isolate) { return v8::Local::New(isolate, v8_ref_); } // static void CallbackHolderBase::FirstWeakCallback( const v8::WeakCallbackInfo& data) { data.GetParameter()->v8_ref_.Reset(); data.SetSecondPassCallback(SecondWeakCallback); } // static void CallbackHolderBase::SecondWeakCallback( const v8::WeakCallbackInfo& 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