Commit 30fabc4c authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

Replace CALL_GENERATED_CODE by GeneratedCode wrapper

This ensures that there is only one entrance point from C++ to
generated code, hence only one method has to be excluded from CFI.
It also introduces type safety by only allowing the code to be called
with the right arguments.
This CL includes minor drive-by fixes in the tests, like removing
unused dummy variables.

R=mstarzinger@chromium.org

Bug: v8:7182
Change-Id: Ied9164a2497db9e7c032324c5e082094fdffc72d
Reviewed-on: https://chromium-review.googlesource.com/852213Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50426}
parent c176c054
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Declares a Simulator for ARM instructions if we are not generating a native
// ARM binary. This Simulator allows us to run and debug ARM code generation on
// regular desktop machines.
// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
// V8 calls into generated code by using the GeneratedCode class,
// which will start execution in the Simulator or forwards to the real entry
// on a ARM HW platform.
......@@ -496,21 +495,6 @@ class Simulator : public SimulatorBase {
static base::LazyInstance<GlobalMonitor>::type global_monitor_;
};
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \
Simulator::current(isolate)->CallFP<int>(FUNCTION_ADDR(entry), p0, p1)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
} // namespace internal
} // namespace v8
......
......@@ -485,9 +485,8 @@ void CEntryStub::Generate(MacroAssembler* masm) {
__ Br(x10);
}
// This is the entry point from C++. 5 arguments are provided in x0-x4.
// See use of the CALL_GENERATED_CODE macro for example in src/execution.cc.
// See use of the JSEntryFunction for example in src/execution.cc.
// Input:
// x0: code entry.
// x1: function.
......
......@@ -2355,17 +2355,6 @@ inline float Simulator::FPDefaultNaN<float>() {
return kFP32DefaultNaN;
}
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
#endif // defined(USE_SIMULATOR)
} // namespace internal
......
......@@ -114,9 +114,9 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(
// Placeholder for return value.
Object* value = nullptr;
typedef Object* (*JSEntryFunction)(Object* new_target, Object* target,
Object* receiver, int argc,
Object*** args);
using JSEntryFunction =
GeneratedCode<Object*(Object * new_target, Object * target,
Object * receiver, int argc, Object*** args)>;
Handle<Code> code;
switch (execution_target) {
......@@ -136,7 +136,8 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(
// allocation of handles without explicit handle scopes.
SaveContext save(isolate);
SealHandleScope shs(isolate);
JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
JSEntryFunction stub_entry =
JSEntryFunction::FromAddress(isolate, code->entry());
if (FLAG_clear_exceptions_on_js_entry) isolate->clear_pending_exception();
......@@ -149,8 +150,7 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(
PrintDeserializedCodeInfo(Handle<JSFunction>::cast(target));
}
RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kJS_Execution);
value = CALL_GENERATED_CODE(isolate, stub_entry, orig_func, func, recv,
argc, argv);
value = stub_entry.Call(orig_func, func, recv, argc, argv);
}
#ifdef VERIFY_HEAP
......
......@@ -8,6 +8,7 @@
#include "src/allocation.h"
#include "src/base/atomicops.h"
#include "src/globals.h"
#include "src/objects/code.h"
#include "src/utils.h"
namespace v8 {
......
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Declares a Simulator for MIPS instructions if we are not generating a native
// MIPS binary. This Simulator allows us to run and debug MIPS code generation
// on regular desktop machines.
// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
// V8 calls into generated code via the GeneratedCode wrapper,
// which will start execution in the Simulator or forwards to the real entry
// on a MIPS HW platform.
......@@ -561,17 +560,6 @@ class Simulator : public SimulatorBase {
StopCountAndDesc watched_stops_[kMaxStopCode + 1];
};
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
} // namespace internal
} // namespace v8
......
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Declares a Simulator for MIPS instructions if we are not generating a native
// MIPS binary. This Simulator allows us to run and debug MIPS code generation
// on regular desktop machines.
// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
// V8 calls into generated code via the GeneratedCode wrapper,
// which will start execution in the Simulator or forwards to the real entry
// on a MIPS HW platform.
......@@ -582,18 +581,6 @@ class Simulator : public SimulatorBase {
StopCountAndDesc watched_stops_[kMaxStopCode + 1];
};
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
} // namespace internal
} // namespace v8
......
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Declares a Simulator for PPC instructions if we are not generating a native
// PPC binary. This Simulator allows us to run and debug PPC code generation on
// regular desktop machines.
// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
// V8 calls into generated code via the GeneratedCode wrapper,
// which will start execution in the Simulator or forwards to the real entry
// on a PPC HW platform.
......@@ -434,18 +433,6 @@ class Simulator : public SimulatorBase {
static base::LazyInstance<GlobalMonitor>::type global_monitor_;
};
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
} // namespace internal
} // namespace v8
......
......@@ -86,8 +86,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in arm/simulator-arm.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -96,8 +96,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in arm64/simulator-arm64.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -85,8 +85,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in mips/simulator-mips.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -120,8 +120,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in mips/simulator-mips.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*
* clang-format on
*/
......
......@@ -86,8 +86,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in ppc/simulator-ppc.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -286,9 +286,15 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
Address stack_base = stack_scope.stack()->stack_base();
int direct_call = 0;
int result = CALL_GENERATED_REGEXP_CODE(
isolate, code->entry(), input, start_offset, input_start, input_end,
output, output_size, stack_base, direct_call, isolate);
using RegexpMatcherSig = int(
String * input, int start_offset, // NOLINT(readability/casting)
const byte* input_start, const byte* input_end, int* output,
int output_size, Address stack_base, int direct_call, Isolate* isolate);
auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(code);
int result = fn.Call(input, start_offset, input_start, input_end, output,
output_size, stack_base, direct_call, isolate);
DCHECK(result >= RETRY);
if (result == EXCEPTION && !isolate->has_pending_exception()) {
......
......@@ -88,8 +88,7 @@ namespace internal {
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in s390/simulator-s390.h.
* (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -5,7 +5,7 @@
// Declares a Simulator for S390 instructions if we are not generating a native
// S390 binary. This Simulator allows us to run and debug S390 code generation
// on regular desktop machines.
// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
// V8 calls into generated code via the GeneratedCode wrapper,
// which will start execution in the Simulator or forwards to the real entry
// on a S390 hardware platform.
......@@ -1201,17 +1201,6 @@ class Simulator : public SimulatorBase {
#undef EVALUATE
};
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
Simulator::current(isolate)->Call<Object*>(FUNCTION_ADDR(entry), p0, p1, p2, \
p3, p4)
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call<int>(entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8)
} // namespace internal
} // namespace v8
......
......@@ -6,6 +6,7 @@
#define V8_SIMULATOR_H_
#include "src/globals.h"
#include "src/objects/code.h"
#if V8_TARGET_ARCH_IA32
#include "src/ia32/simulator-ia32.h"
......@@ -79,20 +80,55 @@ class SimulatorStack : public v8::internal::AllStatic {
}
};
// When running without a simulator we call the entry directly.
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
(entry(p0, p1, p2, p3, p4))
#endif // defined(USE_SIMULATOR)
typedef int (*regexp_matcher)(String*, int, const byte*, const byte*, int*, int,
Address, int, Isolate*);
// Use this class either as {GeneratedCode<ret, arg1, arg2>} or
// {GeneratedCode<ret(arg1, arg2)>} (see specialization below).
template <typename Return, typename... Args>
class GeneratedCode {
public:
using Signature = Return(Args...);
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type {regexp_matcher} above.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, p8))
template <typename T>
static GeneratedCode FromAddress(Isolate* isolate, T* addr) {
return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr));
}
#endif // defined(USE_SIMULATOR)
static GeneratedCode FromCode(Code* code) {
return FromAddress(code->GetIsolate(), code->entry());
}
#ifdef USE_SIMULATOR
// Defined in simulator-base.h.
Return Call(Args... args) {
return Simulator::current(isolate_)->template Call<Return>(
reinterpret_cast<byte*>(fn_ptr_), args...);
}
#else
Return Call(Args... args) {
// When running without a simulator we call the entry directly.
return fn_ptr_(args...);
}
#endif
private:
friend class GeneratedCode<Return(Args...)>;
Isolate* isolate_;
Signature* fn_ptr_;
GeneratedCode(Isolate* isolate, Signature* fn_ptr)
: isolate_(isolate), fn_ptr_(fn_ptr) {}
};
// Allow to use {GeneratedCode<ret(arg1, arg2)>} instead of
// {GeneratedCode<ret, arg1, arg2>}.
template <typename Return, typename... Args>
class GeneratedCode<Return(Args...)> : public GeneratedCode<Return, Args...> {
public:
// Automatically convert from {GeneratedCode<ret, arg1, arg2>} to
// {GeneratedCode<ret(arg1, arg2)>}.
GeneratedCode(GeneratedCode<Return, Args...> other)
: GeneratedCode<Return, Args...>(other.isolate_, other.fn_ptr_) {}
};
} // namespace internal
} // namespace v8
......
......@@ -4,15 +4,15 @@
#include "test/cctest/assembler-helper-arm.h"
#include "src/assembler-inl.h"
#include "src/isolate-inl.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
#include "src/isolate-inl.h"
namespace v8 {
namespace internal {
Address AssembleCode(std::function<void(Assembler&)> assemble) {
Handle<Code> AssembleCodeImpl(std::function<void(Assembler&)> assemble) {
Isolate* isolate = CcTest::i_isolate();
Assembler assm(isolate, nullptr, 0);
......@@ -26,7 +26,7 @@ Address AssembleCode(std::function<void(Assembler&)> assemble) {
if (FLAG_print_code) {
code->Print();
}
return code->entry();
return code;
}
} // namespace internal
......
......@@ -7,20 +7,27 @@
#include <functional>
#include "src/macro-assembler.h"
#include "src/handles.h"
#include "src/simulator.h"
namespace v8 {
namespace internal {
// These function prototypes have 5 arguments since they are used with the
// CALL_GENERATED_CODE macro.
typedef Object* (*F_iiiii)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F_piiii)(void* p0, int p1, int p2, int p3, int p4);
typedef Object* (*F_ppiii)(void* p0, void* p1, int p2, int p3, int p4);
typedef Object* (*F_pppii)(void* p0, void* p1, void* p2, int p3, int p4);
typedef Object* (*F_ippii)(int p0, void* p1, void* p2, int p3, int p4);
Address AssembleCode(std::function<void(Assembler&)> assemble);
// TODO(arm): Refine these signatures per test case, they can have arbitrary
// return and argument types and arbitrary number of arguments.
using F_iiiii = Object*(int x, int p1, int p2, int p3, int p4);
using F_piiii = Object*(void* p0, int p1, int p2, int p3, int p4);
using F_ppiii = Object*(void* p0, void* p1, int p2, int p3, int p4);
using F_pppii = Object*(void* p0, void* p1, void* p2, int p3, int p4);
using F_ippii = Object*(int p0, void* p1, void* p2, int p3, int p4);
Handle<Code> AssembleCodeImpl(std::function<void(Assembler&)> assemble);
template <typename Signature>
GeneratedCode<Signature> AssembleCode(
std::function<void(Assembler&)> assemble) {
return GeneratedCode<Signature>::FromCode(*AssembleCodeImpl(assemble));
}
} // namespace internal
} // namespace v8
......
......@@ -10,16 +10,6 @@
#include "src/simulator.h"
#include "test/cctest/compiler/c-signature.h"
#if V8_TARGET_ARCH_IA32
#if __GNUC__
#define V8_CDECL __attribute__((cdecl))
#else
#define V8_CDECL __cdecl
#endif
#else
#define V8_CDECL
#endif
namespace v8 {
namespace internal {
namespace compiler {
......@@ -35,9 +25,10 @@ class CallHelper {
template <typename... Params>
R Call(Params... args) {
using FType = R(V8_CDECL*)(Params...);
CSignature::VerifyParams<Params...>(csig_);
return DoCall(FUNCTION_CAST<FType>(Generate()), args...);
byte* entry = Generate();
auto fn = GeneratedCode<R, Params...>::FromAddress(isolate_, entry);
return fn.Call(args...);
}
protected:
......@@ -46,19 +37,6 @@ class CallHelper {
virtual byte* Generate() = 0;
private:
#if USE_SIMULATOR
template <typename F, typename... Params>
R DoCall(F* f, Params... args) {
Simulator* simulator = Simulator::current(isolate_);
return simulator->Call<R>(FUNCTION_ADDR(f), args...);
}
#else
template <typename F, typename... Params>
R DoCall(F* f, Params... args) {
return f(args...);
}
#endif
Isolate* isolate_;
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -38,10 +38,11 @@ namespace v8 {
namespace internal {
// Define these function prototypes to match JSEntryFunction in execution.cc.
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
// TODO(s390): Refine these signatures per test case.
using F1 = Object*(int x, int p1, int p2, int p3, int p4);
using F2 = Object*(int x, int y, int p2, int p3, int p4);
using F3 = Object*(void* p0, int p1, int p2, int p3, int p4);
using F4 = Object*(void* p0, void* p1, int p2, int p3, int p4);
#define __ assm.
......@@ -66,9 +67,8 @@ TEST(0) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res = reinterpret_cast<intptr_t>(f.Call(3, 4, 0, 0, 0));
::printf("f() = %" V8PRIxPTR "\n", res);
CHECK_EQ(7, static_cast<int>(res));
}
......@@ -106,9 +106,8 @@ TEST(1) {
#ifdef DEBUG
code->Print();
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 100, 0, 0, 0, 0));
auto f = GeneratedCode<F1>::FromCode(*code);
intptr_t res = reinterpret_cast<intptr_t>(f.Call(100, 0, 0, 0, 0));
::printf("f() = %" V8PRIxPTR "\n", res);
CHECK_EQ(5050, static_cast<int>(res));
}
......@@ -158,9 +157,8 @@ TEST(2) {
#ifdef DEBUG
code->Print();
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 10, 0, 0, 0, 0));
auto f = GeneratedCode<F1>::FromCode(*code);
intptr_t res = reinterpret_cast<intptr_t>(f.Call(10, 0, 0, 0, 0));
::printf("f() = %" V8PRIxPTR "\n", res);
CHECK_EQ(3628800, static_cast<int>(res));
}
......@@ -255,9 +253,9 @@ TEST(4) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
f.Call(3, 4, 3, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
CHECK_EQ(4, static_cast<int>(res));
}
......@@ -283,9 +281,9 @@ TEST(5) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res =
reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
reinterpret_cast<intptr_t>(f.Call(3, 4, 3, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
CHECK_EQ(2, static_cast<int>(res));
}
......@@ -317,9 +315,9 @@ TEST(6) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res =
reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
reinterpret_cast<intptr_t>(f.Call(3, 4, 3, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
CHECK_EQ(1, static_cast<int>(res));
}
......@@ -349,9 +347,9 @@ TEST(7) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res =
reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
reinterpret_cast<intptr_t>(f.Call(3, 4, 3, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
CHECK_EQ(0x2468, static_cast<int>(res));
}
......@@ -380,9 +378,9 @@ TEST(8) {
#ifdef DEBUG
code->Print();
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
auto f = GeneratedCode<F1>::FromCode(*code);
intptr_t res =
reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 100, 0,
reinterpret_cast<intptr_t>(f.Call(100, 0,
0, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
CHECK_EQ(0, static_cast<int>(res));
......@@ -407,9 +405,9 @@ TEST(9) {
#ifdef DEBUG
code->Print();
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
auto f = GeneratedCode<F1>::FromCode(*code);
intptr_t res =
reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
reinterpret_cast<intptr_t>(f.Call(0, 0, 0, 0, 0));
::printf("f() = %" V8PRIdPTR "\n", res);
}
#endif
......@@ -492,9 +490,8 @@ TEST(10) {
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
auto f = GeneratedCode<F2>::FromCode(*code);
intptr_t res = reinterpret_cast<intptr_t>(f.Call(3, 4, 0, 0, 0));
::printf("f() = %" V8PRIxPTR "\n", res);
CHECK_EQ(0, static_cast<int>(res));
}
......
......@@ -132,7 +132,8 @@ static Isolate* GetIsolateFrom(LocalContext* context) {
int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
double from) {
#ifdef USE_SIMULATOR
return CALL_GENERATED_FP_INT(CcTest::i_isolate(), func, from, 0);
return Simulator::current(CcTest::i_isolate())
->CallFP<int32_t>(FUNCTION_ADDR(func), from, 0);
#else
return (*func)(from);
#endif
......
......@@ -38,12 +38,12 @@ namespace v8 {
namespace internal {
namespace test_macro_assembler_arm {
typedef void* (*F)(int x, int y, int p2, int p3, int p4);
using F = void*(int x, int y, int p2, int p3, int p4);
#define __ masm->
typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
typedef int (*F5)(void*, void*, void*, void*, void*);
using F3 = Object*(void* p0, int p1, int p2, int p3, int p4);
using F5 = int(void*, void*, void*, void*, void*);
TEST(LoadAndStoreWithRepresentation) {
Isolate* isolate = CcTest::i_isolate();
......@@ -129,8 +129,8 @@ TEST(LoadAndStoreWithRepresentation) {
isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
// Call the function from C++.
F5 f = FUNCTION_CAST<F5>(code->entry());
CHECK(!CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
auto f = GeneratedCode<F5>::FromCode(*code);
CHECK(!f.Call(0, 0, 0, 0, 0));
}
TEST(ExtractLane) {
......@@ -239,9 +239,8 @@ TEST(ExtractLane) {
OFStream os(stdout);
code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
auto f = GeneratedCode<F3>::FromCode(*code);
f.Call(&t, 0, 0, 0, 0);
for (int i = 0; i < 4; i++) {
CHECK_EQ(i, t.i32x4_low[i]);
CHECK_EQ(i, t.f32x4_low[i]);
......@@ -372,9 +371,8 @@ TEST(ReplaceLane) {
OFStream os(stdout);
code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
auto f = GeneratedCode<F3>::FromCode(*code);
f.Call(&t, 0, 0, 0, 0);
for (int i = 0; i < 4; i++) {
CHECK_EQ(i, t.i32x4_low[i]);
CHECK_EQ(i, t.f32x4_low[i]);
......
This diff is collapsed.
This diff is collapsed.
......@@ -198,16 +198,15 @@ void TestInvalidateExclusiveAccess(TestData initial_data, MemoryAccess access1,
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
F_piiii f = FUNCTION_CAST<F_piiii>(AssembleCode([&](Assembler& assm) {
auto f = AssembleCode<int(TestData*, int, int, int)>([&](Assembler& assm) {
AssembleLoadExcl(&assm, access1, r1, r1);
AssembleMemoryAccess(&assm, access2, r3, r2, r1);
AssembleStoreExcl(&assm, access3, r0, r3, r1);
}));
});
TestData t = initial_data;
int res =
reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0));
int res = f.Call(&t, 0, 0, 0);
CHECK_EQ(expected_res, res);
switch (access3.size) {
case MemoryAccess::Size::Byte:
......@@ -267,12 +266,11 @@ namespace {
int ExecuteMemoryAccess(Isolate* isolate, TestData* test_data,
MemoryAccess access) {
HandleScope scope(isolate);
F_piiii f = FUNCTION_CAST<F_piiii>(AssembleCode([&](Assembler& assm) {
auto f = AssembleCode<int(TestData*, int, int)>([&](Assembler& assm) {
AssembleMemoryAccess(&assm, access, r0, r2, r1);
}));
});
return reinterpret_cast<int>(
CALL_GENERATED_CODE(isolate, f, test_data, 0, 0, 0, 0));
return f.Call(test_data, 0, 0);
}
} // namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment