Commit 429f3cf9 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Direct call to native RegExp code from JavaScript.

Calls to RegExp no longer have to be via a call to the runtime system. A new stub have been added which can handle this call in generated code. The stub checks all the parameters and creates RegExp entry frame in the same way as it is created by the runtime system. Bailout to the runtime system is done whenever an uncommon situation is encountered or when the static data used is not initialized. After running the native RegExp code the last match info is updated like in the runtime system.

Currently only ASCII strings are handled.

Added another argument to the RegExp entry frame. It indicated whether the call is direct from JavaScript code or through the runtime system. This information is used when RegExp execution is interrupted. If an interruption happens when RegExp code is called directly a retry is issued causing the interruption to be handled via the runtime system. The reason for this is that the direct call to RegExp code does not support garbage collection.
Review URL: http://codereview.chromium.org/521028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3542 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8618b984
......@@ -3451,6 +3451,19 @@ void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
ASSERT_EQ(4, args->length());
Load(args->at(0));
Load(args->at(1));
Load(args->at(2));
Load(args->at(3));
frame_->CallRuntime(Runtime::kRegExpExec, 4);
frame_->EmitPush(r0);
}
void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 2);
......
......@@ -363,6 +363,9 @@ class CodeGenerator: public AstVisitor {
// Fast support for StringAdd.
void GenerateStringAdd(ZoneList<Expression*>* args);
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
......
......@@ -59,15 +59,19 @@ namespace internal {
*
* Each call to a public method should retain this convention.
* The stack will have the following structure:
* - direct_call (if 1, direct call from JavaScript code, if 0 call
* through the runtime system)
* - stack_area_base (High end of the memory area to use as
* backtracking stack)
* - at_start (if 1, start at start of string, if 0, don't)
* - at_start (if 1, we are starting at the start of the
* string, otherwise 0)
* - int* capture_array (int[num_saved_registers_], for output).
* --- sp when called ---
* - link address
* - backup of registers r4..r11
* - int* capture_array (int[num_saved_registers_], for output).
* - end of input (Address of end of string)
* - start of input (Address of first character in string)
* - start index (character index of start)
* --- frame pointer ----
* - void* input_string (location of a handle containing the string)
* - Offset of location before start of input (effectively character
......@@ -85,11 +89,13 @@ namespace internal {
* The data up to the return address must be placed there by the calling
* code, by calling the code entry as cast to a function with the signature:
* int (*match)(String* input_string,
* int start_index,
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* byte* stack_area_base)
* byte* stack_area_base,
* bool direct_call)
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc).
*/
......
......@@ -127,6 +127,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
static const int kRegisterOutput = kReturnAddress + kPointerSize;
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
......
......@@ -62,9 +62,9 @@ class SimulatorStack : public v8::internal::AllStatic {
// Call the generated regexp code directly. The entry function pointer should
// expect seven int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......@@ -79,9 +79,9 @@ class SimulatorStack : public v8::internal::AllStatic {
assembler::arm::Simulator::current()->Call(FUNCTION_ADDR(entry), 5, \
p0, p1, p2, p3, p4))
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
assembler::arm::Simulator::current()->Call( \
FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6)
FUNCTION_ADDR(entry), 8, p0, p1, p2, p3, p4, p5, p6, p7)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
try_catch_address == NULL ? \
......
......@@ -674,6 +674,19 @@ ExternalReference ExternalReference::re_case_insensitive_compare_uc16() {
FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16)));
}
ExternalReference ExternalReference::address_of_static_offsets_vector() {
return ExternalReference(OffsetsVector::static_offsets_vector_address());
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_address() {
return ExternalReference(RegExpStack::memory_address());
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_size() {
return ExternalReference(RegExpStack::memory_size_address());
}
#endif
......
......@@ -420,6 +420,11 @@ class ExternalReference BASE_EMBEDDED {
// Static variable RegExpStack::limit_address()
static ExternalReference address_of_regexp_stack_limit();
// Static variables for RegExp.
static ExternalReference address_of_static_offsets_vector();
static ExternalReference address_of_regexp_stack_memory_address();
static ExternalReference address_of_regexp_stack_memory_size();
// Static variable Heap::NewSpaceStart()
static ExternalReference new_space_start();
static ExternalReference heap_always_allocate_scope_depth();
......
......@@ -52,6 +52,7 @@ namespace internal {
V(Instanceof) \
V(CounterOp) \
V(ArgumentsAccess) \
V(RegExpExec) \
V(Runtime) \
V(CEntry) \
V(JSEntry)
......
......@@ -345,6 +345,7 @@ CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
{&CodeGenerator::GenerateIsObject, "_IsObject"},
{&CodeGenerator::GenerateIsFunction, "_IsFunction"},
{&CodeGenerator::GenerateStringAdd, "_StringAdd"},
{&CodeGenerator::GenerateRegExpExec, "_RegExpExec"},
};
......
......@@ -478,6 +478,26 @@ class ArgumentsAccessStub: public CodeStub {
};
class RegExpExecStub: public CodeStub {
public:
RegExpExecStub() { }
private:
Major MajorKey() { return RegExpExec; }
int MinorKey() { return 0; }
void Generate(MacroAssembler* masm);
const char* GetName() { return "RegExpExecStub"; }
#ifdef DEBUG
void Print() {
PrintF("RegExpExecStub\n");
}
#endif
};
} // namespace internal
} // namespace v8
......
......@@ -231,6 +231,7 @@ DEFINE_bool(preemption, false,
// Regexp
DEFINE_bool(trace_regexps, false, "trace regexp execution")
DEFINE_bool(regexp_optimization, true, "generate optimized regexp code")
DEFINE_bool(regexp_entry_native, true, "use native code to enter regexp")
// Testing flags test/cctest/test-{flags,api,serialization}.cc
DEFINE_bool(testing_bool_flag, true, "testing_bool_flag")
......
This diff is collapsed.
......@@ -544,6 +544,9 @@ class CodeGenerator: public AstVisitor {
// Fast support for StringAdd.
void GenerateStringAdd(ZoneList<Expression*>* args);
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
......
......@@ -325,6 +325,17 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
}
Condition MacroAssembler::IsObjectStringType(Register heap_object,
Register map,
Register instance_type) {
mov(map, FieldOperand(heap_object, HeapObject::kMapOffset));
movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
ASSERT(kNotStringTag != 0);
test(instance_type, Immediate(kIsNotStringMask));
return zero;
}
void MacroAssembler::FCmp() {
if (CpuFeatures::IsSupported(CMOV)) {
fucomip();
......
......@@ -141,6 +141,15 @@ class MacroAssembler: public Assembler {
// Compare instance type for map.
void CmpInstanceType(Register map, InstanceType type);
// Check if the object in register heap_object is a string. Afterwards the
// register map contains the object map and the register instance_type
// contains the instance_type. The registers map and instance_type can be the
// same in which case it contains the instance type afterwards. Either of the
// registers map and instance_type can be the same as heap_object.
Condition IsObjectStringType(Register heap_object,
Register map,
Register instance_type);
// FCmp is similar to integer cmp, but requires unsigned
// jcc instructions (je, ja, jae, jb, jbe, je, and jz).
void FCmp();
......
......@@ -55,13 +55,17 @@ namespace internal {
*
* Each call to a public method should retain this convention.
* The stack will have the following structure:
* - direct_call (if 1, direct call from JavaScript code, if 0
* call through the runtime system)
* - stack_area_base (High end of the memory area to use as
* backtracking stack)
* - at_start (if 1, start at start of string, if 0, don't)
* - at_start (if 1, we are starting at the start of the
* string, otherwise 0)
* - int* capture_array (int[num_saved_registers_], for output).
* - end of input (Address of end of string)
* - start of input (Address of first character in string)
* - void* input_string (location of a handle containing the string)
* - start index (character index of start)
* - String* input_string (location of a handle containing the string)
* --- frame alignment (if applicable) ---
* - return address
* ebp-> - old ebp
......@@ -81,11 +85,13 @@ namespace internal {
* The data up to the return address must be placed there by the calling
* code, by calling the code entry as cast to a function with the signature:
* int (*match)(String* input_string,
* int start_index,
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* byte* stack_area_base)
* byte* stack_area_base,
* bool direct_call)
*/
#define __ ACCESS_MASM(masm_)
......@@ -942,6 +948,12 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
// If not real stack overflow the stack guard was used to interrupt
// execution for another purpose.
// If this is a direct call from JavaScript retry the RegExp forcing the call
// through the runtime system. Currently the direct call cannot handle a GC.
if (frame_entry<int>(re_frame, kDirectCall) == 1) {
return RETRY;
}
// Prepare for possible GC.
HandleScope handles;
Handle<Code> code_handle(re_code);
......
......@@ -128,6 +128,7 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
static const int kRegisterOutput = kInputEnd + kPointerSize;
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
// Below the frame pointer - local stack variables.
// When adding local variables remember to push space for them in
// the frame in GetCode.
......
......@@ -52,9 +52,9 @@ class SimulatorStack : public v8::internal::AllStatic {
};
// Call the generated regexp code directly. The entry function pointer should
// expect seven int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......
......@@ -112,37 +112,6 @@ static inline void ThrowRegExpException(Handle<JSRegExp> re,
// Generic RegExp methods. Dispatches to implementation specific methods.
class OffsetsVector {
public:
inline OffsetsVector(int num_registers)
: offsets_vector_length_(num_registers) {
if (offsets_vector_length_ > kStaticOffsetsVectorSize) {
vector_ = NewArray<int>(offsets_vector_length_);
} else {
vector_ = static_offsets_vector_;
}
}
inline ~OffsetsVector() {
if (offsets_vector_length_ > kStaticOffsetsVectorSize) {
DeleteArray(vector_);
vector_ = NULL;
}
}
inline int* vector() { return vector_; }
inline int length() { return offsets_vector_length_; }
private:
int* vector_;
int offsets_vector_length_;
static const int kStaticOffsetsVectorSize = 50;
static int static_offsets_vector_[kStaticOffsetsVectorSize];
};
int OffsetsVector::static_offsets_vector_[
OffsetsVector::kStaticOffsetsVectorSize];
Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
Handle<String> pattern,
Handle<String> flag_str) {
......@@ -448,6 +417,14 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
// The captures come in (start, end+1) pairs.
for (int i = 0; i < number_of_capture_registers; i += 2) {
// Capture values are relative to start_offset only.
// Convert them to be relative to start of string.
if (captures_vector[i] >= 0) {
captures_vector[i] += previous_index;
}
if (captures_vector[i + 1] >= 0) {
captures_vector[i + 1] += previous_index;
}
SetCapture(*array, i, captures_vector[i]);
SetCapture(*array, i + 1, captures_vector[i + 1]);
}
......@@ -4606,4 +4583,8 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
pattern);
}
int OffsetsVector::static_offsets_vector_[
OffsetsVector::kStaticOffsetsVectorSize];
}} // namespace v8::internal
......@@ -101,13 +101,23 @@ class RegExpImpl {
int index,
Handle<JSArray> lastMatchInfo);
// Offsets in the lastMatchInfo array.
// Array index in the lastMatchInfo array.
static const int kLastCaptureCount = 0;
static const int kLastSubject = 1;
static const int kLastInput = 2;
static const int kFirstCapture = 3;
static const int kLastMatchOverhead = 3;
// Direct offset into the lastMatchInfo array.
static const int kLastCaptureCountOffset =
FixedArray::kHeaderSize + kLastCaptureCount * kPointerSize;
static const int kLastSubjectOffset =
FixedArray::kHeaderSize + kLastSubject * kPointerSize;
static const int kLastInputOffset =
FixedArray::kHeaderSize + kLastInput * kPointerSize;
static const int kFirstCaptureOffset =
FixedArray::kHeaderSize + kFirstCapture * kPointerSize;
// Used to access the lastMatchInfo array.
static int GetCapture(FixedArray* array, int index) {
return Smi::cast(array->get(index + kFirstCapture))->value();
......@@ -1276,6 +1286,40 @@ class RegExpEngine: public AllStatic {
};
class OffsetsVector {
public:
inline OffsetsVector(int num_registers)
: offsets_vector_length_(num_registers) {
if (offsets_vector_length_ > kStaticOffsetsVectorSize) {
vector_ = NewArray<int>(offsets_vector_length_);
} else {
vector_ = static_offsets_vector_;
}
}
inline ~OffsetsVector() {
if (offsets_vector_length_ > kStaticOffsetsVectorSize) {
DeleteArray(vector_);
vector_ = NULL;
}
}
inline int* vector() { return vector_; }
inline int length() { return offsets_vector_length_; }
static const int kStaticOffsetsVectorSize = 50;
private:
static Address static_offsets_vector_address() {
return reinterpret_cast<Address>(&static_offsets_vector_);
}
int* vector_;
int offsets_vector_length_;
static int static_offsets_vector_[kStaticOffsetsVectorSize];
friend class ExternalReference;
};
} } // namespace v8::internal
#endif // V8_JSREGEXP_H_
......@@ -3603,6 +3603,14 @@ class JSRegExp: public JSObject {
static const int kIrregexpCaptureCountIndex = kDataIndex + 3;
static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
// Offsets directly into the data fixed array.
static const int kDataTagOffset =
FixedArray::kHeaderSize + kTagIndex * kPointerSize;
static const int kDataAsciiCodeOffset =
FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize;
static const int kIrregexpCaptureCountOffset =
FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
};
......
......@@ -136,7 +136,7 @@ function CompileRegExp(pattern, flags) {
function DoRegExpExec(regexp, string, index) {
return %RegExpExec(regexp, string, index, lastMatchInfo);
return %_RegExpExec(regexp, string, index, lastMatchInfo);
}
......@@ -164,7 +164,7 @@ function RegExpExec(string) {
%_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %RegExpExec(this, s, i, lastMatchInfo);
var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
if (matchIndices == null) {
if (this.global) this.lastIndex = 0;
......@@ -221,7 +221,7 @@ function RegExpTest(string) {
%_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %RegExpExec(this, s, i, lastMatchInfo);
var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
if (matchIndices == null) {
if (this.global) this.lastIndex = 0;
......
......@@ -143,17 +143,6 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
input_end,
offsets_vector,
previous_index == 0);
if (res == SUCCESS) {
// Capture values are relative to start_offset only.
// Convert them to be relative to start of string.
for (int i = 0; i < offsets_vector_length; i++) {
if (offsets_vector[i] >= 0) {
offsets_vector[i] += previous_index;
}
}
}
return res;
}
......@@ -167,7 +156,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
int* output,
bool at_start) {
typedef int (*matcher)(String*, int, const byte*,
const byte*, int*, int, Address);
const byte*, int*, int, Address, int);
matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
int at_start_val = at_start ? 1 : 0;
......@@ -176,6 +165,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
RegExpStack stack;
Address stack_base = RegExpStack::stack_base();
int direct_call = 0;
int result = CALL_GENERATED_REGEXP_CODE(matcher_func,
input,
start_offset,
......@@ -183,7 +173,8 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
input_end,
output,
at_start_val,
stack_base);
stack_base,
direct_call);
ASSERT(result <= SUCCESS);
ASSERT(result >= RETRY);
......
......@@ -98,12 +98,24 @@ class RegExpStack {
void Free();
};
// Address of allocated memory.
static Address memory_address() {
return reinterpret_cast<Address>(&thread_local_.memory_);
}
// Address of size of allocated memory.
static Address memory_size_address() {
return reinterpret_cast<Address>(&thread_local_.memory_size_);
}
// Resets the buffer if it has grown beyond the default/minimum size.
// After this, the buffer is either the default size, or it is empty, so
// you have to call EnsureCapacity before using it again.
static void Reset();
static ThreadLocal thread_local_;
friend class ExternalReference;
};
}} // namespace v8::internal
......
......@@ -153,7 +153,9 @@ namespace internal {
SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls) \
SC(generic_binary_stub_calls_regs, V8.GenericBinaryStubCallsRegs) \
SC(string_add_runtime, V8.StringAddRuntime) \
SC(string_add_native, V8.StringAddNative)
SC(string_add_native, V8.StringAddNative) \
SC(regexp_entry_runtime, V8.RegExpEntryRuntime) \
SC(regexp_entry_native, V8.RegExpEntryNative)
// This file contains all the v8 counters that are in use.
class Counters : AllStatic {
......
......@@ -3876,6 +3876,19 @@ void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 4);
// Load the arguments on the stack and call the runtime system.
Load(args->at(0));
Load(args->at(1));
Load(args->at(2));
Load(args->at(3));
Result result = frame_->CallRuntime(Runtime::kRegExpExec, 4);
frame_->Push(&result);
}
void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
ASSERT_EQ(2, args->length());
......
......@@ -541,6 +541,9 @@ class CodeGenerator: public AstVisitor {
// Fast support for StringAdd.
void GenerateStringAdd(ZoneList<Expression*>* args);
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
......
......@@ -67,13 +67,17 @@ namespace internal {
*
* The stack will have the following content, in some order, indexable from the
* frame pointer (see, e.g., kStackHighEnd):
* - direct_call (if 1, direct call from JavaScript code, if 0 call
* through the runtime system)
* - stack_area_base (High end of the memory area to use as
* backtracking stack)
* - at_start (if 1, start at start of string, if 0, don't)
* - at_start (if 1, we are starting at the start of the
* string, otherwise 0)
* - int* capture_array (int[num_saved_registers_], for output).
* - end of input (Address of end of string)
* - start of input (Address of first character in string)
* - String** input_string (location of a handle containing the string)
* - start index (character index of start)
* - String* input_string (input string)
* - return address
* - backup of callee save registers (rbx, possibly rsi and rdi).
* - Offset of location before start of input (effectively character
......@@ -90,11 +94,13 @@ namespace internal {
* calling the code's entry address cast to a function pointer with the
* following signature:
* int (*match)(String* input_string,
* int start_index,
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* byte* stack_area_base)
* byte* stack_area_base,
* bool direct_call)
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -143,6 +143,8 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// AtStart is passed as 32 bit int (values 0 or 1).
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
// DirectCall is passed as 32 bit int (values 0 or 1).
static const int kDirectCall = kStackHighEnd + kPointerSize;
#else
// In AMD64 ABI Calling Convention, the first six integer parameters
// are passed as registers, and caller must allocate space on the stack
......@@ -154,6 +156,7 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
static const int kRegisterOutput = kInputEnd - kPointerSize;
static const int kAtStart = kRegisterOutput - kPointerSize;
static const int kStackHighEnd = kFrameAlign;
static const int kDirectCall = kStackHighEnd + kPointerSize;
#endif
#ifdef _WIN64
......
......@@ -53,9 +53,9 @@ class SimulatorStack : public v8::internal::AllStatic {
};
// Call the generated regexp code directly. The entry function pointer should
// expect seven int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......
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