Version 3.3.4
Implemented API to disallow code generation from strings for a context (issue 1258).
Fixed bug with whitespaces in parseInt (issue 955).
Fixed bug with == comparison of Date objects (issue 1356).
Added GYP variables for ARM code generation: v8_can_use_vfp_instructions, v8_can_use_unaligned_accesses and v8_use_arm_eabi_hardfloat.
git-svn-id: http://v8.googlecode.com/svn/trunk@7779 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/.gitignore b/.gitignore
index af1b0d7..7219675 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@
/tools/visual_studio/Release
/xcodebuild/
TAGS
+Makefile
+*.Makefile
diff --git a/ChangeLog b/ChangeLog
index a90b27a..b089e41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-05-04: Version 3.3.4
+
+ Implemented API to disallow code generation from strings for a context
+ (issue 1258).
+
+ Fixed bug with whitespaces in parseInt (issue 955).
+
+ Fixed bug with == comparison of Date objects (issue 1356).
+
+ Added GYP variables for ARM code generation:
+ v8_can_use_vfp_instructions, v8_can_use_unaligned_accesses
+ and v8_use_arm_eabi_hardfloat.
+
+
2011-05-02: Version 3.3.3
Added support for generating Visual Studio solution and project files
diff --git a/SConstruct b/SConstruct
index fb780a2..0d01e7e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -162,7 +162,7 @@
}
},
'armeabi:softfp' : {
- 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
+ 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0', 'CAN_USE_VFP_INSTRUCTIONS'],
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=softfp'],
}
diff --git a/include/v8.h b/include/v8.h
index b621f01..4dcbf28 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -115,7 +115,7 @@
}
-// --- W e a k H a n d l e s
+// --- Weak Handles ---
/**
@@ -131,7 +131,7 @@
void* parameter);
-// --- H a n d l e s ---
+// --- Handles ---
#define TYPE_CHECK(T, S) \
while (false) { \
@@ -483,7 +483,7 @@
};
-// --- S p e c i a l o b j e c t s ---
+// --- Special objects ---
/**
@@ -841,7 +841,7 @@
};
-// --- V a l u e ---
+// --- Value ---
/**
@@ -1349,87 +1349,6 @@
};
-/**
- * An instance of the built-in Date constructor (ECMA-262, 15.9).
- */
-class Date : public Value {
- public:
- V8EXPORT static Local<Value> New(double time);
-
- /**
- * A specialization of Value::NumberValue that is more efficient
- * because we know the structure of this object.
- */
- V8EXPORT double NumberValue() const;
-
- static inline Date* Cast(v8::Value* obj);
-
- /**
- * Notification that the embedder has changed the time zone,
- * daylight savings time, or other date / time configuration
- * parameters. V8 keeps a cache of various values used for
- * date / time computation. This notification will reset
- * those cached values for the current context so that date /
- * time configuration changes would be reflected in the Date
- * object.
- *
- * This API should not be called more than needed as it will
- * negatively impact the performance of date operations.
- */
- V8EXPORT static void DateTimeConfigurationChangeNotification();
-
- private:
- V8EXPORT static void CheckCast(v8::Value* obj);
-};
-
-
-/**
- * An instance of the built-in RegExp constructor (ECMA-262, 15.10).
- */
-class RegExp : public Value {
- public:
- /**
- * Regular expression flag bits. They can be or'ed to enable a set
- * of flags.
- */
- enum Flags {
- kNone = 0,
- kGlobal = 1,
- kIgnoreCase = 2,
- kMultiline = 4
- };
-
- /**
- * Creates a regular expression from the given pattern string and
- * the flags bit field. May throw a JavaScript exception as
- * described in ECMA-262, 15.10.4.1.
- *
- * For example,
- * RegExp::New(v8::String::New("foo"),
- * static_cast<RegExp::Flags>(kGlobal | kMultiline))
- * is equivalent to evaluating "/foo/gm".
- */
- V8EXPORT static Local<RegExp> New(Handle<String> pattern,
- Flags flags);
-
- /**
- * Returns the value of the source property: a string representing
- * the regular expression.
- */
- V8EXPORT Local<String> GetSource() const;
-
- /**
- * Returns the flags bit field.
- */
- V8EXPORT Flags GetFlags() const;
-
- static inline RegExp* Cast(v8::Value* obj);
-
- private:
- V8EXPORT static void CheckCast(v8::Value* obj);
-};
-
-
enum PropertyAttribute {
None = 0,
ReadOnly = 1 << 0,
@@ -1757,6 +1676,87 @@
/**
+ * An instance of the built-in Date constructor (ECMA-262, 15.9).
+ */
+class Date : public Object {
+ public:
+ V8EXPORT static Local<Value> New(double time);
+
+ /**
+ * A specialization of Value::NumberValue that is more efficient
+ * because we know the structure of this object.
+ */
+ V8EXPORT double NumberValue() const;
+
+ static inline Date* Cast(v8::Value* obj);
+
+ /**
+ * Notification that the embedder has changed the time zone,
+ * daylight savings time, or other date / time configuration
+ * parameters. V8 keeps a cache of various values used for
+ * date / time computation. This notification will reset
+ * those cached values for the current context so that date /
+ * time configuration changes would be reflected in the Date
+ * object.
+ *
+ * This API should not be called more than needed as it will
+ * negatively impact the performance of date operations.
+ */
+ V8EXPORT static void DateTimeConfigurationChangeNotification();
+
+ private:
+ V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
+/**
+ * An instance of the built-in RegExp constructor (ECMA-262, 15.10).
+ */
+class RegExp : public Object {
+ public:
+ /**
+ * Regular expression flag bits. They can be or'ed to enable a set
+ * of flags.
+ */
+ enum Flags {
+ kNone = 0,
+ kGlobal = 1,
+ kIgnoreCase = 2,
+ kMultiline = 4
+ };
+
+ /**
+ * Creates a regular expression from the given pattern string and
+ * the flags bit field. May throw a JavaScript exception as
+ * described in ECMA-262, 15.10.4.1.
+ *
+ * For example,
+ * RegExp::New(v8::String::New("foo"),
+ * static_cast<RegExp::Flags>(kGlobal | kMultiline))
+ * is equivalent to evaluating "/foo/gm".
+ */
+ V8EXPORT static Local<RegExp> New(Handle<String> pattern,
+ Flags flags);
+
+ /**
+ * Returns the value of the source property: a string representing
+ * the regular expression.
+ */
+ V8EXPORT Local<String> GetSource() const;
+
+ /**
+ * Returns the flags bit field.
+ */
+ V8EXPORT Flags GetFlags() const;
+
+ static inline RegExp* Cast(v8::Value* obj);
+
+ private:
+ V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
+/**
* A JavaScript value that wraps a C++ void*. This type of value is
* mainly used to associate C++ data structures with JavaScript
* objects.
@@ -1783,7 +1783,7 @@
};
-// --- T e m p l a t e s ---
+// --- Templates ---
/**
@@ -2317,7 +2317,7 @@
};
-// --- E x t e n s i o n s ---
+// --- Extensions ---
/**
@@ -2369,7 +2369,7 @@
};
-// --- S t a t i c s ---
+// --- Statics ---
Handle<Primitive> V8EXPORT Undefined();
@@ -2410,7 +2410,7 @@
bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints);
-// --- E x c e p t i o n s ---
+// --- Exceptions ---
typedef void (*FatalErrorCallback)(const char* location, const char* message);
@@ -2441,7 +2441,7 @@
};
-// --- C o u n t e r s C a l l b a c k s ---
+// --- Counters Callbacks ---
typedef int* (*CounterLookupCallback)(const char* name);
@@ -2452,7 +2452,7 @@
typedef void (*AddHistogramSampleCallback)(void* histogram, int sample);
-// --- M e m o r y A l l o c a t i o n C a l l b a c k ---
+// --- Memory Allocation Callback ---
enum ObjectSpace {
kObjectSpaceNewSpace = 1 << 0,
kObjectSpaceOldPointerSpace = 1 << 1,
@@ -2476,12 +2476,20 @@
AllocationAction action,
int size);
-// --- F a i l e d A c c e s s C h e c k C a l l b a c k ---
+// --- Failed Access Check Callback ---
typedef void (*FailedAccessCheckCallback)(Local<Object> target,
AccessType type,
Local<Value> data);
-// --- G a r b a g e C o l l e c t i o n C a l l b a c k s
+// --- AllowCodeGenerationFromStrings callbacks ---
+
+/**
+ * Callback to check if code generation from strings is allowed. See
+ * Context::AllowCodeGenerationFromStrings.
+ */
+typedef bool (*AllowCodeGenerationFromStringsCallback)(Local<Context> context);
+
+// --- Garbage Collection Callbacks ---
/**
* Applications can register callback functions which will be called
@@ -2662,6 +2670,13 @@
static void SetFatalErrorHandler(FatalErrorCallback that);
/**
+ * Set the callback to invoke to check if code generation from
+ * strings should be allowed.
+ */
+ static void SetAllowCodeGenerationFromStringsCallback(
+ AllowCodeGenerationFromStringsCallback that);
+
+ /**
* Ignore out-of-memory exceptions.
*
* V8 running out of memory is treated as a fatal error by default.
@@ -3189,7 +3204,7 @@
};
-// --- C o n t e x t ---
+// --- Context ---
/**
@@ -3325,6 +3340,21 @@
Local<Value> GetData();
/**
+ * Control whether code generation from strings is allowed. Calling
+ * this method with false will disable 'eval' and the 'Function'
+ * constructor for code running in this context. If 'eval' or the
+ * 'Function' constructor are used an exception will be thrown.
+ *
+ * If code generation from strings is not allowed the
+ * V8::AllowCodeGenerationFromStrings callback will be invoked if
+ * set before blocking the call to 'eval' or the 'Function'
+ * constructor. If that callback returns true, the call will be
+ * allowed, otherwise an exception will be thrown. If no callback is
+ * set an exception will be thrown.
+ */
+ void AllowCodeGenerationFromStrings(bool allow);
+
+ /**
* Stack-allocated class which sets the execution context for all
* operations executed within a local scope.
*/
@@ -3520,7 +3550,7 @@
};
-// --- I m p l e m e n t a t i o n ---
+// --- Implementation ---
namespace internal {
diff --git a/src/accessors.cc b/src/accessors.cc
index 5f9bf74..d8df05e 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -32,6 +32,7 @@
#include "deoptimizer.h"
#include "execution.h"
#include "factory.h"
+#include "list-inl.h"
#include "safepoint-table.h"
#include "scopeinfo.h"
diff --git a/src/api.cc b/src/api.cc
index 84c0be4..792e488 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -372,6 +372,13 @@
}
+void V8::SetAllowCodeGenerationFromStringsCallback(
+ AllowCodeGenerationFromStringsCallback callback) {
+ i::Isolate* isolate = EnterIsolateIfNeeded();
+ isolate->set_allow_code_gen_callback(callback);
+}
+
+
#ifdef DEBUG
void ImplementationUtilities::ZapHandleRange(i::Object** begin,
i::Object** end) {
@@ -3918,6 +3925,20 @@
}
+void Context::AllowCodeGenerationFromStrings(bool allow) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
+ return;
+ }
+ ENTER_V8(isolate);
+ i::Object** ctx = reinterpret_cast<i::Object**>(this);
+ i::Handle<i::Context> context =
+ i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
+ context->set_allow_code_gen_from_strings(
+ allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
+}
+
+
void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
}
diff --git a/src/api.h b/src/api.h
index 7423d28..cd0205b 100644
--- a/src/api.h
+++ b/src/api.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index fa97a3b..3533dfd 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -51,24 +51,30 @@
unsigned CpuFeatures::found_by_runtime_probing_ = 0;
-#ifdef __arm__
+// Get the CPU features enabled by the build. For cross compilation the
+// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP_INSTRUCTIONS
+// can be defined to enable ARMv7 and VFPv3 instructions when building the
+// snapshot.
static uint64_t CpuFeaturesImpliedByCompiler() {
uint64_t answer = 0;
#ifdef CAN_USE_ARMV7_INSTRUCTIONS
answer |= 1u << ARMv7;
#endif // def CAN_USE_ARMV7_INSTRUCTIONS
+#ifdef CAN_USE_VFP_INSTRUCTIONS
+ answer |= 1u << VFP3 | 1u << ARMv7;
+#endif // def CAN_USE_VFP_INSTRUCTIONS
+
+#ifdef __arm__
// If the compiler is allowed to use VFP then we can use VFP too in our code
// generation even when generating snapshots. This won't work for cross
// compilation. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
answer |= 1u << VFP3 | 1u << ARMv7;
#endif // defined(__VFP_FP__) && !defined(__SOFTFP__)
-#ifdef CAN_USE_VFP_INSTRUCTIONS
- answer |= 1u << VFP3 | 1u << ARMv7;
-#endif // def CAN_USE_VFP_INSTRUCTIONS
+#endif // def __arm__
+
return answer;
}
-#endif // def __arm__
void CpuFeatures::Probe() {
@@ -76,6 +82,18 @@
#ifdef DEBUG
initialized_ = true;
#endif
+
+ // Get the features implied by the OS and the compiler settings. This is the
+ // minimal set of features which is also alowed for generated code in the
+ // snapshot.
+ supported_ |= OS::CpuFeaturesImpliedByPlatform();
+ supported_ |= CpuFeaturesImpliedByCompiler();
+
+ if (Serializer::enabled()) {
+ // No probing for features if we might serialize (generate snapshot).
+ return;
+ }
+
#ifndef __arm__
// For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
// enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
@@ -87,13 +105,8 @@
supported_ |= 1u << ARMv7;
}
#else // def __arm__
- if (Serializer::enabled()) {
- supported_ |= OS::CpuFeaturesImpliedByPlatform();
- supported_ |= CpuFeaturesImpliedByCompiler();
- return; // No features if we might serialize.
- }
-
- if (OS::ArmCpuHasFeature(VFP3)) {
+ // Probe for additional features not already known to be available.
+ if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) {
// This implementation also sets the VFP flags if runtime
// detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
// 0406B, page A1-6.
@@ -101,7 +114,7 @@
found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7;
}
- if (OS::ArmCpuHasFeature(ARMv7)) {
+ if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) {
supported_ |= 1u << ARMv7;
found_by_runtime_probing_ |= 1u << ARMv7;
}
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index c6b40ee..33b6731 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -46,7 +46,7 @@
deoptimization_index_(deoptimization_index) { }
virtual ~SafepointGenerator() { }
- virtual void BeforeCall(int call_size) {
+ virtual void BeforeCall(int call_size) const {
ASSERT(call_size >= 0);
// Ensure that we have enough space after the previous safepoint position
// for the generated code there.
@@ -63,7 +63,7 @@
}
}
- virtual void AfterCall() {
+ virtual void AfterCall() const {
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
@@ -2641,7 +2641,7 @@
// The number of arguments is stored in receiver which is r0, as expected
// by InvokeFunction.
v8::internal::ParameterCount actual(receiver);
- __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -3084,7 +3084,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers, env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(r1, count, CALL_FUNCTION, &generator);
+ __ InvokeFunction(r1, count, CALL_FUNCTION, generator);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -4256,7 +4256,7 @@
SafepointGenerator safepoint_generator(this,
pointers,
env->deoptimization_index());
- __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
}
@@ -4272,7 +4272,7 @@
SafepointGenerator safepoint_generator(this,
pointers,
env->deoptimization_index());
- __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
}
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index eeaba73..3f2b01e 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -886,7 +886,7 @@
Register code_reg,
Label* done,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
bool definitely_matches = false;
Label regular_invoke;
@@ -941,11 +941,9 @@
Handle<Code> adaptor =
isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) {
- call_wrapper->BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
- }
+ call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
Call(adaptor, RelocInfo::CODE_TARGET);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
b(done);
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
@@ -959,15 +957,15 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
Label done;
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag,
call_wrapper);
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
+ call_wrapper.BeforeCall(CallSize(code));
Call(code);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
Jump(code);
@@ -1002,7 +1000,7 @@
void MacroAssembler::InvokeFunction(Register fun,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
// Contract with called JS functions requires that function is passed in r1.
ASSERT(fun.is(r1));
@@ -2314,12 +2312,12 @@
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
GetBuiltinEntry(r2, id);
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(r2));
+ call_wrapper.BeforeCall(CallSize(r2));
Call(r2);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
Jump(r2);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 7d29757..ca6b015 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -33,9 +33,6 @@
namespace v8 {
namespace internal {
-// Forward declaration.
-class CallWrapper;
-
// ----------------------------------------------------------------------------
// Static helper functions
@@ -353,7 +350,7 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
@@ -366,7 +363,7 @@
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
@@ -802,7 +799,7 @@
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Store the code object for the given builtin in the target register and
// setup the function in r1.
@@ -1005,7 +1002,7 @@
Register code_reg,
Label* done,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Activation support.
void EnterFrame(StackFrame::Type type);
@@ -1066,21 +1063,6 @@
#endif // ENABLE_DEBUGGER_SUPPORT
-// Helper class for generating code or data associated with the code
-// right after a call instruction. As an example this can be used to
-// generate safepoint data after calls for crankshaft.
-class CallWrapper {
- public:
- CallWrapper() { }
- virtual ~CallWrapper() { }
- // Called just before emitting a call. Argument is the size of the generated
- // call code.
- virtual void BeforeCall(int call_size) = 0;
- // Called just after emitting a call, i.e., at the return site for the call.
- virtual void AfterCall() = 0;
-};
-
-
// -----------------------------------------------------------------------------
// Static helper functions.
diff --git a/src/assembler.h b/src/assembler.h
index 5669f1a..ef4ddc0 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -843,6 +843,28 @@
double power_double_int(double x, int y);
double power_double_double(double x, double y);
+// Helper class for generating code or data associated with the code
+// right after a call instruction. As an example this can be used to
+// generate safepoint data after calls for crankshaft.
+class CallWrapper {
+ public:
+ CallWrapper() { }
+ virtual ~CallWrapper() { }
+ // Called just before emitting a call. Argument is the size of the generated
+ // call code.
+ virtual void BeforeCall(int call_size) const = 0;
+ // Called just after emitting a call, i.e., at the return site for the call.
+ virtual void AfterCall() const = 0;
+};
+
+class NullCallWrapper : public CallWrapper {
+ public:
+ NullCallWrapper() { }
+ virtual ~NullCallWrapper() { }
+ virtual void BeforeCall(int call_size) const { }
+ virtual void AfterCall() const { }
+};
+
} } // namespace v8::internal
#endif // V8_ASSEMBLER_H_
diff --git a/src/ast-inl.h b/src/ast-inl.h
index d80684a..c2bd613 100644
--- a/src/ast-inl.h
+++ b/src/ast-inl.h
@@ -31,6 +31,7 @@
#include "v8.h"
#include "ast.h"
+#include "scopes.h"
namespace v8 {
namespace internal {
diff --git a/src/char-predicates.h b/src/char-predicates.h
index dac1eb8..5a901a2 100644
--- a/src/char-predicates.h
+++ b/src/char-predicates.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,6 +28,8 @@
#ifndef V8_CHAR_PREDICATES_H_
#define V8_CHAR_PREDICATES_H_
+#include "unicode.h"
+
namespace v8 {
namespace internal {
diff --git a/src/codegen.cc b/src/codegen.cc
index 6d81415..ad3cf1b 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -34,7 +34,6 @@
#include "prettyprinter.h"
#include "rewriter.h"
#include "runtime.h"
-#include "scopeinfo.h"
#include "stub-cache.h"
namespace v8 {
diff --git a/src/compiler.cc b/src/compiler.cc
index 16250af..e9b48cb 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -32,7 +32,6 @@
#include "bootstrapper.h"
#include "codegen.h"
#include "compilation-cache.h"
-#include "data-flow.h"
#include "debug.h"
#include "full-codegen.h"
#include "gdb-jit.h"
diff --git a/src/contexts.h b/src/contexts.h
index e46619e..3b997ab 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -106,7 +106,8 @@
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
V(MAP_CACHE_INDEX, Object, map_cache) \
- V(CONTEXT_DATA_INDEX, Object, data)
+ V(CONTEXT_DATA_INDEX, Object, data) \
+ V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings)
// JSFunctions are pairs (context, function code), sometimes also called
// closures. A Context object is used to represent function contexts and
@@ -236,6 +237,7 @@
OUT_OF_MEMORY_INDEX,
MAP_CACHE_INDEX,
CONTEXT_DATA_INDEX,
+ ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
// Properties from here are treated as weak references by the full GC.
// Scavenge treats them as strong references.
diff --git a/src/conversions.cc b/src/conversions.cc
index 1458584..5cf5efd 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -254,12 +254,12 @@
if (*current == '+') {
// Ignore leading sign; skip following spaces.
++current;
- if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
+ if (current == end) {
return JUNK_STRING_VALUE;
}
} else if (*current == '-') {
++current;
- if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
+ if (current == end) {
return JUNK_STRING_VALUE;
}
negative = true;
diff --git a/src/data-flow.h b/src/data-flow.h
index 76cff88..da92102 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -37,9 +37,6 @@
namespace v8 {
namespace internal {
-// Forward declarations.
-class Node;
-
class BitVector: public ZoneObject {
public:
// Iterator for the elements of this BitVector.
@@ -201,140 +198,6 @@
uint32_t* data_;
};
-
-// An implementation of a sparse set whose elements are drawn from integers
-// in the range [0..universe_size[. It supports constant-time Contains,
-// destructive Add, and destructuve Remove operations and linear-time (in
-// the number of elements) destructive Union.
-class SparseSet: public ZoneObject {
- public:
- // Iterator for sparse set elements. Elements should not be added or
- // removed during iteration.
- class Iterator BASE_EMBEDDED {
- public:
- explicit Iterator(SparseSet* target) : target_(target), current_(0) {
- ASSERT(++target->iterator_count_ > 0);
- }
- ~Iterator() {
- ASSERT(target_->iterator_count_-- > 0);
- }
- bool Done() const { return current_ >= target_->dense_.length(); }
- void Advance() {
- ASSERT(!Done());
- ++current_;
- }
- int Current() {
- ASSERT(!Done());
- return target_->dense_[current_];
- }
-
- private:
- SparseSet* target_;
- int current_;
-
- friend class SparseSet;
- };
-
- explicit SparseSet(int universe_size)
- : dense_(4),
- sparse_(ZONE->NewArray<int>(universe_size)) {
-#ifdef DEBUG
- size_ = universe_size;
- iterator_count_ = 0;
-#endif
- }
-
- bool Contains(int n) const {
- ASSERT(0 <= n && n < size_);
- int dense_index = sparse_[n];
- return (0 <= dense_index) &&
- (dense_index < dense_.length()) &&
- (dense_[dense_index] == n);
- }
-
- void Add(int n) {
- ASSERT(0 <= n && n < size_);
- ASSERT(iterator_count_ == 0);
- if (!Contains(n)) {
- sparse_[n] = dense_.length();
- dense_.Add(n);
- }
- }
-
- void Remove(int n) {
- ASSERT(0 <= n && n < size_);
- ASSERT(iterator_count_ == 0);
- if (Contains(n)) {
- int dense_index = sparse_[n];
- int last = dense_.RemoveLast();
- if (dense_index < dense_.length()) {
- dense_[dense_index] = last;
- sparse_[last] = dense_index;
- }
- }
- }
-
- void Union(const SparseSet& other) {
- for (int i = 0; i < other.dense_.length(); ++i) {
- Add(other.dense_[i]);
- }
- }
-
- private:
- // The set is implemented as a pair of a growable dense list and an
- // uninitialized sparse array.
- ZoneList<int> dense_;
- int* sparse_;
-#ifdef DEBUG
- int size_;
- int iterator_count_;
-#endif
-};
-
-
-// Simple fixed-capacity list-based worklist (managed as a queue) of
-// pointers to T.
-template<typename T>
-class WorkList BASE_EMBEDDED {
- public:
- // The worklist cannot grow bigger than size. We keep one item empty to
- // distinguish between empty and full.
- explicit WorkList(int size)
- : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
- for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
- }
-
- bool is_empty() { return head_ == tail_; }
-
- bool is_full() {
- // The worklist is full if head is at 0 and tail is at capacity - 1:
- // head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
- // or if tail is immediately to the left of head:
- // tail+1 == head ==> tail - head == -1
- int diff = tail_ - head_;
- return (diff == -1 || diff == capacity_ - 1);
- }
-
- void Insert(T* item) {
- ASSERT(!is_full());
- queue_[tail_++] = item;
- if (tail_ == capacity_) tail_ = 0;
- }
-
- T* Remove() {
- ASSERT(!is_empty());
- T* item = queue_[head_++];
- if (head_ == capacity_) head_ = 0;
- return item;
- }
-
- private:
- int capacity_; // Including one empty slot.
- int head_; // Where the first item is.
- int tail_; // Where the next inserted item will go.
- List<T*> queue_;
-};
-
} } // namespace v8::internal
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index bc0f966..908fcd2 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -1335,7 +1335,7 @@
try {
try {
// Convert the JSON string to an object.
- request = %CompileString('(' + json_request + ')')();
+ request = JSON.parse(json_request);
// Create an initial response.
response = this.createResponse(request);
diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc
index c094251..ebac4b9 100644
--- a/src/func-name-inferrer.cc
+++ b/src/func-name-inferrer.cc
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,6 +29,7 @@
#include "ast.h"
#include "func-name-inferrer.h"
+#include "list-inl.h"
namespace v8 {
namespace internal {
diff --git a/src/global-handles.h b/src/global-handles.h
index 2171b2c..c89a2aa 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -30,7 +30,7 @@
#include "../include/v8-profiler.h"
-#include "list-inl.h"
+#include "list.h"
namespace v8 {
namespace internal {
diff --git a/src/hashmap.h b/src/hashmap.h
index bb3e3ce..5c13212 100644
--- a/src/hashmap.h
+++ b/src/hashmap.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,6 +28,8 @@
#ifndef V8_HASHMAP_H_
#define V8_HASHMAP_H_
+#include "allocation.h"
+
namespace v8 {
namespace internal {
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 99737ed..44faf75 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,8 +29,9 @@
#define V8_HEAP_INL_H_
#include "heap.h"
-#include "objects.h"
#include "isolate.h"
+#include "list-inl.h"
+#include "objects.h"
#include "v8-counters.h"
namespace v8 {
diff --git a/src/heap.cc b/src/heap.cc
index ac00c01..64489a1 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -33,8 +33,8 @@
#include "codegen.h"
#include "compilation-cache.h"
#include "debug.h"
-#include "heap-profiler.h"
#include "global-handles.h"
+#include "heap-profiler.h"
#include "liveobjectlist-inl.h"
#include "mark-compact.h"
#include "natives.h"
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 4fb7fec..82fdfa7 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -31,6 +31,7 @@
#include "v8.h"
#include "code-stubs.h"
+#include "data-flow.h"
#include "small-pointer-list.h"
#include "string-stream.h"
#include "zone.h"
@@ -554,6 +555,8 @@
representation_ = r;
}
+ virtual bool IsConvertibleToInteger() const { return true; }
+
HType type() const { return type_; }
void set_type(HType type) {
ASSERT(HasNoUses());
@@ -1922,7 +1925,8 @@
: inputs_(2),
merged_index_(merged_index),
phi_id_(-1),
- is_live_(false) {
+ is_live_(false),
+ is_convertible_to_integer_(true) {
for (int i = 0; i < Representation::kNumRepresentations; i++) {
non_phi_uses_[i] = 0;
indirect_uses_[i] = 0;
@@ -2000,6 +2004,14 @@
}
virtual Opcode opcode() const { return HValue::kPhi; }
+ virtual bool IsConvertibleToInteger() const {
+ return is_convertible_to_integer_;
+ }
+
+ void set_is_convertible_to_integer(bool b) {
+ is_convertible_to_integer_ = b;
+ }
+
protected:
virtual void DeleteFromGraph();
virtual void InternalSetOperandAt(int index, HValue* value) {
@@ -2014,6 +2026,7 @@
int indirect_uses_[Representation::kNumRepresentations];
int phi_id_;
bool is_live_;
+ bool is_convertible_to_integer_;
};
@@ -2044,6 +2057,14 @@
return Representation::None();
}
+ virtual bool IsConvertibleToInteger() const {
+ if (handle_->IsSmi()) return true;
+ if (handle_->IsHeapNumber() &&
+ (HeapNumber::cast(*handle_)->value() ==
+ static_cast<double>(NumberToInt32(*handle_)))) return true;
+ return false;
+ }
+
virtual bool EmitAtUses() { return !representation().IsDouble(); }
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 67ff14d..3b57f9f 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -29,7 +29,6 @@
#include "hydrogen.h"
#include "codegen.h"
-#include "data-flow.h"
#include "full-codegen.h"
#include "hashmap.h"
#include "lithium-allocator.h"
@@ -1575,14 +1574,12 @@
}
if (non_tagged_count >= tagged_count) {
- // More untagged than tagged.
- if (double_count > 0) {
- // There is at least one usage that is a double => guess that the
- // correct representation is double.
- return Representation::Double();
- } else if (int32_count > 0) {
- return Representation::Integer32();
+ if (int32_count > 0) {
+ if (!value->IsPhi() || value->IsConvertibleToInteger()) {
+ return Representation::Integer32();
+ }
}
+ if (double_count > 0) return Representation::Double();
}
return Representation::None();
}
@@ -1595,11 +1592,12 @@
// bit-vector of length <number of phis>.
const ZoneList<HPhi*>* phi_list = graph_->phi_list();
int phi_count = phi_list->length();
- ScopedVector<BitVector*> connected_phis(phi_count);
+ ZoneList<BitVector*> connected_phis(phi_count);
for (int i = 0; i < phi_count; ++i) {
phi_list->at(i)->InitRealUses(i);
- connected_phis[i] = new(zone()) BitVector(phi_count);
- connected_phis[i]->Add(i);
+ BitVector* connected_set = new(zone()) BitVector(phi_count);
+ connected_set->Add(i);
+ connected_phis.Add(connected_set);
}
// (2) Do a fixed point iteration to find the set of connected phis. A
@@ -1636,6 +1634,25 @@
}
}
+ // (4) Compute phis that definitely can't be converted to integer
+ // without deoptimization and mark them to avoid unnecessary deoptimization.
+ change = true;
+ while (change) {
+ change = false;
+ for (int i = 0; i < phi_count; ++i) {
+ HPhi* phi = phi_list->at(i);
+ for (int j = 0; j < phi->OperandCount(); ++j) {
+ if (phi->IsConvertibleToInteger() &&
+ !phi->OperandAt(j)->IsConvertibleToInteger()) {
+ phi->set_is_convertible_to_integer(false);
+ change = true;
+ break;
+ }
+ }
+ }
+ }
+
+
for (int i = 0; i < graph_->blocks()->length(); ++i) {
HBasicBlock* block = graph_->blocks()->at(i);
const ZoneList<HPhi*>* phis = block->phis();
diff --git a/src/hydrogen.h b/src/hydrogen.h
index f65386f..22b82d7 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -32,7 +32,6 @@
#include "ast.h"
#include "compiler.h"
-#include "data-flow.h"
#include "hydrogen-instructions.h"
#include "zone.h"
@@ -40,6 +39,7 @@
namespace internal {
// Forward declarations.
+class BitVector;
class HEnvironment;
class HGraph;
class HLoopInformation;
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index a91b0c4..043eb2e 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -32,7 +32,7 @@
// The original source code covered by the above license above has been modified
// significantly by Google Inc.
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
#include "v8.h"
@@ -1580,12 +1580,24 @@
}
+int Assembler::CallSize(const Operand& adr) {
+ // Call size is 1 (opcode) + adr.len_ (operand).
+ return 1 + adr.len_;
+}
+
+
void Assembler::call(const Operand& adr) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0xFF);
emit_operand(edx, adr);
+ ASSERT(pc_ - last_pc_ == CallSize(adr));
+}
+
+
+int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
+ return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
}
@@ -2246,6 +2258,15 @@
}
+void Assembler::xorps(XMMRegister dst, XMMRegister src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0x0F);
+ EMIT(0x57);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 86ce8a6..af41cb5 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -847,7 +847,9 @@
// Calls
void call(Label* L);
void call(byte* entry, RelocInfo::Mode rmode);
+ int CallSize(const Operand& adr);
void call(const Operand& adr);
+ int CallSize(Handle<Code> code, RelocInfo::Mode mode);
void call(Handle<Code> code,
RelocInfo::Mode rmode,
unsigned ast_id = kNoASTId);
@@ -952,6 +954,7 @@
void mulsd(XMMRegister dst, XMMRegister src);
void divsd(XMMRegister dst, XMMRegister src);
void xorpd(XMMRegister dst, XMMRegister src);
+ void xorps(XMMRegister dst, XMMRegister src);
void sqrtsd(XMMRegister dst, XMMRegister src);
void andpd(XMMRegister dst, XMMRegister src);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 777924b..7af000a 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -2880,7 +2880,7 @@
// Calculates reciprocal of square root.
// sqrtsd returns -0 when input is -0. ECMA spec requires +0.
- __ xorpd(xmm1, xmm1);
+ __ xorps(xmm1, xmm1);
__ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
__ divsd(xmm3, xmm1);
@@ -2897,7 +2897,7 @@
__ j(not_equal, &call_runtime);
// Calculates square root.
// sqrtsd returns -0 when input is -0. ECMA spec requires +0.
- __ xorpd(xmm1, xmm1);
+ __ xorps(xmm1, xmm1);
__ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index d1c869a..7a59a4f 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -981,6 +981,14 @@
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (f0byte == 0x57) {
+ data += 2;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("xorps %s,%s",
+ NameOfXMMRegister(regop),
+ NameOfXMMRegister(rm));
+ data++;
} else if ((f0byte & 0xF0) == 0x80) {
data += JumpConditional(data, branch_hint);
} else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 7d3dea2..c46a869 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2794,7 +2794,7 @@
__ movd(xmm1, Operand(ebx));
__ movd(xmm0, Operand(eax));
__ cvtss2sd(xmm1, xmm1);
- __ pxor(xmm0, xmm1);
+ __ xorps(xmm0, xmm1);
__ subsd(xmm0, xmm1);
__ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
} else {
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 07ee7d6..25138df 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -40,7 +40,7 @@
// When invoking builtins, we need to record the safepoint in the middle of
// the invoke instruction sequence generated by the macro assembler.
-class SafepointGenerator : public PostCallGenerator {
+class SafepointGenerator : public CallWrapper {
public:
SafepointGenerator(LCodeGen* codegen,
LPointerMap* pointers,
@@ -50,7 +50,9 @@
deoptimization_index_(deoptimization_index) {}
virtual ~SafepointGenerator() { }
- virtual void Generate() {
+ virtual void BeforeCall(int call_size) const {}
+
+ virtual void AfterCall() const {
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
@@ -1137,7 +1139,7 @@
// Use xor to produce +0.0 in a fast and compact way, but avoid to
// do so if the constant is -0.0.
if (BitCast<uint64_t, double>(v) == 0) {
- __ xorpd(res, res);
+ __ xorps(res, res);
} else {
Register temp = ToRegister(instr->TempAt(0));
uint64_t int_val = BitCast<uint64_t, double>(v);
@@ -1151,7 +1153,7 @@
__ Set(temp, Immediate(upper));
__ pinsrd(res, Operand(temp), 1);
} else {
- __ xorpd(res, res);
+ __ xorps(res, res);
__ Set(temp, Immediate(upper));
__ pinsrd(res, Operand(temp), 1);
}
@@ -1341,7 +1343,7 @@
EmitBranch(true_block, false_block, not_zero);
} else if (r.IsDouble()) {
XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
- __ xorpd(xmm0, xmm0);
+ __ xorps(xmm0, xmm0);
__ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal);
} else {
@@ -2550,7 +2552,7 @@
pointers,
env->deoptimization_index());
ParameterCount actual(eax);
- __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
}
@@ -2718,7 +2720,7 @@
if (r.IsDouble()) {
XMMRegister scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
- __ pxor(scratch, scratch);
+ __ xorps(scratch, scratch);
__ subsd(scratch, input_reg);
__ pand(input_reg, scratch);
} else if (r.IsInteger32()) {
@@ -2740,7 +2742,7 @@
XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
- __ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
+ __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
@@ -2816,7 +2818,7 @@
XMMRegister xmm_scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
- __ xorpd(xmm_scratch, xmm_scratch);
+ __ xorps(xmm_scratch, xmm_scratch);
__ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
__ sqrtsd(input_reg, input_reg);
}
@@ -2886,7 +2888,7 @@
ASSERT(instr->InputAt(0)->Equals(instr->result()));
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
NearLabel positive, done, zero, negative;
- __ xorpd(xmm0, xmm0);
+ __ xorps(xmm0, xmm0);
__ ucomisd(input_reg, xmm0);
__ j(above, &positive);
__ j(equal, &zero);
@@ -2972,7 +2974,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers, env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(edi, count, CALL_FUNCTION, &generator);
+ __ InvokeFunction(edi, count, CALL_FUNCTION, generator);
}
@@ -4235,7 +4237,7 @@
env->deoptimization_index());
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
- __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
}
@@ -4295,7 +4297,7 @@
pointers,
env->deoptimization_index());
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
- __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
}
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 0c24fc4..f13585d 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1435,7 +1435,7 @@
const Operand& code_operand,
NearLabel* done,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
bool definitely_matches = false;
Label invoke;
if (expected.is_immediate()) {
@@ -1485,8 +1485,9 @@
}
if (flag == CALL_FUNCTION) {
+ call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
call(adaptor, RelocInfo::CODE_TARGET);
- if (post_call_generator != NULL) post_call_generator->Generate();
+ call_wrapper.AfterCall();
jmp(done);
} else {
jmp(adaptor, RelocInfo::CODE_TARGET);
@@ -1500,13 +1501,14 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
NearLabel done;
InvokePrologue(expected, actual, Handle<Code>::null(), code,
- &done, flag, post_call_generator);
+ &done, flag, call_wrapper);
if (flag == CALL_FUNCTION) {
+ call_wrapper.BeforeCall(CallSize(code));
call(code);
- if (post_call_generator != NULL) post_call_generator->Generate();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
jmp(code);
@@ -1520,14 +1522,14 @@
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
NearLabel done;
Operand dummy(eax);
- InvokePrologue(expected, actual, code, dummy, &done,
- flag, post_call_generator);
+ InvokePrologue(expected, actual, code, dummy, &done, flag, call_wrapper);
if (flag == CALL_FUNCTION) {
+ call_wrapper.BeforeCall(CallSize(code, rmode));
call(code, rmode);
- if (post_call_generator != NULL) post_call_generator->Generate();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
jmp(code, rmode);
@@ -1539,7 +1541,7 @@
void MacroAssembler::InvokeFunction(Register fun,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
ASSERT(fun.is(edi));
mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
@@ -1548,14 +1550,14 @@
ParameterCount expected(ebx);
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
- expected, actual, flag, post_call_generator);
+ expected, actual, flag, call_wrapper);
}
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
mov(edi, Immediate(Handle<JSFunction>(function)));
@@ -1567,18 +1569,18 @@
// code field in the function to allow recompilation to take effect
// without changing any of the call sites.
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
- expected, actual, flag, post_call_generator);
+ expected, actual, flag, call_wrapper);
} else {
Handle<Code> code(function->code());
InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET,
- flag, post_call_generator);
+ flag, call_wrapper);
}
}
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
// Calls are not allowed in some stubs.
ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
@@ -1588,7 +1590,7 @@
ParameterCount expected(0);
GetBuiltinFunction(edi, id);
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
- expected, expected, flag, post_call_generator);
+ expected, expected, flag, call_wrapper);
}
void MacroAssembler::GetBuiltinFunction(Register target,
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index f1666ba..ee8c0c7 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -49,9 +49,6 @@
// distinguish memory operands from other operands on ia32.
typedef Operand MemOperand;
-// Forward declaration.
-class PostCallGenerator;
-
// MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler {
public:
@@ -160,32 +157,32 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Store the function for the given builtin in the target register.
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
@@ -652,7 +649,7 @@
const Operand& code_operand,
NearLabel* done,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Activation support.
void EnterFrame(StackFrame::Type type);
@@ -734,17 +731,6 @@
};
-// Helper class for generating code or data associated with the code
-// right after a call instruction. As an example this can be used to
-// generate safepoint data after calls for crankshaft.
-class PostCallGenerator {
- public:
- PostCallGenerator() { }
- virtual ~PostCallGenerator() { }
- virtual void Generate() = 0;
-};
-
-
// -----------------------------------------------------------------------------
// Static helper functions.
diff --git a/src/isolate.h b/src/isolate.h
index 52c7145..44190c2 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -345,6 +345,7 @@
/* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \
V(byte*, assembler_spare_buffer, NULL) \
V(FatalErrorCallback, exception_behavior, NULL) \
+ V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL) \
V(v8::Debug::MessageHandler, message_handler, NULL) \
/* To distinguish the function templates, so that we can find them in the */ \
/* function cache of the global context. */ \
diff --git a/src/list.h b/src/list.h
index ccb095c..ef79557 100644
--- a/src/list.h
+++ b/src/list.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,6 +28,8 @@
#ifndef V8_LIST_H_
#define V8_LIST_H_
+#include "utils.h"
+
namespace v8 {
namespace internal {
diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
index f109c45..7fff294 100644
--- a/src/lithium-allocator.h
+++ b/src/lithium-allocator.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -30,7 +30,6 @@
#include "v8.h"
-#include "data-flow.h"
#include "lithium.h"
#include "zone.h"
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 8488170..3754fa2 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -30,8 +30,8 @@
#include "liveedit.h"
-#include "compiler.h"
#include "compilation-cache.h"
+#include "compiler.h"
#include "debug.h"
#include "deoptimizer.h"
#include "global-handles.h"
diff --git a/src/messages.js b/src/messages.js
index e657fc0..fdeae7d 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -142,6 +142,7 @@
kMessages = {
// Error
cyclic_proto: ["Cyclic __proto__ value"],
+ code_gen_from_strings: ["Code generation from strings disallowed for this context"],
// TypeError
unexpected_token: ["Unexpected token ", "%0"],
unexpected_token_number: ["Unexpected number"],
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 1d7752d..f24ed6f 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -1658,6 +1658,18 @@
}
+int MacroAssembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
+ UNIMPLEMENTED_MIPS();
+ return 0;
+}
+
+
+int MacroAssembler::CallSize(Register reg) {
+ UNIMPLEMENTED_MIPS();
+ return 0;
+}
+
+
// Note: To call gcc-compiled C code on mips, you must call thru t9.
void MacroAssembler::Call(const Operand& target, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
@@ -2243,7 +2255,7 @@
Register code_reg,
Label* done,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
bool definitely_matches = false;
Label regular_invoke;
@@ -2296,8 +2308,9 @@
Handle<Code> adaptor =
isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (flag == CALL_FUNCTION) {
+ call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
Call(adaptor, RelocInfo::CODE_TARGET);
- if (post_call_generator != NULL) post_call_generator->Generate();
+ call_wrapper.AfterCall();
jmp(done);
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
@@ -2311,11 +2324,11 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
Label done;
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag,
- post_call_generator);
+ call_wrapper);
if (flag == CALL_FUNCTION) {
Call(code);
} else {
@@ -2350,7 +2363,7 @@
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
// Contract with called JS functions requires that function is passed in a1.
ASSERT(function.is(a1));
Register expected_reg = a2;
@@ -2365,7 +2378,7 @@
lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg);
- InvokeCode(code_reg, expected, actual, flag, post_call_generator);
+ InvokeCode(code_reg, expected, actual, flag, call_wrapper);
}
@@ -2642,11 +2655,12 @@
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- PostCallGenerator* post_call_generator) {
+ const CallWrapper& call_wrapper) {
GetBuiltinEntry(t9, id);
if (flag == CALL_FUNCTION) {
+ call_wrapper.BeforeCall(CallSize(t9));
Call(t9);
- if (post_call_generator != NULL) post_call_generator->Generate();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
Jump(t9);
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 49adbb1..266ef71 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -36,7 +36,6 @@
// Forward declaration.
class JumpTarget;
-class PostCallGenerator;
// Reserved Register Usage Summary.
//
@@ -588,7 +587,7 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
@@ -601,7 +600,7 @@
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
@@ -771,7 +770,7 @@
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Store the code object for the given builtin in the target register and
// setup the function in a1.
@@ -954,7 +953,7 @@
Register code_reg,
Label* done,
InvokeFlag flag,
- PostCallGenerator* post_call_generator = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Get the code for the given builtin. Returns if able to resolve
// the function in the 'resolved' flag.
@@ -1007,17 +1006,6 @@
#endif // ENABLE_DEBUGGER_SUPPORT
-// Helper class for generating code or data associated with the code
-// right after a call instruction. As an example this can be used to
-// generate safepoint data after calls for crankshaft.
-class PostCallGenerator {
- public:
- PostCallGenerator() { }
- virtual ~PostCallGenerator() { }
- virtual void Generate() = 0;
-};
-
-
// -----------------------------------------------------------------------------
// Static helper functions.
diff --git a/src/objects.cc b/src/objects.cc
index 7c2097f..f42be65 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -41,7 +41,6 @@
#include "macro-assembler.h"
#include "safepoint-table.h"
#include "scanner-base.h"
-#include "scopeinfo.h"
#include "string-stream.h"
#include "utils.h"
#include "vm-state-inl.h"
diff --git a/src/parser.cc b/src/parser.cc
index 14eb534..f983437 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -28,7 +28,7 @@
#include "v8.h"
#include "api.h"
-#include "ast.h"
+#include "ast-inl.h"
#include "bootstrapper.h"
#include "codegen.h"
#include "compiler.h"
@@ -41,8 +41,6 @@
#include "scopeinfo.h"
#include "string-stream.h"
-#include "ast-inl.h"
-
namespace v8 {
namespace internal {
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index db6c80ed..606e607 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -110,14 +110,7 @@
uint64_t OS::CpuFeaturesImpliedByPlatform() {
-#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
- // Here gcc is telling us that we are on an ARM and gcc is assuming
- // that we have VFP3 instructions. If gcc can assume it then so can
- // we. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
- return 1u << VFP3 | 1u << ARMv7;
-#elif CAN_USE_ARMV7_INSTRUCTIONS
- return 1u << ARMv7;
-#elif(defined(__mips_hard_float) && __mips_hard_float != 0)
+#if(defined(__mips_hard_float) && __mips_hard_float != 0)
// Here gcc is telling us that we are on an MIPS and gcc is assuming that we
// have FPU instructions. If gcc can assume it then so can we.
return 1u << FPU;
diff --git a/src/preparse-data.cc b/src/preparse-data.cc
index 92a0338..5cb0a88 100644
--- a/src/preparse-data.cc
+++ b/src/preparse-data.cc
@@ -26,15 +26,12 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/v8stdint.h"
-#include "globals.h"
-#include "checks.h"
-#include "allocation.h"
-#include "utils.h"
-#include "list-inl.h"
-#include "hashmap.h"
#include "preparse-data.h"
+#include "checks.h"
+#include "globals.h"
+#include "hashmap.h"
namespace v8 {
namespace internal {
diff --git a/src/preparse-data.h b/src/preparse-data.h
index bb5707b..e12203a 100644
--- a/src/preparse-data.h
+++ b/src/preparse-data.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,6 +29,7 @@
#define V8_PREPARSER_DATA_H_
#include "hashmap.h"
+#include "utils-inl.h"
namespace v8 {
namespace internal {
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 4cf62e2..099977c 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,14 +28,15 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
#include "v8.h"
+
+#include "profile-generator-inl.h"
+
#include "global-handles.h"
#include "heap-profiler.h"
#include "scopeinfo.h"
#include "unicode.h"
#include "zone-inl.h"
-#include "profile-generator-inl.h"
-
namespace v8 {
namespace internal {
diff --git a/src/runtime.cc b/src/runtime.cc
index 44fe646..6738213 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -46,13 +46,14 @@
#include "liveobjectlist-inl.h"
#include "parser.h"
#include "platform.h"
-#include "runtime.h"
#include "runtime-profiler.h"
+#include "runtime.h"
#include "scopeinfo.h"
#include "smart-pointer.h"
+#include "string-search.h"
#include "stub-cache.h"
#include "v8threads.h"
-#include "string-search.h"
+#include "vm-state-inl.h"
namespace v8 {
namespace internal {
@@ -8285,13 +8286,41 @@
}
+bool CodeGenerationFromStringsAllowed(Isolate* isolate,
+ Handle<Context> context) {
+ if (context->allow_code_gen_from_strings()->IsFalse()) {
+ // Check with callback if set.
+ AllowCodeGenerationFromStringsCallback callback =
+ isolate->allow_code_gen_callback();
+ if (callback == NULL) {
+ // No callback set and code generation disallowed.
+ return false;
+ } else {
+ // Callback set. Let it decide if code generation is allowed.
+ VMState state(isolate, EXTERNAL);
+ return callback(v8::Utils::ToLocal(context));
+ }
+ }
+ return true;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
HandleScope scope(isolate);
ASSERT_EQ(1, args.length());
CONVERT_ARG_CHECKED(String, source, 0);
- // Compile source string in the global context.
+ // Extract global context.
Handle<Context> context(isolate->context()->global_context());
+
+ // Check if global context allows code generation from
+ // strings. Throw an exception if it doesn't.
+ if (!CodeGenerationFromStringsAllowed(isolate, context)) {
+ return isolate->Throw(*isolate->factory()->NewError(
+ "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ }
+
+ // Compile source string in the global context.
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
context,
true,
@@ -8309,17 +8338,28 @@
Handle<String> source,
Handle<Object> receiver,
StrictModeFlag strict_mode) {
+ Handle<Context> context = Handle<Context>(isolate->context());
+ Handle<Context> global_context = Handle<Context>(context->global_context());
+
+ // Check if global context allows code generation from
+ // strings. Throw an exception if it doesn't.
+ if (!CodeGenerationFromStringsAllowed(isolate, global_context)) {
+ isolate->Throw(*isolate->factory()->NewError(
+ "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ return MakePair(Failure::Exception(), NULL);
+ }
+
// Deal with a normal eval call with a string argument. Compile it
// and return the compiled function bound in the local context.
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
source,
Handle<Context>(isolate->context()),
- isolate->context()->IsGlobalContext(),
+ context->IsGlobalContext(),
strict_mode);
if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
Handle<JSFunction> compiled =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
- shared, Handle<Context>(isolate->context()), NOT_TENURED);
+ shared, context, NOT_TENURED);
return MakePair(*compiled, *receiver);
}
diff --git a/src/runtime.js b/src/runtime.js
index 66d839b..4f53efe 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -49,41 +49,47 @@
const $Boolean = global.Boolean;
const $NaN = 0/0;
-
-// ECMA-262, section 11.9.1, page 55.
+// ECMA-262 Section 11.9.3.
function EQUALS(y) {
if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y);
var x = this;
- // NOTE: We use iteration instead of recursion, because it is
- // difficult to call EQUALS with the correct setting of 'this' in
- // an efficient way.
while (true) {
if (IS_NUMBER(x)) {
- if (y == null) return 1; // not equal
- return %NumberEquals(x, %ToNumber(y));
- } else if (IS_STRING(x)) {
- if (IS_STRING(y)) return %StringEquals(x, y);
- if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
- if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
- if (y == null) return 1; // not equal
- y = %ToPrimitive(y, NO_HINT);
- } else if (IS_BOOLEAN(x)) {
- if (IS_BOOLEAN(y)) {
- return %_ObjectEquals(x, y) ? 0 : 1;
+ while (true) {
+ if (IS_NUMBER(y)) return %NumberEquals(x, y);
+ if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
+ if (!IS_SPEC_OBJECT(y)) {
+ // String or boolean.
+ return %NumberEquals(x, %ToNumber(y));
+ }
+ y = %ToPrimitive(y, NO_HINT);
}
- if (y == null) return 1; // not equal
- return %NumberEquals(%ToNumber(x), %ToNumber(y));
- } else if (x == null) {
- // NOTE: This checks for both null and undefined.
- return (y == null) ? 0 : 1;
+ } else if (IS_STRING(x)) {
+ while (true) {
+ if (IS_STRING(y)) return %StringEquals(x, y);
+ if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
+ if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
+ if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
+ y = %ToPrimitive(y, NO_HINT);
+ }
+ } else if (IS_BOOLEAN(x)) {
+ if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
+ if (IS_NULL_OR_UNDEFINED(y)) return 1;
+ if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
+ if (IS_STRING(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
+ // y is object.
+ x = %ToNumber(x);
+ y = %ToPrimitive(y, NO_HINT);
+ } else if (IS_NULL_OR_UNDEFINED(x)) {
+ return IS_NULL_OR_UNDEFINED(y) ? 0 : 1;
} else {
- // x is not a number, boolean, null or undefined.
- if (y == null) return 1; // not equal
+ // x is an object.
if (IS_SPEC_OBJECT(y)) {
return %_ObjectEquals(x, y) ? 0 : 1;
}
-
+ if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
+ if (IS_BOOLEAN(y)) y = %ToNumber(y);
x = %ToPrimitive(x, NO_HINT);
}
}
diff --git a/src/scanner-base.h b/src/scanner-base.h
index 60b97d2..a2fbd82 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -30,14 +30,13 @@
#ifndef V8_SCANNER_BASE_H_
#define V8_SCANNER_BASE_H_
-#include "globals.h"
-#include "checks.h"
#include "allocation.h"
+#include "char-predicates.h"
+#include "checks.h"
+#include "globals.h"
#include "token.h"
#include "unicode-inl.h"
-#include "char-predicates.h"
#include "utils.h"
-#include "list-inl.h"
namespace v8 {
namespace internal {
diff --git a/src/serialize.cc b/src/serialize.cc
index 12e9613..a64fba3 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,6 +29,7 @@
#include "accessors.h"
#include "api.h"
+#include "bootstrapper.h"
#include "execution.h"
#include "global-handles.h"
#include "ic-inl.h"
@@ -38,7 +39,6 @@
#include "serialize.h"
#include "stub-cache.h"
#include "v8threads.h"
-#include "bootstrapper.h"
namespace v8 {
namespace internal {
diff --git a/src/spaces.h b/src/spaces.h
index bd939d1..8269ea6 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,7 +28,7 @@
#ifndef V8_SPACES_H_
#define V8_SPACES_H_
-#include "list-inl.h"
+#include "list.h"
#include "log.h"
namespace v8 {
diff --git a/src/utils-inl.h b/src/utils-inl.h
new file mode 100644
index 0000000..76a3c10
--- /dev/null
+++ b/src/utils-inl.h
@@ -0,0 +1,48 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_UTILS_INL_H_
+#define V8_UTILS_INL_H_
+
+#include "list-inl.h"
+
+namespace v8 {
+namespace internal {
+
+template<typename T, int growth_factor, int max_growth>
+void Collector<T, growth_factor, max_growth>::Reset() {
+ for (int i = chunks_.length() - 1; i >= 0; i--) {
+ chunks_.at(i).Dispose();
+ }
+ chunks_.Rewind(0);
+ index_ = 0;
+ size_ = 0;
+}
+
+} } // namespace v8::internal
+
+#endif // V8_UTILS_INL_H_
diff --git a/src/utils.h b/src/utils.h
index 6f89766..e2ce7d6 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -582,14 +582,7 @@
}
// Resets the collector to be empty.
- virtual void Reset() {
- for (int i = chunks_.length() - 1; i >= 0; i--) {
- chunks_.at(i).Dispose();
- }
- chunks_.Rewind(0);
- index_ = 0;
- size_ = 0;
- }
+ virtual void Reset();
// Total number of elements added to collector so far.
inline int size() { return size_; }
diff --git a/src/v8dll-main.cc b/src/v8dll-main.cc
index 3d4b3a3..49d8689 100644
--- a/src/v8dll-main.cc
+++ b/src/v8dll-main.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,10 +25,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <windows.h>
-
+// The GYP based build ends up defining USING_V8_SHARED when compiling this
+// file.
+#undef USING_V8_SHARED
#include "../include/v8.h"
+#ifdef WIN32
+#include <windows.h> // NOLINT
+
extern "C" {
BOOL WINAPI DllMain(HANDLE hinstDLL,
DWORD dwReason,
@@ -37,3 +41,4 @@
return TRUE;
}
}
+#endif
diff --git a/src/version.cc b/src/version.cc
index 71add0f..168f779 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 3
-#define BUILD_NUMBER 3
+#define BUILD_NUMBER 4
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 7764033..5b45b13 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -49,7 +49,7 @@
deoptimization_index_(deoptimization_index) { }
virtual ~SafepointGenerator() { }
- virtual void BeforeCall(int call_size) {
+ virtual void BeforeCall(int call_size) const {
ASSERT(call_size >= 0);
// Ensure that we have enough space after the previous safepoint position
// for the jump generated there.
@@ -62,7 +62,7 @@
}
}
- virtual void AfterCall() {
+ virtual void AfterCall() const {
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
@@ -2562,7 +2562,7 @@
pointers,
env->deoptimization_index());
v8::internal::ParameterCount actual(rax);
- __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
@@ -2969,7 +2969,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers, env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(rdi, count, CALL_FUNCTION, &generator);
+ __ InvokeFunction(rdi, count, CALL_FUNCTION, generator);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
@@ -3597,7 +3597,7 @@
__ cvttsd2siq(result_reg, input_reg);
__ movq(kScratchRegister, V8_INT64_C(0x8000000000000000), RelocInfo::NONE);
__ cmpq(result_reg, kScratchRegister);
- DeoptimizeIf(equal, instr->environment());
+ DeoptimizeIf(equal, instr->environment());
} else {
__ cvttsd2si(result_reg, input_reg);
__ cvtlsi2sd(xmm0, result_reg);
@@ -4046,7 +4046,7 @@
pointers,
env->deoptimization_index());
__ Push(Smi::FromInt(strict_mode_flag()));
- __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
}
@@ -4066,7 +4066,7 @@
SafepointGenerator safepoint_generator(this,
pointers,
env->deoptimization_index());
- __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
+ __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
}
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 24f2fef..5cf959f 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -755,7 +755,7 @@
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
// Calls are not allowed in some stubs.
ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
@@ -2056,7 +2056,7 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
NearLabel done;
InvokePrologue(expected,
actual,
@@ -2066,9 +2066,9 @@
flag,
call_wrapper);
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
+ call_wrapper.BeforeCall(CallSize(code));
call(code);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
jmp(code);
@@ -2082,7 +2082,7 @@
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
NearLabel done;
Register dummy = rax;
InvokePrologue(expected,
@@ -2093,9 +2093,9 @@
flag,
call_wrapper);
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
+ call_wrapper.BeforeCall(CallSize(code));
Call(code, rmode);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
Jump(code, rmode);
@@ -2107,7 +2107,7 @@
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
ASSERT(function.is(rdi));
movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
movq(rsi, FieldOperand(function, JSFunction::kContextOffset));
@@ -2125,7 +2125,7 @@
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
Move(rdi, Handle<JSFunction>(function));
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 8499edf..400bdce 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -61,7 +61,6 @@
// Forward declaration.
class JumpTarget;
-class CallWrapper;
struct SmiIndex {
SmiIndex(Register index_register, ScaleFactor scale)
@@ -245,32 +244,32 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
- CallWrapper* call_wrapper = NULL);
+ const CallWrapper& call_wrapper = NullCallWrapper());
// Store the function for the given builtin in the target register.
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
@@ -1127,7 +1126,7 @@
Register code_register,
LabelType* done,
InvokeFlag flag,
- CallWrapper* call_wrapper);
+ const CallWrapper& call_wrapper);
// Activation support.
void EnterFrame(StackFrame::Type type);
@@ -1192,21 +1191,6 @@
};
-// Helper class for generating code or data associated with the code
-// right before or after a call instruction. As an example this can be used to
-// generate safepoint data after calls for crankshaft.
-class CallWrapper {
- public:
- CallWrapper() { }
- virtual ~CallWrapper() { }
- // Called just before emitting a call. Argument is the size of the generated
- // call code.
- virtual void BeforeCall(int call_size) = 0;
- // Called just after emitting a call, i.e., at the return site for the call.
- virtual void AfterCall() = 0;
-};
-
-
// -----------------------------------------------------------------------------
// Static helper functions.
@@ -1952,7 +1936,7 @@
Register code_register,
LabelType* done,
InvokeFlag flag,
- CallWrapper* call_wrapper) {
+ const CallWrapper& call_wrapper) {
bool definitely_matches = false;
NearLabel invoke;
if (expected.is_immediate()) {
@@ -2001,9 +1985,9 @@
}
if (flag == CALL_FUNCTION) {
- if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(adaptor));
+ call_wrapper.BeforeCall(CallSize(adaptor));
Call(adaptor, RelocInfo::CODE_TARGET);
- if (call_wrapper != NULL) call_wrapper->AfterCall();
+ call_wrapper.AfterCall();
jmp(done);
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index a228a6f..e2a7fb1 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1050,8 +1050,10 @@
v8::HandleScope scope;
LocalContext env;
double PI = 3.1415926;
- Local<Value> date_obj = v8::Date::New(PI);
- CHECK_EQ(3.0, date_obj->NumberValue());
+ Local<Value> date = v8::Date::New(PI);
+ CHECK_EQ(3.0, date->NumberValue());
+ date.As<v8::Date>()->Set(v8_str("property"), v8::Integer::New(42));
+ CHECK_EQ(42, date.As<v8::Date>()->Get(v8_str("property"))->Int32Value());
}
@@ -13740,6 +13742,11 @@
context->Global()->Set(v8_str("re"), re);
ExpectTrue("re.test('FoobarbaZ')");
+ // RegExps are objects on which you can set properties.
+ re->Set(v8_str("property"), v8::Integer::New(32));
+ v8::Handle<v8::Value> value = CompileRun("re.property");
+ ASSERT_EQ(32, value->Int32Value());
+
v8::TryCatch try_catch;
re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
CHECK(re.IsEmpty());
@@ -14023,3 +14030,77 @@
CHECK(instance->HasOwnProperty(v8_str("bar")));
}
}
+
+
+void CheckCodeGenerationAllowed() {
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK_EQ(42, result->Int32Value());
+ result = CompileRun("(function(e) { return e('42'); })(eval)");
+ CHECK_EQ(42, result->Int32Value());
+ result = CompileRun("execScript('42')");
+ CHECK(!result.IsEmpty());
+ result = CompileRun("var f = new Function('return 42'); f()");
+ CHECK_EQ(42, result->Int32Value());
+}
+
+
+void CheckCodeGenerationDisallowed() {
+ TryCatch try_catch;
+
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ result = CompileRun("(function(e) { return e('42'); })(eval)");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ result = CompileRun("execScript('42')");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ result = CompileRun("var f = new Function('return 42'); f()");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+}
+
+
+bool CodeGenerationAllowed(Local<Context> context) {
+ ApiTestFuzzer::Fuzz();
+ return true;
+}
+
+
+bool CodeGenerationDisallowed(Local<Context> context) {
+ ApiTestFuzzer::Fuzz();
+ return false;
+}
+
+
+THREADED_TEST(AllowCodeGenFromStrings) {
+ v8::HandleScope scope;
+ LocalContext context;
+
+ // eval, execScript and the Function constructor allowed by default.
+ CheckCodeGenerationAllowed();
+
+ // Disallow eval, execScript and the Function constructor.
+ context->AllowCodeGenerationFromStrings(false);
+ CheckCodeGenerationDisallowed();
+
+ // Allow again.
+ context->AllowCodeGenerationFromStrings(true);
+ CheckCodeGenerationAllowed();
+
+ // Disallow but setting a global callback that will allow the calls.
+ context->AllowCodeGenerationFromStrings(false);
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed);
+ CheckCodeGenerationAllowed();
+
+ // Set a callback that disallows the code generation.
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed);
+ CheckCodeGenerationDisallowed();
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 9847c89..852c6d4 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -6313,8 +6313,7 @@
v8::Persistent<v8::Context> context_1;
v8::Handle<v8::ObjectTemplate> global_template =
v8::Handle<v8::ObjectTemplate>();
- v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
- context_1 = v8::Context::New(NULL, global_template, global_object);
+ context_1 = v8::Context::New(NULL, global_template);
// Default data value is undefined.
CHECK(context_1->GetData()->IsUndefined());
@@ -6379,11 +6378,11 @@
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
const char* eval_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "arguments:{\"expression\":\"debugger;\","
- "\"global\":true,\"disable_break\":false}}";
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"debugger;\","
+ "\"global\":true,\"disable_break\":false}}";
// Send evaluate command.
v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer));
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index bd08d4c..ee9ee26 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -1,14 +1,16 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
//
// Tests for heap profiler
#ifdef ENABLE_LOGGING_AND_PROFILING
#include "v8.h"
+
+#include "cctest.h"
#include "heap-profiler.h"
#include "snapshot.h"
#include "string-stream.h"
-#include "cctest.h"
+#include "utils-inl.h"
#include "zone-inl.h"
#include "../include/v8-profiler.h"
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index ce53f8e..e136858 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,8 +29,9 @@
#include "v8.h"
-#include "platform.h"
#include "cctest.h"
+#include "platform.h"
+#include "utils-inl.h"
using namespace v8::internal;
diff --git a/test/mjsunit/closures.js b/test/mjsunit/closures.js
index ee487a4..7c11971 100644
--- a/test/mjsunit/closures.js
+++ b/test/mjsunit/closures.js
@@ -25,10 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
function runner(f, expected) {
- for (var i = 0; i < 1000000; i++) {
- assertEquals(expected, f.call(this));
- }
+ assertEquals(expected, f.call(this));
}
function test(n) {
@@ -36,6 +36,8 @@
var result = n * 2 + arguments.length;
return result;
}
+ for (var i = 0; i < 5; ++i) MyFunction();
+ %OptimizeFunctionOnNextCall(MyFunction)
runner(MyFunction, n * 2);
}
diff --git a/test/mjsunit/compiler/regress-closures-with-eval.js b/test/mjsunit/compiler/regress-closures-with-eval.js
index 507d74f..57afb16 100644
--- a/test/mjsunit/compiler/regress-closures-with-eval.js
+++ b/test/mjsunit/compiler/regress-closures-with-eval.js
@@ -25,12 +25,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Verifies that closures in presence of eval work fine.
function withEval(expr, filter) {
function walk(v) {
for (var i in v) {
for (var i in v) {}
}
+ %OptimizeFunctionOnNextCall(filter);
return filter(v);
}
@@ -46,6 +49,8 @@
var expr = '([' + makeTagInfoJSON(128).join(', ') + '])'
-for (var n = 0; n < 300; n++) {
+for (var n = 0; n < 5; n++) {
withEval(expr, function(a) { return a; });
}
+%OptimizeFunctionOnNextCall(withEval);
+withEval(expr, function(a) { return a; });
\ No newline at end of file
diff --git a/test/mjsunit/compiler/regress-intoverflow.js b/test/mjsunit/compiler/regress-intoverflow.js
index d3842f1..063a376 100644
--- a/test/mjsunit/compiler/regress-intoverflow.js
+++ b/test/mjsunit/compiler/regress-intoverflow.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test overflow checks in optimized code.
function testMul(a, b) {
a *= 2;
@@ -34,7 +36,8 @@
}
}
-for (var i=0; i<1000000; i++) testMul(0,0);
+for (var i=0; i<5; i++) testMul(0,0);
+%OptimizeFunctionOnNextCall(testMul);
assertEquals(4611686018427388000, testMul(-0x40000000, -0x40000000));
function testAdd(a, b) {
@@ -45,7 +48,8 @@
}
}
-for (var i=0; i<1000000; i++) testAdd(0,0);
+for (var i=0; i<5; i++) testAdd(0,0);
+%OptimizeFunctionOnNextCall(testAdd);
assertEquals(-4294967296, testAdd(-0x40000000, -0x40000000));
@@ -58,5 +62,6 @@
}
}
-for (var i=0; i<1000000; i++) testSub(0,0);
+for (var i=0; i<5; i++) testSub(0,0);
+%OptimizeFunctionOnNextCall(testSub);
assertEquals(-2147483650, testSub(-0x40000000, 1));
diff --git a/test/mjsunit/debug-evaluate.js b/test/mjsunit/debug-evaluate.js
index 182e2ac..accf656 100644
--- a/test/mjsunit/debug-evaluate.js
+++ b/test/mjsunit/debug-evaluate.js
@@ -91,24 +91,24 @@
// parameter is passed.
testRequest(
dcp,
- '{"expression":"this.longString","global":true,maxStringLength:-1}',
+ '{"expression":"this.longString","global":true,"maxStringLength":-1}',
true,
longString);
testRequest(
dcp,
- '{"expression":"this.longString","global":true,maxStringLength:' +
+ '{"expression":"this.longString","global":true,"maxStringLength":' +
longString.length + '}',
true,
longString);
var truncatedStringSuffix = '... (length: ' + longString.length + ')';
testRequest(
dcp,
- '{"expression":"this.longString","global":true,maxStringLength:0}',
+ '{"expression":"this.longString","global":true,"maxStringLength":0}',
true,
truncatedStringSuffix);
testRequest(
dcp,
- '{"expression":"this.longString","global":true,maxStringLength:1}',
+ '{"expression":"this.longString","global":true,"maxStringLength":1}',
true,
longString.charAt(0) + truncatedStringSuffix);
// Test that by default string is truncated to first 80 chars.
diff --git a/test/mjsunit/debug-scripts-request.js b/test/mjsunit/debug-scripts-request.js
index 41bff0e..faa732e 100644
--- a/test/mjsunit/debug-scripts-request.js
+++ b/test/mjsunit/debug-scripts-request.js
@@ -71,7 +71,7 @@
testArguments(dcp, '{"types":2}', true);
testArguments(dcp, '{"types":4}', true);
testArguments(dcp, '{"types":7}', true);
- testArguments(dcp, '{"types":0xFF}', true);
+ testArguments(dcp, '{"types":255}', true);
// Test request for all scripts.
var request = '{' + base_request + '}'
diff --git a/test/mjsunit/double-equals.js b/test/mjsunit/double-equals.js
index a68d7ea..5ebf92c 100644
--- a/test/mjsunit/double-equals.js
+++ b/test/mjsunit/double-equals.js
@@ -31,84 +31,206 @@
* implementation of assertEquals.
*/
-assertTrue (void 0 == void 0, "void 0 == void 0");
-assertTrue (null == null, "null == null");
-assertFalse(NaN == NaN, "NaN == NaN");
-assertFalse(NaN == 0, "NaN == 0");
-assertFalse(0 == NaN, "0 == NaN");
-assertFalse(NaN == Infinity, "NaN == Inf");
-assertFalse(Infinity == NaN, "Inf == NaN");
+function testEqual(a, b) {
+ assertTrue(a == b);
+ assertTrue(b == a);
+ assertFalse(a != b);
+ assertFalse(b != a);
+}
-assertTrue(Number.MAX_VALUE == Number.MAX_VALUE, "MAX == MAX");
-assertTrue(Number.MIN_VALUE == Number.MIN_VALUE, "MIN == MIN");
-assertTrue(Infinity == Infinity, "Inf == Inf");
-assertTrue(-Infinity == -Infinity, "-Inf == -Inf");
+function testNotEqual(a, b) {
+ assertFalse(a == b);
+ assertFalse(b == a);
+ assertTrue(a != b);
+ assertTrue(b != a);
+}
-assertTrue(0 == 0, "0 == 0");
-assertTrue(0 == -0, "0 == -0");
-assertTrue(-0 == 0, "-0 == 0");
-assertTrue(-0 == -0, "-0 == -0");
+// Object where ToPrimitive returns value.
+function Wrapper(value) {
+ this.value = value;
+ this.valueOf = function () { return this.value; };
+}
-assertFalse(0.9 == 1, "0.9 == 1");
-assertFalse(0.999999 == 1, "0.999999 == 1");
-assertFalse(0.9999999999 == 1, "0.9999999999 == 1");
-assertFalse(0.9999999999999 == 1, "0.9999999999999 == 1");
+// Object where ToPrimitive returns value by failover to toString when
+// valueOf isn't a function.
+function Wrapper2(value) {
+ this.value = value;
+ this.valueOf = null;
+ this.toString = function () { return this.value; };
+}
-assertTrue('hello' == 'hello', "'hello' == 'hello'");
-assertTrue (true == true, "true == true");
-assertTrue (false == false, "false == false");
-assertFalse(true == false, "true == false");
-assertFalse(false == true, "false == true");
+// Compare values of same type.
-assertFalse(new Wrapper(null) == new Wrapper(null), "new Wrapper(null) == new Wrapper(null)");
-assertFalse(new Boolean(true) == new Boolean(true), "new Boolean(true) == new Boolean(true)");
-assertFalse(new Boolean(false) == new Boolean(false), "new Boolean(false) == new Boolean(false)");
+// Numbers are equal if same, unless NaN, which isn't equal to anything, and
+// +/-0 being equal.
+
+testNotEqual(NaN, NaN);
+testNotEqual(NaN, 0);
+testNotEqual(NaN, Infinity);
+
+testEqual(Number.MAX_VALUE, Number.MAX_VALUE);
+testEqual(Number.MIN_VALUE, Number.MIN_VALUE);
+testEqual(Infinity, Infinity);
+testEqual(-Infinity, -Infinity);
+
+testEqual(0, 0);
+testEqual(0, -0);
+testEqual(-0, -0);
+
+testNotEqual(0.9, 1);
+testNotEqual(0.999999, 1);
+testNotEqual(0.9999999999, 1);
+testNotEqual(0.9999999999999, 1);
+
+// Strings are equal if containing the same code points.
+
+testEqual('hello', 'hello');
+testEqual('hello', 'hel' + 'lo');
+testEqual('', '');
+testEqual('\u0020\x20', ' '); // Escapes are not part of the value.
+
+// Booleans are equal if they are the same.
+
+testEqual(true, true);
+testEqual(false, false);
+testNotEqual(true, false);
+
+// Null and undefined are equal to themselves.
+
+testEqual(null, null);
+testEqual(undefined, undefined);
+
+// Objects are equal if they are the same object only.
+
+testEqual(Math, Math);
+testEqual(Object.prototype, Object.prototype);
+
(function () {
var x = new Wrapper(null);
var y = x, z = x;
- assertTrue(y == x);
+ testEqual(y, x);
})();
(function () {
var x = new Boolean(true);
var y = x, z = x;
- assertTrue(y == x);
+ testEqual(y, x);
})();
(function () {
var x = new Boolean(false);
var y = x, z = x;
- assertTrue(y == x);
+ testEqual(y, x);
})();
-assertTrue(null == void 0, "null == void 0");
-assertTrue(void 0 == null, "void 0 == null");
-assertFalse(new Wrapper(null) == null, "new Wrapper(null) == null");
-assertFalse(null == new Wrapper(null), "null == new Wrapper(null)");
+// Test comparing values of different types.
-assertTrue(1 == '1', "1 == '1");
-assertTrue(255 == '0xff', "255 == '0xff'");
-assertTrue(0 == '\r', "0 == '\\r'");
-assertTrue(1e19 == '1e19', "1e19 == '1e19'");
+// Null and undefined are equal to each-other, and to nothing else.
+testEqual(null, undefined);
+testEqual(undefined, null);
-assertTrue(new Boolean(true) == true, "new Boolean(true) == true");
-assertTrue(new Boolean(false) == false, "new Boolean(false) == false");
-assertTrue(true == new Boolean(true), "true == new Boolean(true)");
-assertTrue(false == new Boolean(false), "false == new Boolean(false)");
+testNotEqual(null, new Wrapper(null));
+testNotEqual(null, 0);
+testNotEqual(null, false);
+testNotEqual(null, "");
+testNotEqual(null, new Object());
+testNotEqual(undefined, new Wrapper(undefined));
+testNotEqual(undefined, 0);
+testNotEqual(undefined, false);
+testNotEqual(undefined, "");
+testNotEqual(undefined, new Object());
-assertTrue(Boolean(true) == true, "Boolean(true) == true");
-assertTrue(Boolean(false) == false, "Boolean(false) == false");
-assertTrue(true == Boolean(true), "true == Boolean(true)");
-assertTrue(false == Boolean(false), "false == Boolean(false)");
+// Numbers compared to Strings will convert the string to a number using
+// the internal ToNumber conversion.
-assertTrue(new Wrapper(true) == true, "new Wrapper(true) == true");
-assertTrue(new Wrapper(false) == false, "new Wrapper(false) == false");
-assertTrue(true == new Wrapper(true), "true = new Wrapper(true)");
-assertTrue(false == new Wrapper(false), "false = new Wrapper(false)");
+testEqual(1, '1');
+testEqual(255, '0xff');
+testEqual(0, '\r'); // ToNumber ignores tailing and trailing whitespace.
+testEqual(1e19, '1e19');
+testEqual(Infinity, "Infinity");
-function Wrapper(value) {
- this.value = value;
- this.valueOf = function () { return this.value; };
+// Booleans compared to anything else will be converted to numbers.
+testEqual(false, 0);
+testEqual(true, 1);
+testEqual(false, "0"); // String also converted to number.
+testEqual(true, "1");
+
+// Objects compared to Number or String (or Boolean, since that's converted
+// to Number too) is converted to primitive using ToPrimitive with NO HINT.
+// Having no hint means Date gets a string hint, and everything else gets
+// a number hint.
+
+testEqual(new Boolean(true), true);
+testEqual(new Boolean(true), 1); // First to primtive boolean, then to number.
+testEqual(new Boolean(false), false);
+testEqual(new Boolean(false), 0);
+
+testEqual(new Wrapper(true), true);
+testEqual(new Wrapper(true), 1);
+testEqual(new Wrapper(false), false);
+testEqual(new Wrapper(false), 0);
+
+testEqual(new Wrapper2(true), true);
+testEqual(new Wrapper2(true), 1);
+testEqual(new Wrapper2(false), false);
+testEqual(new Wrapper2(false), 0);
+
+testEqual(new Number(1), true);
+testEqual(new Number(1), 1);
+testEqual(new Number(0), false);
+testEqual(new Number(0), 0);
+
+// Date objects convert to string, not number (and the string does not
+// convert to the number).
+testEqual(new Date(42), String(new Date(42)));
+testNotEqual(new Date(42), Number(new Date(42)));
+var dnow = new Date();
+testEqual(dnow, dnow);
+testEqual(dnow, String(dnow));
+testNotEqual(dnow, Number(dnow));
+
+// Doesn't just call toString, but uses ToPrimitive which tries toString first
+// and valueOf second.
+dnow.toString = null;
+testEqual(dnow, Number(dnow));
+dnow.valueOf = function () { return "42"; };
+testEqual(dnow, 42);
+dnow.toString = function () { return "1"; };
+testEqual(dnow, true);
+
+
+// Objects compared to other objects, or to null and undefined, are not
+// converted to primitive.
+testNotEqual(new Wrapper(null), new Wrapper(null));
+testNotEqual(new Boolean(true), new Boolean(true));
+testNotEqual(new Boolean(false), new Boolean(false));
+testNotEqual(new String("a"), new String("a"));
+testNotEqual(new Number(42), new Number(42));
+testNotEqual(new Date(42), new Date(42));
+testNotEqual(new Array(42), new Array(42));
+testNotEqual(new Object(), new Object());
+
+// Object that can't be converted to primitive.
+var badObject = {
+ valueOf: null,
+ toString: function() {
+ return this; // Not primitive.
+ }
+};
+
+testEqual(badObject, badObject);
+testNotEqual(badObject, {});
+testNotEqual(badObject, null);
+testNotEqual(badObject, undefined);
+// Forcing conversion will throw.
+function testBadConversion(value) {
+ assertThrows(function() { return badObject == value; });
+ assertThrows(function() { return badObject != value; });
+ assertThrows(function() { return value == badObject; });
+ assertThrows(function() { return value != badObject; });
}
+testBadConversion(0);
+testBadConversion("string");
+testBadConversion(true);
diff --git a/test/mjsunit/regress/regress-1099.js b/test/mjsunit/regress/regress-1099.js
index 0ed6ede..36f09e4 100644
--- a/test/mjsunit/regress/regress-1099.js
+++ b/test/mjsunit/regress/regress-1099.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test that LApplyArguments lithium instruction restores context after the call.
function X() {
@@ -41,6 +43,9 @@
var y = Y(X());
-for (var i = 0; i < 1000000; i++) {
+for (var i = 0; i < 5; i++) {
assertTrue(y("foo"));
}
+
+%OptimizeFunctionOnNextCall(y);
+assertTrue(y("foo"));
\ No newline at end of file
diff --git a/test/mjsunit/regress/regress-955.js b/test/mjsunit/regress/regress-955.js
new file mode 100644
index 0000000..9a9a0b0
--- /dev/null
+++ b/test/mjsunit/regress/regress-955.js
@@ -0,0 +1,44 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=955
+
+// Correctly parse signed numbers.
+assertEquals(-0, parseInt("-0"));
+assertEquals(0, parseInt("+0"));
+
+// Don't allow whitespace after signs in parseInt.
+assertEquals(NaN, parseInt("- 0"));
+assertEquals(NaN, parseInt("+ 0"));
+assertEquals(NaN, parseInt("-\t0"));
+assertEquals(NaN, parseInt("+\t0"));
+
+// Do allow whitespace at start.
+assertEquals(-0, parseInt(" -0"));
+assertEquals(0, parseInt(" +0"));
+assertEquals(-0, parseInt("\t-0"));
+assertEquals(0, parseInt("\t+0"));
diff --git a/test/mjsunit/strict-mode-opt.js b/test/mjsunit/strict-mode-opt.js
index e2eae33..5ca5c27 100644
--- a/test/mjsunit/strict-mode-opt.js
+++ b/test/mjsunit/strict-mode-opt.js
@@ -25,8 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
var global = 0;
-var MAX = 1000000;
+var MAX = 5;
// Attempt to inline strcit in non-strict.
@@ -43,6 +45,7 @@
(function testInlineStrictInNonStrict() {
for (var i = 0; i <= MAX; i ++) {
try {
+ if (i == MAX - 1) %OptimizeFunctionOnNextCall(nonstrictCallStrict);
nonstrictCallStrict(i);
} catch (e) {
assertInstanceof(e, ReferenceError);
@@ -68,6 +71,7 @@
(function testInlineNonStrictInStrict() {
for (var i = 0; i <= MAX; i ++) {
try {
+ if (i == MAX - 1) %OptimizeFunctionOnNextCall(nonstrictCallStrict);
strictCallNonStrict(i);
} catch (e) {
fail("no exception", "exception");
@@ -87,6 +91,7 @@
(function testOptimizeStrictAssignToUndefined() {
for (var i = 0; i <= MAX; i ++) {
try {
+ if (i == MAX - 1) %OptimizeFunctionOnNextCall(nonstrictCallStrict);
strictAssignToUndefined(i);
} catch (e) {
assertInstanceof(e, ReferenceError);
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 77f13fa..0108b12 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -32,6 +32,28 @@
'gcc_version%': 'unknown',
'v8_compress_startup_data%': 'false',
'v8_target_arch%': '<(target_arch)',
+
+ # Setting 'v8_can_use_unaligned_accesses' to 'true' will allow the code
+ # generated by V8 to do unaligned memory access, and setting it to 'false'
+ # will ensure that the generated code will always do aligned memory
+ # accesses. The default value of 'default' will try to determine the correct
+ # setting. Note that for Intel architectures (ia32 and x64) unaligned memory
+ # access is allowed for all CPUs.
+ 'v8_can_use_unaligned_accesses%': 'default',
+
+ # Setting 'v8_can_use_vfp_instructions' to 'true' will enable use of ARM VFP
+ # instructions in the V8 generated code. VFP instructions will be enabled
+ # both for the snapshot and for the ARM target. Leaving the default value
+ # of 'false' will avoid VFP instructions in the snapshot and use CPU feature
+ # probing when running on the target.
+ 'v8_can_use_vfp_instructions%': 'false',
+
+ # Setting v8_use_arm_eabi_hardfloat to true will turn on V8 support for ARM
+ # EABI calling convention where double arguments are passed in VFP
+ # registers. Note that the GCC flag '-mfloat-abi=hard' should be used as
+ # well when compiling for the ARM target.
+ 'v8_use_arm_eabi_hardfloat%': 'false',
+
'v8_use_snapshot%': 'true',
'v8_use_liveobjectlist%': 'false',
},
@@ -56,6 +78,29 @@
'defines': [
'V8_TARGET_ARCH_ARM',
],
+ 'conditions': [
+ [ 'v8_can_use_unaligned_accesses=="true"', {
+ 'defines': [
+ 'CAN_USE_UNALIGNED_ACCESSES=1',
+ ],
+ }],
+ [ 'v8_can_use_unaligned_accesses=="false"', {
+ 'defines': [
+ 'CAN_USE_UNALIGNED_ACCESSES=0',
+ ],
+ }],
+ [ 'v8_can_use_vfp_instructions=="true"', {
+ 'defines': [
+ 'CAN_USE_VFP_INSTRUCTIONS',
+ ],
+ }],
+ [ 'v8_use_arm_eabi_hardfloat=="true"', {
+ 'defines': [
+ 'USE_EABI_HARDFLOAT=1',
+ 'CAN_USE_VFP_INSTRUCTIONS',
+ ],
+ }],
+ ],
}],
['v8_target_arch=="ia32"', {
'defines': [
@@ -193,19 +238,34 @@
{
'dependencies': ['v8_nosnapshot'],
}],
- ['OS=="win" and component=="shared_library"', {
+ ['component=="shared_library"', {
'type': '<(component)',
'sources': [
+ # Note: on non-Windows we still build this file so that gyp
+ # has some sources to link into the component.
'../../src/v8dll-main.cc',
],
- 'defines': [
- 'BUILDING_V8_SHARED'
+ 'conditions': [
+ ['OS=="win"', {
+ 'defines': [
+ 'BUILDING_V8_SHARED',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'USING_V8_SHARED',
+ ],
+ },
+ }, {
+ 'defines': [
+ 'V8_SHARED',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'V8_SHARED',
+ ],
+ },
+ }],
],
- 'direct_dependent_settings': {
- 'defines': [
- 'USING_V8_SHARED',
- ],
- },
},
{
'type': 'none',
@@ -221,9 +281,27 @@
'target_name': 'v8_snapshot',
'type': '<(library)',
'conditions': [
- ['OS=="win" and component=="shared_library"', {
- 'defines': [
- 'BUILDING_V8_SHARED',
+ ['component=="shared_library"', {
+ 'conditions': [
+ ['OS=="win"', {
+ 'defines': [
+ 'BUILDING_V8_SHARED',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'USING_V8_SHARED',
+ ],
+ },
+ }, {
+ 'defines': [
+ 'V8_SHARED',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'V8_SHARED',
+ ],
+ },
+ }],
],
}],
],
@@ -276,9 +354,10 @@
'cflags': ['-m32'],
'ldflags': ['-m32'],
}],
- ['OS=="win" and component=="shared_library"', {
+ ['component=="shared_library"', {
'defines': [
'BUILDING_V8_SHARED',
+ 'V8_SHARED',
],
}],
]
@@ -512,6 +591,7 @@
'../../src/unicode-inl.h',
'../../src/unicode.cc',
'../../src/unicode.h',
+ '../../src/utils-inl.h',
'../../src/utils.cc',
'../../src/utils.h',
'../../src/v8-counters.cc',
@@ -708,9 +788,10 @@
'libraries': [ '-lwinmm.lib' ],
},
}],
- ['OS=="win" and component=="shared_library"', {
+ ['component=="shared_library"', {
'defines': [
- 'BUILDING_V8_SHARED'
+ 'BUILDING_V8_SHARED',
+ 'V8_SHARED',
],
}],
],
@@ -737,10 +818,10 @@
'../../src/regexp.js',
'../../src/macros.py',
],
- 'experimental_library_files': [
- '../../src/proxy.js',
+ 'experimental_library_files': [
+ '../../src/proxy.js',
'../../src/macros.py',
- ],
+ ],
},
'actions': [
{
@@ -760,7 +841,7 @@
'<@(library_files)'
],
},
- {
+ {
'action_name': 'js2c_experimental',
'inputs': [
'../../tools/js2c.py',