blob: 7172bbec869376922deb8a42f781398ac483f364 [file] [log] [blame]
// Copyright (c) 2016, 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_SIMULATOR_DBC_H_
#define VM_SIMULATOR_DBC_H_
#ifndef VM_SIMULATOR_H_
#error Do not include simulator_dbc.h directly; use simulator.h.
#endif
#include "vm/constants_dbc.h"
#include "vm/method_recognizer.h"
namespace dart {
class Isolate;
class RawObject;
class SimulatorSetjmpBuffer;
class Thread;
class Code;
class Array;
class RawICData;
class RawArray;
class RawObjectPool;
class RawFunction;
// Simulator intrinsic handler. It is invoked on entry to the intrinsified
// function via Intrinsic bytecode before the frame is setup.
// If the handler returns true then Intrinsic bytecode works as a return
// instruction returning the value in result. Otherwise interpreter proceeds to
// execute the body of the function.
typedef bool (*IntrinsicHandler)(Thread* thread,
RawObject** FP,
RawObject** result);
class Simulator {
public:
static const uword kSimulatorStackUnderflowSize = 0x80;
Simulator();
~Simulator();
// The currently executing Simulator instance, which is associated to the
// current isolate
static Simulator* Current();
// Accessors to the internal simulator stack base and top.
uword StackBase() const { return reinterpret_cast<uword>(stack_); }
uword StackTop() const;
// The isolate's top_exit_frame_info refers to a Dart frame in the simulator
// stack. The simulator's top_exit_frame_info refers to a C++ frame in the
// native stack.
uword top_exit_frame_info() const { return top_exit_frame_info_; }
void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; }
// Call on program start.
static void InitOnce();
RawObject* Call(const Code& code,
const Array& arguments_descriptor,
const Array& arguments,
Thread* thread);
void Longjmp(uword pc,
uword sp,
uword fp,
RawObject* raw_exception,
RawObject* raw_stacktrace,
Thread* thread);
uword get_sp() const {
return reinterpret_cast<uword>(sp_);
}
enum IntrinsicId {
#define V(test_class_name, test_function_name, enum_name, type, fp) \
k##enum_name##Intrinsic,
ALL_INTRINSICS_LIST(V)
GRAPH_INTRINSICS_LIST(V)
#undef V
kIntrinsicCount,
};
static bool IsSupportedIntrinsic(IntrinsicId id) {
return intrinsics_[id] != NULL;
}
enum SpecialIndex {
kExceptionSpecialIndex,
kStacktraceSpecialIndex,
kSpecialIndexCount
};
private:
uintptr_t* stack_;
RawObject** fp_;
RawObject** sp_;
uword pc_;
SimulatorSetjmpBuffer* last_setjmp_buffer_;
uword top_exit_frame_info_;
RawObject* special_[kSpecialIndexCount];
static IntrinsicHandler intrinsics_[kIntrinsicCount];
void Exit(Thread* thread,
RawObject** base,
RawObject** exit_frame,
uint32_t* pc);
void CallRuntime(Thread* thread,
RawObject** base,
RawObject** exit_frame,
uint32_t* pc,
intptr_t argc_tag,
RawObject** args,
RawObject** result,
uword target);
void Invoke(Thread* thread,
RawObject** call_base,
RawObject** call_top,
RawObjectPool** pp,
uint32_t** pc,
RawObject*** B,
RawObject*** SP);
void InlineCacheMiss(int checked_args,
Thread* thread,
RawICData* icdata,
RawObject** call_base,
RawObject** top,
uint32_t* pc,
RawObject** B, RawObject** SP);
void InstanceCall1(Thread* thread,
RawICData* icdata,
RawObject** call_base,
RawObject** call_top,
RawArray** argdesc,
RawObjectPool** pp,
uint32_t** pc,
RawObject*** B, RawObject*** SP);
void InstanceCall2(Thread* thread,
RawICData* icdata,
RawObject** call_base,
RawObject** call_top,
RawArray** argdesc,
RawObjectPool** pp,
uint32_t** pc,
RawObject*** B, RawObject*** SP);
// Longjmp support for exceptions.
SimulatorSetjmpBuffer* last_setjmp_buffer() {
return last_setjmp_buffer_;
}
void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) {
last_setjmp_buffer_ = buffer;
}
friend class SimulatorSetjmpBuffer;
DISALLOW_COPY_AND_ASSIGN(Simulator);
};
} // namespace dart
#endif // VM_SIMULATOR_DBC_H_