Author: [EMAIL PROTECTED]
Date: Thu Nov 20 01:17:38 2008
New Revision: 798
Modified:
branches/experimental/regexp2000/ChangeLog
branches/experimental/regexp2000/include/v8.h
branches/experimental/regexp2000/src/api.cc
branches/experimental/regexp2000/src/ast.h
branches/experimental/regexp2000/src/builtins-arm.cc
branches/experimental/regexp2000/src/codegen-arm.h
branches/experimental/regexp2000/src/codegen-ia32.cc
branches/experimental/regexp2000/src/codegen-ia32.h
branches/experimental/regexp2000/src/codegen.cc
branches/experimental/regexp2000/src/codegen.h
branches/experimental/regexp2000/src/compiler.cc
branches/experimental/regexp2000/src/compiler.h
branches/experimental/regexp2000/src/debug-delay.js
branches/experimental/regexp2000/src/debug.cc
branches/experimental/regexp2000/src/globals.h
branches/experimental/regexp2000/src/handles.cc
branches/experimental/regexp2000/src/handles.h
branches/experimental/regexp2000/src/heap-inl.h
branches/experimental/regexp2000/src/heap.cc
branches/experimental/regexp2000/src/heap.h
branches/experimental/regexp2000/src/ic.cc
branches/experimental/regexp2000/src/jsregexp.cc
branches/experimental/regexp2000/src/objects.cc
branches/experimental/regexp2000/src/runtime.cc
branches/experimental/regexp2000/src/scanner.cc
branches/experimental/regexp2000/src/stub-cache.cc
branches/experimental/regexp2000/src/stub-cache.h
branches/experimental/regexp2000/src/top.h
branches/experimental/regexp2000/src/v8natives.js
branches/experimental/regexp2000/test/cctest/cctest.status
branches/experimental/regexp2000/test/cctest/test-api.cc
branches/experimental/regexp2000/test/mjsunit/mjsunit.status
branches/experimental/regexp2000/test/mozilla/mozilla.status
branches/experimental/regexp2000/tools/test.py
Log:
Merged bleeding edge 746:795 into regexp2000.
Review URL: http://codereview.chromium.org/11316
Modified: branches/experimental/regexp2000/ChangeLog
==============================================================================
--- branches/experimental/regexp2000/ChangeLog (original)
+++ branches/experimental/regexp2000/ChangeLog Thu Nov 20 01:17:38 2008
@@ -1,3 +1,28 @@
+2008-11-17: Version 0.4.4
+
+ Reduced code size by using shorter instruction encoding when
+ possible.
+
+ Added a --help option to the shell sample and to the d8 shell.
+
+ Added visual studio project files for building the ARM simulator.
+
+ Fixed a number of ARM simulator issues.
+
+ Fixed bug in out-of-memory handling on ARM.
+
+ Implemented shell support for passing arguments to a script from
+ the command line.
+
+ Fixed bug in date code that made certain date functions return -0
+ instead of 0 for dates before the epoch.
+
+ Restricted applications of eval so it can only be used in the
+ context of the associated global object.
+
+ Treat byte-order marks as whitespace characters.
+
+
2008-11-04: Version 0.4.3
Added support for API accessors that prohibit overwriting by
Modified: branches/experimental/regexp2000/include/v8.h
==============================================================================
--- branches/experimental/regexp2000/include/v8.h (original)
+++ branches/experimental/regexp2000/include/v8.h Thu Nov 20 01:17:38 2008
@@ -1811,7 +1811,7 @@
};
-// --- C o u n t e r s C a l l b a c k s
+// --- C o u n t e r s C a l l b a c k s ---
typedef int* (*CounterLookupCallback)(const wchar_t* name);
@@ -1832,7 +1832,24 @@
typedef void (*GCCallback)();
-// --- C o n t e x t G e n e r a t o r
+// --- E x t e r n a l S y m b o l C a l l b a c k ---
+
+/**
+ * Callback used to allocate certain V8 symbols as external strings.
+ *
+ * The data passed to the callback is utf8 encoded.
+ *
+ * Allocations are not allowed in the callback function, you therefore
+ * cannot manipulate objects (set or delete properties for example)
+ * since it is possible such operations will result in the allocation
+ * of objects.
+ */
+typedef String::ExternalStringResource* (*ExternalSymbolCallback)(
+ const char* utf8,
+ size_t length);
+
+
+// --- C o n t e x t G e n e r a t o r ---
/**
* Applications must provide a callback function which is called to
generate
@@ -1930,6 +1947,20 @@
* operations will result in the allocation of objects.
*/
static void SetGlobalGCEpilogueCallback(GCCallback);
+
+ /**
+ * Applications can register a callback that will be used when
+ * allocating most of the V8 symbols. The callback must return an
+ * external string resource that represents the symbols.
+ *
+ * Most often when performing a property lookup the key will be a
+ * symbol. Allocating symbols as external strings can reduce the
+ * amount of string conversions needed when using interceptors and
+ * accessors.
+ *
+ * \note This is an experimental feature and it might be removed.
+ */
+ static void SetExternalSymbolCallback(ExternalSymbolCallback);
/**
* Allows the host application to group objects together. If one
Modified: branches/experimental/regexp2000/src/api.cc
==============================================================================
--- branches/experimental/regexp2000/src/api.cc (original)
+++ branches/experimental/regexp2000/src/api.cc Thu Nov 20 01:17:38 2008
@@ -2203,7 +2203,7 @@
const char* v8::V8::GetVersion() {
- return "0.4.4 (candidate)";
+ return "0.4.5 (candidate)";
}
@@ -2649,6 +2649,12 @@
void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
if (IsDeadCheck("v8::V8::SetGlobalGCEpilogueCallback()")) return;
i::Heap::SetGlobalGCEpilogueCallback(callback);
+}
+
+
+void V8::SetExternalSymbolCallback(ExternalSymbolCallback callback) {
+ if (IsDeadCheck("v8::V8::SetExternalSymbolCallback()")) return;
+ i::Heap::SetExternalSymbolCallback(callback);
}
Modified: branches/experimental/regexp2000/src/ast.h
==============================================================================
--- branches/experimental/regexp2000/src/ast.h (original)
+++ branches/experimental/regexp2000/src/ast.h Thu Nov 20 01:17:38 2008
@@ -1126,6 +1126,7 @@
start_position_(start_position),
end_position_(end_position),
is_expression_(is_expression),
+ loop_nesting_(0),
function_token_position_(RelocInfo::kNoPosition) {
}
@@ -1150,6 +1151,9 @@
bool AllowsLazyCompilation();
+ bool loop_nesting() const { return loop_nesting_; }
+ void set_loop_nesting(int nesting) { loop_nesting_ = nesting; }
+
private:
Handle<String> name_;
Scope* scope_;
@@ -1161,6 +1165,7 @@
int start_position_;
int end_position_;
bool is_expression_;
+ int loop_nesting_;
int function_token_position_;
};
Modified: branches/experimental/regexp2000/src/builtins-arm.cc
==============================================================================
--- branches/experimental/regexp2000/src/builtins-arm.cc (original)
+++ branches/experimental/regexp2000/src/builtins-arm.cc Thu Nov 20
01:17:38 2008
@@ -663,36 +663,7 @@
// they will have the correct value when returning from the debugger.
__ SaveRegistersToMemory(kJSCallerSaved);
- // This is a direct call from a debug breakpoint. To build a fake JS
frame
- // with no parameters push a function and a receiver, keep the current
- // return address in lr, and set r0 to zero.
- __ mov(ip, Operand(ExternalReference::the_hole_value_location()));
- __ ldr(r3, MemOperand(ip));
- __ mov(r0, Operand(0)); // Null receiver and zero arguments.
- __ stm(db_w, sp, r0.bit() | r3.bit()); // push function and receiver
-
- // r0: number of arguments.
- // What follows is an inlined version of EnterJSFrame(0, 0).
- // It needs to be kept in sync if any calling conventions are changed.
-
- // Compute parameter pointer before making changes
- // ip = sp + kPointerSize*(args_len+1); // +1 for receiver, args_len ==
0
- __ add(ip, sp, Operand(kPointerSize));
-
- __ mov(r3, Operand(0)); // args_len to be saved
- __ mov(r2, Operand(cp)); // context to be saved
-
- // push in reverse order: context (r2), args_len (r3), caller_pp,
caller_fp,
- // sp_on_exit (ip == pp), return address
- __ stm(db_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit() |
- ip.bit() | lr.bit());
- // Setup new frame pointer.
- __ add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
- __ mov(pp, Operand(ip)); // setup new parameter pointer
- // r0 is already set to 0 as spare slot to store caller code object
during GC
- __ push(r0); // code pointer
-
- // Inlined EnterJSFrame ends here.
+ __ EnterInternalFrame();
// Store the registers containing object pointers on the expression
stack to
// make sure that these are correctly updated during GC.
@@ -702,7 +673,7 @@
#ifdef DEBUG
__ RecordComment("// Calling from debug break to runtime - come in -
over");
#endif
- // r0 is already 0, no arguments
+ __ mov(r0, Operand(0)); // no arguments
__ mov(r1, Operand(ExternalReference::debug_break()));
CEntryDebugBreakStub ceb;
@@ -713,14 +684,7 @@
// Use sp as base to pop.
__ CopyRegistersFromStackToMemory(sp, r3, pointer_regs);
- // What follows is an inlined version of ExitJSFrame(0).
- // It needs to be kept in sync if any calling conventions are changed.
- // NOTE: loading the return address to lr and discarding the (fake)
function
- // is an addition to this inlined copy.
-
- __ mov(sp, Operand(fp)); // respect ABI stack constraint
- __ ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() | lr.bit());
- __ pop(); // discard fake function
+ __ LeaveInternalFrame();
// Inlined ExitJSFrame ends here.
Modified: branches/experimental/regexp2000/src/codegen-arm.h
==============================================================================
--- branches/experimental/regexp2000/src/codegen-arm.h (original)
+++ branches/experimental/regexp2000/src/codegen-arm.h Thu Nov 20 01:17:38
2008
@@ -296,6 +296,7 @@
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
Handle<Code> ComputeCallInitialize(int argc);
+ Handle<Code> ComputeCallInitializeInLoop(int argc);
// Declare global variables and functions in the given array of
// name/value pairs.
Modified: branches/experimental/regexp2000/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/regexp2000/src/codegen-ia32.cc (original)
+++ branches/experimental/regexp2000/src/codegen-ia32.cc Thu Nov 20
01:17:38 2008
@@ -197,6 +197,10 @@
VirtualFrame virtual_frame(this);
frame_ = &virtual_frame;
cc_reg_ = no_condition;
+
+ // Adjust for function-level loop nesting.
+ loop_nesting_ += fun->loop_nesting();
+
{
CodeGenState state(this);
@@ -383,11 +387,15 @@
}
}
+ // Adjust for function-level loop nesting.
+ loop_nesting_ -= fun->loop_nesting();
+
// Code generation state must be reset.
scope_ = NULL;
frame_ = NULL;
ASSERT(!has_cc());
ASSERT(state_ == NULL);
+ ASSERT(loop_nesting() == 0);
}
@@ -2694,14 +2702,15 @@
// patch the stack to use the global proxy as 'this' in the
// invoked function.
LoadGlobal();
-
// Load the arguments.
for (int i = 0; i < args->length(); i++) {
Load(args->at(i));
}
// Setup the receiver register and call the IC initialization code.
- Handle<Code> stub = ComputeCallInitialize(args->length());
+ Handle<Code> stub = (loop_nesting() > 0)
+ ? ComputeCallInitializeInLoop(args->length())
+ : ComputeCallInitialize(args->length());
__ RecordPosition(node->position());
__ call(stub, RelocInfo::CODE_TARGET_CONTEXT);
__ mov(esi, frame_->Context());
@@ -2745,7 +2754,9 @@
for (int i = 0; i < args->length(); i++) Load(args->at(i));
// Call the IC initialization code.
- Handle<Code> stub = ComputeCallInitialize(args->length());
+ Handle<Code> stub = (loop_nesting() > 0)
+ ? ComputeCallInitializeInLoop(args->length())
+ : ComputeCallInitialize(args->length());
__ RecordPosition(node->position());
__ call(stub, RelocInfo::CODE_TARGET);
__ mov(esi, frame_->Context());
Modified: branches/experimental/regexp2000/src/codegen-ia32.h
==============================================================================
--- branches/experimental/regexp2000/src/codegen-ia32.h (original)
+++ branches/experimental/regexp2000/src/codegen-ia32.h Thu Nov 20 01:17:38
2008
@@ -320,6 +320,7 @@
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
Handle<Code> ComputeCallInitialize(int argc);
+ Handle<Code> ComputeCallInitializeInLoop(int argc);
// Declare global variables and functions in the given array of
// name/value pairs.
Modified: branches/experimental/regexp2000/src/codegen.cc
==============================================================================
--- branches/experimental/regexp2000/src/codegen.cc (original)
+++ branches/experimental/regexp2000/src/codegen.cc Thu Nov 20 01:17:38 2008
@@ -242,6 +242,15 @@
}
+Handle<Code> CodeGenerator::ComputeCallInitializeInLoop(int argc) {
+ // Force the creation of the corresponding stub outside loops,
+ // because it will be used when clearing the ICs later - when we
+ // don't know if we're inside a loop or not.
+ ComputeCallInitialize(argc);
+ CALL_HEAP_FUNCTION(StubCache::ComputeCallInitializeInLoop(argc), Code);
+}
+
+
void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>*
declarations) {
int length = declarations->length();
int globals = 0;
Modified: branches/experimental/regexp2000/src/codegen.h
==============================================================================
--- branches/experimental/regexp2000/src/codegen.h (original)
+++ branches/experimental/regexp2000/src/codegen.h Thu Nov 20 01:17:38 2008
@@ -48,6 +48,7 @@
// CodeGenerator::GenCode
// CodeGenerator::BuildBoilerplate
// CodeGenerator::ComputeCallInitialize
+// CodeGenerator::ComputeCallInitializeInLoop
// CodeGenerator::ProcessDeclarations
// CodeGenerator::DeclareGlobals
// CodeGenerator::CheckForInlineRuntimeCall
Modified: branches/experimental/regexp2000/src/compiler.cc
==============================================================================
--- branches/experimental/regexp2000/src/compiler.cc (original)
+++ branches/experimental/regexp2000/src/compiler.cc Thu Nov 20 01:17:38
2008
@@ -239,7 +239,8 @@
}
-bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared) {
+bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
+ int loop_nesting) {
ZoneScope zone_scope(DELETE_ON_EXIT);
// The VM is in the COMPILER state until exiting this function.
@@ -270,6 +271,9 @@
ASSERT(Top::has_pending_exception());
return false;
}
+
+ // Update the loop nesting in the function literal.
+ lit->set_loop_nesting(loop_nesting);
// Measure how long it takes to do the lazy compilation; only take
// the rest of the function into account to avoid overlap with the
Modified: branches/experimental/regexp2000/src/compiler.h
==============================================================================
--- branches/experimental/regexp2000/src/compiler.h (original)
+++ branches/experimental/regexp2000/src/compiler.h Thu Nov 20 01:17:38 2008
@@ -64,7 +64,7 @@
// Compile from function info (used for lazy compilation). Returns
// true on success and false if the compilation resulted in a stack
// overflow.
- static bool CompileLazy(Handle<SharedFunctionInfo> shared);
+ static bool CompileLazy(Handle<SharedFunctionInfo> shared, int
loop_nesting);
};
} } // namespace v8::internal
Modified: branches/experimental/regexp2000/src/debug-delay.js
==============================================================================
--- branches/experimental/regexp2000/src/debug-delay.js (original)
+++ branches/experimental/regexp2000/src/debug-delay.js Thu Nov 20 01:17:38
2008
@@ -752,46 +752,6 @@
};
-BreakEvent.prototype.details = function() {
- // Build the break details.
- var details = '';
- if (this.breakPointsHit()) {
- details += 'breakpoint';
- if (this.breakPointsHit().length > 1) {
- details += 's';
- }
- details += ' ';
- for (var i = 0; i < this.breakPointsHit().length; i++) {
- if (i > 0) {
- details += ',';
- }
- details += this.breakPointsHit()[i].number();
- }
- } else {
- details += 'break';
- }
- details += ' in ';
- details += this.exec_state_.frame(0).invocationText();
- details += ' at ';
- details += this.exec_state_.frame(0).sourceAndPositionText();
- details += '\n'
- if (this.func().script()) {
- details += FrameSourceUnderline(this.exec_state_.frame(0));
- }
- return details;
-};
-
-
-BreakEvent.prototype.debugPrompt = function() {
- // Build the debug break prompt.
- if (this.breakPointsHit()) {
- return 'breakpoint';
- } else {
- return 'break';
- }
-};
-
-
BreakEvent.prototype.toJSONProtocol = function() {
var o = { seq: next_response_seq++,
type: "event",
@@ -869,32 +829,6 @@
};
-ExceptionEvent.prototype.details = function() {
- var details = "";
- if (this.uncaught_) {
- details += "Uncaught: ";
- } else {
- details += "Exception: ";
- }
-
- details += '"';
- details += MakeMirror(this.exception_).toText();
- details += '" at ';
- details += this.exec_state_.frame(0).sourceAndPositionText();
- details += '\n';
- details += FrameSourceUnderline(this.exec_state_.frame(0));
-
- return details;
-};
-
-ExceptionEvent.prototype.debugPrompt = function() {
- if (this.uncaught_) {
- return "uncaught exception";
- } else {
- return "exception";
- }
-};
-
ExceptionEvent.prototype.toJSONProtocol = function() {
var o = { seq: next_response_seq++,
type: "event",
@@ -920,75 +854,37 @@
return SimpleObjectToJSON_(o);
};
+
function MakeCompileEvent(script_source, script_name, script_function) {
return new CompileEvent(script_source, script_name, script_function);
}
+
function CompileEvent(script_source, script_name, script_function) {
this.scriptSource = script_source;
this.scriptName = script_name;
this.scriptFunction = script_function;
}
-CompileEvent.prototype.details = function() {
- var result = "";
- result = "Script added"
- if (this.scriptData) {
- result += ": '";
- result += this.scriptData;
- result += "'";
- }
- return result;
-};
-
-CompileEvent.prototype.debugPrompt = function() {
- var result = "source"
- if (this.scriptData) {
- result += " '";
- result += this.scriptData;
- result += "'";
- }
- if (this.func) {
- result += " added";
- } else {
- result += " compiled";
- }
- return result;
-};
function MakeNewFunctionEvent(func) {
return new NewFunctionEvent(func);
}
+
function NewFunctionEvent(func) {
this.func = func;
}
-NewFunctionEvent.prototype.details = function() {
- var result = "";
- result = "Function added: ";
- result += this.func.name;
- return result;
-};
-
-NewFunctionEvent.prototype.debugPrompt = function() {
- var result = "function";
- if (this.func.name) {
- result += " '";
- result += this.func.name;
- result += "'";
- }
- result += " added";
- return result;
-};
-
NewFunctionEvent.prototype.name = function() {
return this.func.name;
};
+
NewFunctionEvent.prototype.setBreakPoint = function(p) {
Debug.setBreakPoint(this.func, p || 0);
};
+
function DebugCommandProcessor(exec_state) {
this.exec_state_ = exec_state;
Modified: branches/experimental/regexp2000/src/debug.cc
==============================================================================
--- branches/experimental/regexp2000/src/debug.cc (original)
+++ branches/experimental/regexp2000/src/debug.cc Thu Nov 20 01:17:38 2008
@@ -1135,7 +1135,7 @@
bool Debug::EnsureCompiled(Handle<SharedFunctionInfo> shared) {
if (shared->is_compiled()) return true;
- return CompileLazyShared(shared, CLEAR_EXCEPTION);
+ return CompileLazyShared(shared, CLEAR_EXCEPTION, 0);
}
Modified: branches/experimental/regexp2000/src/globals.h
==============================================================================
--- branches/experimental/regexp2000/src/globals.h (original)
+++ branches/experimental/regexp2000/src/globals.h Thu Nov 20 01:17:38 2008
@@ -288,6 +288,8 @@
enum InlineCacheState {
// Has never been executed.
UNINITIALIZED,
+ // Has never been executed, but is in a loop.
+ UNINITIALIZED_IN_LOOP,
// Has been executed but monomorhic state has been delayed.
PREMONOMORPHIC,
// Has been executed and only one receiver type has been seen.
Modified: branches/experimental/regexp2000/src/handles.cc
==============================================================================
--- branches/experimental/regexp2000/src/handles.cc (original)
+++ branches/experimental/regexp2000/src/handles.cc Thu Nov 20 01:17:38 2008
@@ -422,10 +422,11 @@
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
- ClearExceptionFlag flag) {
+ ClearExceptionFlag flag,
+ int loop_nesting) {
// Compile the source information to a code object.
ASSERT(!shared->is_compiled());
- bool result = Compiler::CompileLazy(shared);
+ bool result = Compiler::CompileLazy(shared, loop_nesting);
ASSERT(result != Top::has_pending_exception());
if (!result && flag == CLEAR_EXCEPTION) Top::clear_pending_exception();
return result;
@@ -435,9 +436,15 @@
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
// Compile the source information to a code object.
Handle<SharedFunctionInfo> shared(function->shared());
- return CompileLazyShared(shared, flag);
+ return CompileLazyShared(shared, flag, 0);
}
+
+bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag
flag) {
+ // Compile the source information to a code object.
+ Handle<SharedFunctionInfo> shared(function->shared());
+ return CompileLazyShared(shared, flag, 1);
+}
OptimizedObjectForAddingMultipleProperties::
OptimizedObjectForAddingMultipleProperties(Handle<JSObject> object,
Modified: branches/experimental/regexp2000/src/handles.h
==============================================================================
--- branches/experimental/regexp2000/src/handles.h (original)
+++ branches/experimental/regexp2000/src/handles.h Thu Nov 20 01:17:38 2008
@@ -194,9 +194,13 @@
// Do lazy compilation of the given function. Returns true on success
// and false if the compilation resulted in a stack overflow.
enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
+
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
- ClearExceptionFlag flag);
+ ClearExceptionFlag flag,
+ int loop_nesting);
+
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
+bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag
flag);
// These deal with lazily loaded properties.
void SetupLazy(Handle<JSFunction> fun,
Modified: branches/experimental/regexp2000/src/heap-inl.h
==============================================================================
--- branches/experimental/regexp2000/src/heap-inl.h (original)
+++ branches/experimental/regexp2000/src/heap-inl.h Thu Nov 20 01:17:38 2008
@@ -38,6 +38,18 @@
}
+Object* Heap::AllocateSymbol(Vector<const char> str,
+ int chars,
+ uint32_t length_field) {
+ if (global_external_symbol_callback_) {
+ return AllocateExternalSymbol(str, chars);
+ }
+ unibrow::Utf8InputBuffer<> buffer(str.start(),
+ static_cast<unsigned>(str.length()));
+ return AllocateInternalSymbol(&buffer, chars, length_field);
+}
+
+
Object* Heap::AllocateRaw(int size_in_bytes,
AllocationSpace space,
AllocationSpace retry_space) {
Modified: branches/experimental/regexp2000/src/heap.cc
==============================================================================
--- branches/experimental/regexp2000/src/heap.cc (original)
+++ branches/experimental/regexp2000/src/heap.cc Thu Nov 20 01:17:38 2008
@@ -84,6 +84,8 @@
GCCallback Heap::global_gc_prologue_callback_ = NULL;
GCCallback Heap::global_gc_epilogue_callback_ = NULL;
+ExternalSymbolCallback Heap::global_external_symbol_callback_ = NULL;
+
// Variables set based on semispace_size_ and old_generation_size_ in
// ConfigureHeap.
int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_.
@@ -1542,6 +1544,29 @@
}
+Object* Heap::AllocateExternalSymbolFromTwoByte(
+ ExternalTwoByteString::Resource* resource) {
+ Map* map;
+ int length = resource->length();
+ if (length <= String::kMaxShortStringSize) {
+ map = short_external_symbol_map();
+ } else if (length <= String::kMaxMediumStringSize) {
+ map = medium_external_symbol_map();
+ } else {
+ map = long_external_symbol_map();
+ }
+
+ Object* result = Allocate(map, OLD_DATA_SPACE);
+ if (result->IsFailure()) return result;
+
+ ExternalTwoByteString* external_string =
ExternalTwoByteString::cast(result);
+ external_string->set_length(length);
+ external_string->set_resource(resource);
+
+ return result;
+}
+
+
Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
if (code <= String::kMaxAsciiCharCode) {
Object* value = Heap::single_character_string_cache()->get(code);
@@ -2053,9 +2078,9 @@
}
-Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer,
- int chars,
- uint32_t length_field) {
+Object* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
+ int chars,
+ uint32_t length_field) {
// Ensure the chars matches the number of characters in the buffer.
ASSERT(static_cast<unsigned>(chars) == buffer->Length());
// Determine whether the string is ascii.
@@ -2108,6 +2133,44 @@
answer->Set(answer_shape, i, buffer->GetNext());
}
return answer;
+}
+
+
+// External string resource that only contains a length field. These
+// are used temporarily when allocating external symbols.
+class DummyExternalStringResource
+ : public v8::String::ExternalStringResource {
+ public:
+ explicit DummyExternalStringResource(size_t length) : length_(length) { }
+
+ virtual const uint16_t* data() const {
+ UNREACHABLE();
+ return NULL;
+ }
+
+ virtual size_t length() const { return length_; }
+ private:
+ size_t length_;
+};
+
+
+Object* Heap::AllocateExternalSymbol(Vector<const char> string, int chars)
{
+ // Attempt to allocate the resulting external string first. Use a
+ // dummy string resource that has the correct length so that we only
+ // have to patch the external string resource after the callback.
+ DummyExternalStringResource dummy_resource(chars);
+ Object* obj = AllocateExternalSymbolFromTwoByte(&dummy_resource);
+ if (obj->IsFailure()) return obj;
+ // Perform callback.
+ v8::String::ExternalStringResource* resource =
+ global_external_symbol_callback_(string.start(), string.length());
+ // Patch the resource pointer of the result.
+ ExternalTwoByteString* result = ExternalTwoByteString::cast(obj);
+ result->set_resource(resource);
+ // Force hash code to be computed.
+ result->Hash();
+ ASSERT(result->IsEqualTo(string));
+ return result;
}
Modified: branches/experimental/regexp2000/src/heap.h
==============================================================================
--- branches/experimental/regexp2000/src/heap.h (original)
+++ branches/experimental/regexp2000/src/heap.h Thu Nov 20 01:17:38 2008
@@ -356,9 +356,17 @@
// Returns Failure::RetryAfterGC(requested_bytes, space) if the
allocation
// failed.
// Please note this function does not perform a garbage collection.
- static Object* AllocateSymbol(unibrow::CharacterStream* buffer,
- int chars,
- uint32_t length_field);
+ static inline Object* AllocateSymbol(Vector<const char> str,
+ int chars,
+ uint32_t length_field);
+
+ static Object* AllocateInternalSymbol(unibrow::CharacterStream* buffer,
+ int chars,
+ uint32_t length_field);
+
+ static Object* AllocateExternalSymbol(Vector<const char> str,
+ int chars);
+
// Allocates and partially initializes a String. There are two String
// encodings: ASCII and two byte. These functions allocate a string of
the
@@ -533,6 +541,8 @@
ExternalAsciiString::Resource* resource);
static Object* AllocateExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource);
+ static Object* AllocateExternalSymbolFromTwoByte(
+ ExternalTwoByteString::Resource* resource);
// Allocates an uninitialized object. The memory is non-executable if
the
// hardware and OS allow.
@@ -604,6 +614,10 @@
global_gc_epilogue_callback_ = callback;
}
+ static void SetExternalSymbolCallback(ExternalSymbolCallback callback) {
+ global_external_symbol_callback_ = callback;
+ }
+
// Heap roots
#define ROOT_ACCESSOR(type, name) static type* name() { return name##_; }
ROOT_LIST(ROOT_ACCESSOR)
@@ -862,6 +876,9 @@
// Allocations in the callback function are disallowed.
static GCCallback global_gc_prologue_callback_;
static GCCallback global_gc_epilogue_callback_;
+
+ // Callback function used for allocating external symbols.
+ static ExternalSymbolCallback global_external_symbol_callback_;
// Checks whether a global GC is necessary
static GarbageCollector SelectGarbageCollector(AllocationSpace space);
Modified: branches/experimental/regexp2000/src/ic.cc
==============================================================================
--- branches/experimental/regexp2000/src/ic.cc (original)
+++ branches/experimental/regexp2000/src/ic.cc Thu Nov 20 01:17:38 2008
@@ -41,6 +41,7 @@
static char TransitionMarkFromState(IC::State state) {
switch (state) {
case UNINITIALIZED: return '0';
+ case UNINITIALIZED_IN_LOOP: return 'L';
case PREMONOMORPHIC: return '0';
case MONOMORPHIC: return '1';
case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
@@ -223,7 +224,8 @@
void CallIC::Clear(Address address, Code* target) {
- if (target->ic_state() == UNINITIALIZED) return;
+ State state = target->ic_state();
+ if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP) return;
Code* code = StubCache::FindCallInitialize(target->arguments_count());
SetTargetAtAddress(address, code);
}
@@ -434,8 +436,9 @@
if (code->IsFailure()) return;
// Patch the call site depending on the state of the cache.
- if (state == UNINITIALIZED || state == PREMONOMORPHIC ||
- state == MONOMORPHIC || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
+ if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP ||
+ state == PREMONOMORPHIC || state == MONOMORPHIC ||
+ state == MONOMORPHIC_PROTOTYPE_FAILURE) {
set_target(Code::cast(code));
}
@@ -1044,7 +1047,17 @@
ASSERT(args.length() == 2);
CallIC ic;
IC::State state = IC::StateFrom(ic.target(), args[0]);
- return ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
+ Object* result =
+ ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
+ if (state != UNINITIALIZED_IN_LOOP || !result->IsJSFunction())
+ return result;
+
+ // Compile the function with the knowledge that it's called from
+ // within a loop. This enables further optimization of the function.
+ HandleScope scope;
+ Handle<JSFunction> function =
Handle<JSFunction>(JSFunction::cast(result));
+ if (!function->is_compiled()) CompileLazyInLoop(function,
CLEAR_EXCEPTION);
+ return *function;
}
Modified: branches/experimental/regexp2000/src/jsregexp.cc
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.cc (original)
+++ branches/experimental/regexp2000/src/jsregexp.cc Thu Nov 20 01:17:38
2008
@@ -111,7 +111,7 @@
// Ensure that the constructor function has been loaded.
if (!constructor->IsLoaded()) {
LoadLazy(constructor, has_pending_exception);
- if (*has_pending_exception) return
Handle<Object>(Failure::Exception());
+ if (*has_pending_exception) return Handle<Object>();
}
// Call the construct code with 2 arguments.
Object** argv[2] = { Handle<Object>::cast(pattern).location(),
Modified: branches/experimental/regexp2000/src/objects.cc
==============================================================================
--- branches/experimental/regexp2000/src/objects.cc (original)
+++ branches/experimental/regexp2000/src/objects.cc Thu Nov 20 01:17:38 2008
@@ -4654,6 +4654,7 @@
const char* Code::ICState2String(InlineCacheState state) {
switch (state) {
case UNINITIALIZED: return "UNINITIALIZED";
+ case UNINITIALIZED_IN_LOOP: return "UNINITIALIZED_IN_LOOP";
case PREMONOMORPHIC: return "PREMONOMORPHIC";
case MONOMORPHIC: return "MONOMORPHIC";
case MONOMORPHIC_PROTOTYPE_FAILURE:
return "MONOMORPHIC_PROTOTYPE_FAILURE";
@@ -5856,9 +5857,7 @@
Object* GetObject() {
if (length_field_ == 0) Hash();
- unibrow::Utf8InputBuffer<> buffer(string_.start(),
-
static_cast<unsigned>(string_.length()));
- return Heap::AllocateSymbol(&buffer, chars_, length_field_);
+ return Heap::AllocateSymbol(string_, chars_, length_field_);
}
static uint32_t StringHash(Object* obj) {
@@ -5907,9 +5906,9 @@
}
// Otherwise allocate a new symbol.
StringInputBuffer buffer(string_);
- return Heap::AllocateSymbol(&buffer,
- string_->length(),
- string_->length_field());
+ return Heap::AllocateInternalSymbol(&buffer,
+ string_->length(),
+ string_->length_field());
}
static uint32_t StringHash(Object* obj) {
Modified: branches/experimental/regexp2000/src/runtime.cc
==============================================================================
--- branches/experimental/regexp2000/src/runtime.cc (original)
+++ branches/experimental/regexp2000/src/runtime.cc Thu Nov 20 01:17:38 2008
@@ -3956,29 +3956,28 @@
Handle<Context> target = Top::global_context();
if (caller->global_context() == *target) return *caller;
- // Compute a function closure that captures the calling context. We
- // need a function that has trivial scope info, since it is only
- // used to hold the context chain together.
- Handle<JSFunction> closure =
Factory::NewFunction(Factory::empty_symbol(),
-
Factory::undefined_value());
- closure->set_context(*caller);
-
- // Create a new adaptor context that has the target environment as
- // the extension object. This enables the evaluated code to see both
- // the current context with locals and everything and to see global
- // variables declared in the target global object. Furthermore, any
- // properties introduced with 'var' will be added to the target
- // global object because it is the extension object.
- Handle<Context> adaptor =
- Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, closure);
- adaptor->set_extension(target->global());
- return *adaptor;
+ // Otherwise, use the global context from the other environment.
+ return *target;
}
static Object* Runtime_EvalReceiver(Arguments args) {
+ ASSERT(args.length() == 1);
StackFrameLocator locator;
- return locator.FindJavaScriptFrame(1)->receiver();
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
+ // Fetch the caller context from the frame.
+ Context* caller = Context::cast(frame->context());
+
+ // Check for eval() invocations that cross environments. Use the
+ // top frames receiver if evaluating in current environment.
+ Context* global_context = Top::context()->global()->global_context();
+ if (caller->global_context() == global_context) {
+ return frame->receiver();
+ }
+
+ // Otherwise use the given argument (the global object of the
+ // receiving context).
+ return args[0];
}
@@ -4797,9 +4796,10 @@
// Traverse the saved contexts chain to find the active context for the
// selected frame.
SaveContext* save = Top::save_context();
- while (save != NULL && reinterpret_cast<Address>(save) <
it.frame()->sp()) {
+ while (save != NULL && !save->below(it.frame())) {
save = save->prev();
}
+ ASSERT(save != NULL);
// Get the frame id.
Handle<Object> frame_id(WrapFrameId(it.frame()->id()));
@@ -5088,7 +5088,7 @@
if (!done) {
// If the candidate is not compiled compile it to reveal any inner
// functions which might contain the requested source position.
- CompileLazyShared(target, KEEP_EXCEPTION);
+ CompileLazyShared(target, KEEP_EXCEPTION, 0);
}
}
@@ -5299,7 +5299,7 @@
// Traverse the saved contexts chain to find the active context for the
// selected frame.
SaveContext* save = Top::save_context();
- while (save != NULL && reinterpret_cast<Address>(save) < frame->sp()) {
+ while (save != NULL && !save->below(frame)) {
save = save->prev();
}
ASSERT(save != NULL);
Modified: branches/experimental/regexp2000/src/scanner.cc
==============================================================================
--- branches/experimental/regexp2000/src/scanner.cc (original)
+++ branches/experimental/regexp2000/src/scanner.cc Thu Nov 20 01:17:38 2008
@@ -234,11 +234,25 @@
}
+static inline bool IsByteOrderMark(uc32 c) {
+ // The Unicode value U+FFFE is guaranteed never to be assigned as a
+ // Unicode character; this implies that in a Unicode context the
+ // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF
+ // character expressed in little-endian byte order (since it could
+ // not be a U+FFFE character expressed in big-endian byte
+ // order). Nevertheless, we check for it to be compatible with
+ // Spidermonkey.
+ return c == 0xFEFF || c == 0xFFFE;
+}
+
+
void Scanner::SkipWhiteSpace(bool initial) {
has_line_terminator_before_next_ = initial;
while (true) {
- while (kIsWhiteSpace.get(c0_)) {
+ // We treat byte-order marks (BOMs) as whitespace for better
+ // compatibility with Spidermonkey and other JavaScript engines.
+ while (kIsWhiteSpace.get(c0_) || IsByteOrderMark(c0_)) {
// IsWhiteSpace() includes line terminators!
if (kIsLineTerminator.get(c0_))
// Ignore line terminators, but remember them. This is necessary
Modified: branches/experimental/regexp2000/src/stub-cache.cc
==============================================================================
--- branches/experimental/regexp2000/src/stub-cache.cc (original)
+++ branches/experimental/regexp2000/src/stub-cache.cc Thu Nov 20 01:17:38
2008
@@ -543,6 +543,17 @@
}
+Object* StubCache::ComputeCallInitializeInLoop(int argc) {
+ Code::Flags flags =
+ Code::ComputeFlags(Code::CALL_IC, UNINITIALIZED_IN_LOOP, NORMAL,
argc);
+ Object* probe = ProbeCache(flags);
+ if (!probe->IsUndefined()) return probe;
+ StubCompiler compiler;
+ return FillCache(compiler.CompileCallInitialize(flags));
+}
+
+
+
Object* StubCache::ComputeCallPreMonomorphic(int argc) {
Code::Flags flags =
Code::ComputeFlags(Code::CALL_IC, PREMONOMORPHIC, NORMAL, argc);
Modified: branches/experimental/regexp2000/src/stub-cache.h
==============================================================================
--- branches/experimental/regexp2000/src/stub-cache.h (original)
+++ branches/experimental/regexp2000/src/stub-cache.h Thu Nov 20 01:17:38
2008
@@ -148,6 +148,7 @@
// ---
static Object* ComputeCallInitialize(int argc);
+ static Object* ComputeCallInitializeInLoop(int argc);
static Object* ComputeCallPreMonomorphic(int argc);
static Object* ComputeCallNormal(int argc);
static Object* ComputeCallMegamorphic(int argc);
Modified: branches/experimental/regexp2000/src/top.h
==============================================================================
--- branches/experimental/regexp2000/src/top.h (original)
+++ branches/experimental/regexp2000/src/top.h Thu Nov 20 01:17:38 2008
@@ -312,6 +312,10 @@
#endif
prev_(Top::save_context()) {
Top::set_save_context(this);
+
+ // If there is no JS frame under the current C frame, use the value 0.
+ JavaScriptFrameIterator it;
+ js_sp_ = it.done() ? 0 : it.frame()->sp();
}
~SaveContext() {
@@ -322,12 +326,18 @@
Handle<Context> context() { return context_; }
SaveContext* prev() { return prev_; }
+ // Returns true if this save context is below a given JavaScript frame.
+ bool below(JavaScriptFrame* frame) {
+ return (js_sp_ == 0) || (frame->sp() < js_sp_);
+ }
+
private:
Handle<Context> context_;
#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
Handle<Context> dummy_;
#endif
SaveContext* prev_;
+ Address js_sp_; // The top JS frame's sp when saving context.
};
Modified: branches/experimental/regexp2000/src/v8natives.js
==============================================================================
--- branches/experimental/regexp2000/src/v8natives.js (original)
+++ branches/experimental/regexp2000/src/v8natives.js Thu Nov 20 01:17:38
2008
@@ -105,6 +105,11 @@
function GlobalEval(x) {
if (!IS_STRING(x)) return x;
+ if (this !== %GlobalReceiver(global)) {
+ throw new $EvalError('The "this" object passed to eval must ' +
+ 'be the global object from which eval
originated');
+ }
+
var f = %CompileString(x, 0, true);
if (!IS_FUNCTION(f)) return f;
Modified: branches/experimental/regexp2000/test/cctest/cctest.status
==============================================================================
--- branches/experimental/regexp2000/test/cctest/cctest.status (original)
+++ branches/experimental/regexp2000/test/cctest/cctest.status Thu Nov 20
01:17:38 2008
@@ -34,7 +34,6 @@
test-debug: SKIP
test-serialize: SKIP
-test-api: SKIP
# BUG(113): Test seems flaky on ARM.
test-spaces/LargeObjectSpace: PASS || FAIL
Modified: branches/experimental/regexp2000/test/cctest/test-api.cc
==============================================================================
--- branches/experimental/regexp2000/test/cctest/test-api.cc (original)
+++ branches/experimental/regexp2000/test/cctest/test-api.cc Thu Nov 20
01:17:38 2008
@@ -4018,6 +4018,30 @@
}
+THREADED_TEST(Eval) {
+ v8::HandleScope scope;
+ LocalContext current;
+
+ // Test that un-aliased eval uses local context.
+ Local<Script> script =
+ Script::Compile(v8_str("foo = 0;"
+ "(function() {"
+ " var foo = 2;"
+ " return eval('foo');"
+ "})();"));
+ Local<Value> result = script->Run();
+ CHECK_EQ(2, result->Int32Value());
+
+ // Test that un-aliased eval has right this.
+ script =
+ Script::Compile(v8_str("function MyObject() { this.self =
eval('this'); }"
+ "var o = new MyObject();"
+ "o === o.self"));
+ result = script->Run();
+ CHECK(result->IsTrue());
+}
+
+
THREADED_TEST(CrossEval) {
v8::HandleScope scope;
LocalContext other;
@@ -4039,45 +4063,62 @@
CHECK(!current->Global()->Has(v8_str("foo")));
// Check that writing to non-existing properties introduces them in
- // the current context.
+ // the other context.
script =
Script::Compile(v8_str("other.eval('na = 1234')"));
script->Run();
- CHECK_EQ(1234, current->Global()->Get(v8_str("na"))->Int32Value());
- CHECK(!other->Global()->Has(v8_str("na")));
+ CHECK_EQ(1234, other->Global()->Get(v8_str("na"))->Int32Value());
+ CHECK(!current->Global()->Has(v8_str("na")));
- // Check that variables in current context are visible in other
- // context. This must include local variables.
+ // Check that global variables in current context are not visible in
other
+ // context.
+ v8::TryCatch try_catch;
script =
- Script::Compile(v8_str("var bar = 42;"
- "(function() { "
- " var baz = 87;"
- " return other.eval('bar + baz');"
- "})();"));
+ Script::Compile(v8_str("var bar = 42; other.eval('bar');"));
Local<Value> result = script->Run();
- CHECK_EQ(42 + 87, result->Int32Value());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ // Check that local variables in current context are not visible in other
+ // context.
+ script =
+ Script::Compile(v8_str("(function() { "
+ " var baz = 87;"
+ " return other.eval('baz');"
+ "})();"));
+ result = script->Run();
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Check that global variables in the other environment are visible
// when evaluting code.
other->Global()->Set(v8_str("bis"), v8_num(1234));
script = Script::Compile(v8_str("other.eval('bis')"));
CHECK_EQ(1234, script->Run()->Int32Value());
+ CHECK(!try_catch.HasCaught());
- // Check that the 'this' pointer isn't touched as a result of
- // calling eval across environments.
+ // Check that the 'this' pointer points to the global object evaluating
+ // code.
+ other->Global()->Set(v8_str("t"), other->Global());
+ script = Script::Compile(v8_str("other.eval('this == t')"));
+ result = script->Run();
+ CHECK(result->IsTrue());
+ CHECK(!try_catch.HasCaught());
+
+ // Check that variables introduced in with-statement are not visible in
+ // other context.
script =
- Script::Compile(v8_str("var t = this; other.eval('this == t')"));
+ Script::Compile(v8_str("with({x:2}){other.eval('x')}"));
result = script->Run();
- CHECK(result->IsBoolean());
- CHECK(result->BooleanValue());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
- // Check that doing a cross eval works from within a global
- // with-statement.
+ // Check that you cannot use 'eval.call' with another object than the
+ // current global object.
script =
- Script::Compile(v8_str("other.y = 1;"
- "with({x:2}){other.eval('x+y')}"));
+ Script::Compile(v8_str("other.y = 1; eval.call(other, 'y')"));
result = script->Run();
- CHECK_EQ(3, result->Int32Value());
+ CHECK(try_catch.HasCaught());
}
@@ -5213,4 +5254,70 @@
context->Global()->Set(v8_str("obj"), instance);
Local<Value> value = CompileRun("obj.x");
CHECK(value->BooleanValue());
+}
+
+
+static String::ExternalStringResource* SymbolCallback(const char* chars,
+ size_t length) {
+ uint16_t* buffer = i::NewArray<uint16_t>(length + 1);
+ for (size_t i = 0; i < length; i++) {
+ buffer[i] = chars[i];
+ }
+ buffer[length] = '\0';
+ return new TestResource(buffer);
+}
+
+
+static v8::Handle<Value> ExternalSymbolGetter(Local<String> name,
+ const AccessorInfo& info) {
+ ApiTestFuzzer::Fuzz();
+ CHECK(!name->Equals(v8_str("externalSymbol722")) || name->IsExternal());
+ return v8::True();
+}
+
+
+static void ExternalSymbolSetter(Local<String> name,
+ Local<Value> value,
+ const AccessorInfo&) {
+ ApiTestFuzzer::Fuzz();
+ CHECK(!name->Equals(v8_str("externalSymbol722")) || name->IsExternal());
+}
+
+
+THREADED_TEST(ExternalSymbols) {
+ TestResource::dispose_count = 0;
+ v8::V8::SetExternalSymbolCallback(SymbolCallback);
+ v8::HandleScope scope;
+ LocalContext context;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ // Use a bizare name so that the name does not clash with names used
+ // in natives files. If running with snapshots enabled, variable
+ // names used in the native files will be normal symbols instead of
+ // external ones. Also, make sure that the bizare name is used from
+ // JavaScript code before using it from C++ code.
+ Local<Value> value =
+ CompileRun("var o = { externalSymbol722: 42 }; o.externalSymbol722");
+ CHECK_EQ(42, value->Int32Value());
+ templ->SetAccessor(v8_str("externalSymbol722"),
+ ExternalSymbolGetter,
+ ExternalSymbolSetter);
+ context->Global()->Set(v8_str("obj"), templ->NewInstance());
+ value = CompileRun("obj.externalSymbol722");
+ CHECK_EQ(true, value->BooleanValue());
+ value = CompileRun("obj.externalSymbol722 = 42");
+ v8::V8::SetExternalSymbolCallback(NULL);
+}
+
+
+// This test verifies that pre-compilation (aka preparsing) can be called
+// without initializing the whole VM. Thus we cannot run this test in a
+// multi-threaded setup.
+TEST(PreCompile) {
+ // TODO(155): This test would break without the initialization of V8.
This is
+ // a workaround for now to make this test not fail.
+ v8::V8::Initialize();
+ const char *script = "function foo(a) { return a+1; }";
+ v8::ScriptData *sd = v8::ScriptData::PreCompile(script, strlen(script));
+ CHECK_NE(sd->Length(), 0);
+ CHECK_NE(sd->Data(), NULL);
}
Modified: branches/experimental/regexp2000/test/mjsunit/mjsunit.status
==============================================================================
--- branches/experimental/regexp2000/test/mjsunit/mjsunit.status
(original)
+++ branches/experimental/regexp2000/test/mjsunit/mjsunit.status Thu Nov
20
01:17:38 2008
@@ -41,26 +41,21 @@
debug-scripts-request: PASS, SKIP if $mode == debug
# Bug number 1020483: Debug tests fail on ARM.
-debug-constructor: CRASH, FAIL if $mode == debug
-debug-continue: CRASH, FAIL if $mode == debug
-debug-backtrace-text: FAIL
-debug-backtrace: CRASH, FAIL if $mode == debug
+debug-constructor: CRASH, FAIL
+debug-continue: CRASH, FAIL
+debug-backtrace: FAIL
debug-evaluate-recursive: CRASH, FAIL if $mode == debug
debug-changebreakpoint: CRASH, FAIL if $mode == debug
debug-clearbreakpoint: CRASH, FAIL if $mode == debug
debug-conditional-breakpoints: CRASH, FAIL if $mode == debug
-debug-enable-disable-breakpoints: CRASH, FAIL if $mode == debug
debug-evaluate: CRASH, FAIL if $mode == debug
-debug-event-listener: CRASH, FAIL if $mode == debug
debug-ignore-breakpoints: CRASH, FAIL if $mode == debug
debug-multiple-breakpoints: CRASH, FAIL if $mode == debug
debug-setbreakpoint: CRASH, FAIL if $mode == debug
debug-step-stub-callfunction: CRASH
-debug-stepin-constructor: CRASH, FAIL if $mode == debug
+debug-stepin-constructor: CRASH, FAIL
debug-step: CRASH, FAIL if $mode == debug
debug-breakpoints: PASS || FAIL
-
-regress/regress-998565: CRASH, FAIL if $mode == debug
# Bug number 130 http://code.google.com/p/v8/issues/detail?id=130
# Fails on real ARM hardware but not on the simulator.
Modified: branches/experimental/regexp2000/test/mozilla/mozilla.status
==============================================================================
--- branches/experimental/regexp2000/test/mozilla/mozilla.status
(original)
+++ branches/experimental/regexp2000/test/mozilla/mozilla.status Thu Nov
20
01:17:38 2008
@@ -570,10 +570,7 @@
js1_5/Regress/regress-303213: FAIL
-# Bug 1193440: Ignore Unicode BOM characters when scanning.
-ecma_3/extensions/regress-368516: FAIL
-
-# Bug 1202592:New ecma_3/String/15.5.4.11 is failing.
+# Bug 1202592: New ecma_3/String/15.5.4.11 is failing.
ecma_3/String/15.5.4.11: FAIL
# Bug 1202597: New js1_5/Expressions/regress-394673 is failing.
Modified: branches/experimental/regexp2000/tools/test.py
==============================================================================
--- branches/experimental/regexp2000/tools/test.py (original)
+++ branches/experimental/regexp2000/tools/test.py Thu Nov 20 01:17:38 2008
@@ -417,8 +417,12 @@
if utils.IsWindows():
popen_args = '"' + subprocess.list2cmdline(args) + '"'
if context.suppress_dialogs:
- # Try to change the error mode to avoid dialogs on fatal errors.
- Win32SetErrorMode(SEM_NOGPFAULTERRORBOX)
+ # Try to change the error mode to avoid dialogs on fatal errors.
Don't
+ # touch any existing error mode flags by merging the existing error
mode.
+ # See
http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx.
+ error_mode = SEM_NOGPFAULTERRORBOX;
+ prev_error_mode = Win32SetErrorMode(error_mode);
+ Win32SetErrorMode(error_mode | prev_error_mode);
process = subprocess.Popen(
shell = utils.IsWindows(),
args = popen_args,
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---