b4d9e0d620
native functions do not have to call Dart_EnterScope/Dart_ExitScope when they callback into the VM. Remove Dart_EnterScope/Dart_ExitScope calls around native functions in 'bin' directory. R=regis@google.com, srdjan@google.com Review URL: https://codereview.chromium.org//22303002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25827 260f80e4-7a28-3924-810f-c04153c831b5
105 lines
5.0 KiB
C++
105 lines
5.0 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef VM_NATIVE_ENTRY_H_
|
|
#define VM_NATIVE_ENTRY_H_
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/assembler.h"
|
|
#include "vm/code_generator.h"
|
|
#include "vm/exceptions.h"
|
|
#include "vm/native_arguments.h"
|
|
#include "vm/verifier.h"
|
|
|
|
#include "include/dart_api.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class Class;
|
|
class String;
|
|
|
|
typedef void (*NativeFunction)(NativeArguments* arguments);
|
|
|
|
|
|
#define NATIVE_ENTRY_FUNCTION(name) BootstrapNatives::DN_##name
|
|
|
|
#ifdef DEBUG
|
|
#define SET_NATIVE_RETVAL(args, value) \
|
|
RawObject* retval = value; \
|
|
ASSERT(retval->IsDartInstance()); \
|
|
arguments->SetReturnUnsafe(retval);
|
|
#else
|
|
#define SET_NATIVE_RETVAL(arguments, value) \
|
|
arguments->SetReturnUnsafe(value);
|
|
#endif
|
|
|
|
#define DEFINE_NATIVE_ENTRY(name, argument_count) \
|
|
static RawObject* DN_Helper##name(Isolate* isolate, \
|
|
NativeArguments* arguments); \
|
|
void NATIVE_ENTRY_FUNCTION(name)(Dart_NativeArguments args) { \
|
|
CHECK_STACK_ALIGNMENT; \
|
|
VERIFY_ON_TRANSITION; \
|
|
NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); \
|
|
ASSERT(arguments->NativeArgCount() == argument_count); \
|
|
TRACE_NATIVES(""#name); \
|
|
{ \
|
|
StackZone zone(arguments->isolate()); \
|
|
SET_NATIVE_RETVAL(arguments, \
|
|
DN_Helper##name(arguments->isolate(), arguments)); \
|
|
DEOPTIMIZE_ALOT; \
|
|
} \
|
|
VERIFY_ON_TRANSITION; \
|
|
} \
|
|
static RawObject* DN_Helper##name(Isolate* isolate, \
|
|
NativeArguments* arguments)
|
|
|
|
|
|
// Natives should throw an exception if an illegal argument or null is passed.
|
|
// type name = value.
|
|
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value) \
|
|
const Instance& __##name##_instance__ = \
|
|
Instance::CheckedHandle(isolate, value); \
|
|
if (!__##name##_instance__.Is##type()) { \
|
|
const Array& __args__ = Array::Handle(Array::New(1)); \
|
|
__args__.SetAt(0, __##name##_instance__); \
|
|
Exceptions::ThrowByType(Exceptions::kArgument, __args__); \
|
|
} \
|
|
const type& name = type::Cast(__##name##_instance__);
|
|
|
|
|
|
// Natives should throw an exception if an illegal argument is passed.
|
|
// type name = value.
|
|
#define GET_NATIVE_ARGUMENT(type, name, value) \
|
|
const Instance& __##name##_instance__ = \
|
|
Instance::CheckedHandle(isolate, value); \
|
|
type& name = type::Handle(isolate); \
|
|
if (!__##name##_instance__.IsNull()) { \
|
|
if (!__##name##_instance__.Is##type()) { \
|
|
const Array& __args__ = Array::Handle(Array::New(1)); \
|
|
__args__.SetAt(0, __##name##_instance__); \
|
|
Exceptions::ThrowByType(Exceptions::kArgument, __args__); \
|
|
} \
|
|
} \
|
|
name ^= value;
|
|
|
|
|
|
// Helper class for resolving and handling native functions.
|
|
class NativeEntry : public AllStatic {
|
|
public:
|
|
static const intptr_t kNumCallWrapperArguments = 2;
|
|
|
|
// Resolve specified dart native function to the actual native entrypoint.
|
|
static NativeFunction ResolveNative(const Library& library,
|
|
const String& function_name,
|
|
int number_of_arguments);
|
|
static void NativeCallWrapper(Dart_NativeArguments args,
|
|
Dart_NativeFunction func);
|
|
static const ExternalLabel& NativeCallWrapperLabel();
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // VM_NATIVE_ENTRY_H_
|