diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index af0ecded71..5d712fc271 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -10,6 +10,7 @@ Alexandre Vassalotti Craig Schlenter Daniel Andersson Daniel James +Erich Ocean Jan de Mooij Jay Freeman Joel Stanley diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 192dd25002..29ecccd7d8 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,32 @@ +2010-02-03: Version 2.1.0 + + Values are now always wrapped in objects when used as a receiver. + (issue 223). + + [ES5] Implemented Object.getOwnPropertyNames. + + [ES5] Restrict JSON.parse to only accept strings that conforms to the + JSON grammar. + + Improvement of debugger agent (issue 549 and 554). + + Fixed problem with skipped stack frame in profiles (issue 553). + + Solaris support by Erich Ocean and Ryan Dahl + . + + Fix a bug that Math.round() returns incorrect results for huge + integers. + + Fix enumeration order for objects created from some constructor + functions (isue http://crbug.com/3867). + + Fix arithmetic on some integer constants (issue 580). + + Numerous performance improvements including porting of previous IA-32 + optimizations to x64 and ARM architectures. + + 2010-01-14: Version 2.0.6 Added ES5 Object.getPrototypeOf, GetOwnPropertyDescriptor, diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index d68cec7c57..98fc22fba1 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -280,18 +280,12 @@ V8_EXTRA_FLAGS = { }, 'msvc': { 'all': { - 'WARNINGFLAGS': ['/WX', '/wd4355', '/wd4800'] + 'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800'] }, 'library:shared': { 'CPPDEFINES': ['BUILDING_V8_SHARED'], 'LIBS': ['winmm', 'ws2_32'] }, - 'arch:ia32': { - 'WARNINGFLAGS': ['/W3'] - }, - 'arch:x64': { - 'WARNINGFLAGS': ['/W3'] - }, 'arch:arm': { 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'], # /wd4996 is to silence the warning about sscanf @@ -317,7 +311,8 @@ MKSNAPSHOT_EXTRA_FLAGS = { 'LIBS': ['execinfo', 'pthread'] }, 'os:solaris': { - 'LIBS': ['pthread', 'socket', 'nsl', 'rt'] + 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], + 'LINKFLAGS': ['-mt'] }, 'os:openbsd': { 'LIBS': ['execinfo', 'pthread'] @@ -369,7 +364,8 @@ CCTEST_EXTRA_FLAGS = { 'LIBS': ['execinfo', 'pthread'] }, 'os:solaris': { - 'LIBS': ['pthread', 'socket', 'nsl', 'rt'] + 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], + 'LINKFLAGS': ['-mt'] }, 'os:openbsd': { 'LIBS': ['execinfo', 'pthread'] @@ -431,7 +427,8 @@ SAMPLE_FLAGS = { }, 'os:solaris': { 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['pthread', 'socket', 'nsl', 'rt'] + 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], + 'LINKFLAGS': ['-mt'] }, 'os:openbsd': { 'LIBPATH' : ['/usr/local/lib'], @@ -543,7 +540,8 @@ D8_FLAGS = { 'LIBS': ['pthread'], }, 'os:solaris': { - 'LIBS': ['pthread', 'socket', 'nsl', 'rt'] + 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], + 'LINKFLAGS': ['-mt'] }, 'os:openbsd': { 'LIBS': ['pthread'], @@ -693,7 +691,7 @@ SIMPLE_OPTIONS = { def GetOptions(): result = Options() result.Add('mode', 'compilation mode (debug, release)', 'release') - result.Add('sample', 'build sample (shell, process)', '') + result.Add('sample', 'build sample (shell, process, lineprocessor)', '') result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '') result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '') for (name, option) in SIMPLE_OPTIONS.iteritems(): @@ -761,7 +759,7 @@ def IsLegal(env, option, values): def VerifyOptions(env): if not IsLegal(env, 'mode', ['debug', 'release']): return False - if not IsLegal(env, 'sample', ["shell", "process"]): + if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]): return False if not IsLegal(env, 'regexp', ["native", "interpreted"]): return False diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h index 10b41e2368..2e5fb3fde9 100644 --- a/deps/v8/include/v8-debug.h +++ b/deps/v8/include/v8-debug.h @@ -224,9 +224,11 @@ class EXPORT Debug { * be processed. Note that debug messages will only be processed if there is * a V8 break. This can happen automatically by using the option * --debugger-auto-break. + * \param provide_locker requires that V8 acquires v8::Locker for you before + * calling handler */ static void SetDebugMessageDispatchHandler( - DebugMessageDispatchHandler handler); + DebugMessageDispatchHandler handler, bool provide_locker = false); /** * Run a JavaScript function in the debugger. @@ -263,6 +265,43 @@ class EXPORT Debug { */ static bool EnableAgent(const char* name, int port, bool wait_for_connection = false); + + /** + * Makes V8 process all pending debug messages. + * + * From V8 point of view all debug messages come asynchronously (e.g. from + * remote debugger) but they all must be handled synchronously: V8 cannot + * do 2 things at one time so normal script execution must be interrupted + * for a while. + * + * Generally when message arrives V8 may be in one of 3 states: + * 1. V8 is running script; V8 will automatically interrupt and process all + * pending messages (however auto_break flag should be enabled); + * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated + * to reading and processing debug messages; + * 3. V8 is not running at all or has called some long-working C++ function; + * by default it means that processing of all debug message will be deferred + * until V8 gets control again; however, embedding application may improve + * this by manually calling this method. + * + * It makes sense to call this method whenever a new debug message arrived and + * V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler + * should help with the former condition. + * + * Technically this method in many senses is equivalent to executing empty + * script: + * 1. It does nothing except for processing all pending debug messages. + * 2. It should be invoked with the same precautions and from the same context + * as V8 script would be invoked from, because: + * a. with "evaluate" command it can do whatever normal script can do, + * including all native calls; + * b. no other thread should call V8 while this method is running + * (v8::Locker may be used here). + * + * "Evaluate" debug command behavior currently is not specified in scope + * of this method. + */ + static void ProcessDebugMessages(); }; diff --git a/deps/v8/samples/lineprocessor.cc b/deps/v8/samples/lineprocessor.cc new file mode 100644 index 0000000000..505dabf945 --- /dev/null +++ b/deps/v8/samples/lineprocessor.cc @@ -0,0 +1,425 @@ +// Copyright 2009 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. + +#include +#include +#include +#include +#include +#include + +/** + * This sample program should demonstrate certain aspects of debugging + * standalone V8-based application. + * + * The program reads input stream, processes it line by line and print + * the result to output. The actual processing is done by custom JavaScript + * script. The script is specified with command line parameters. + * + * The main cycle of the program will sequentially read lines from standard + * input, process them and print to standard output until input closes. + * There are 2 possible configuration in regard to main cycle. + * + * 1. The main cycle is on C++ side. Program should be run with + * --main-cycle-in-cpp option. Script must declare a function named + * "ProcessLine". The main cycle in C++ reads lines and calls this function + * for processing every time. This is a sample script: + +function ProcessLine(input_line) { + return ">>>" + input_line + "<<<"; +} + + * + * 2. The main cycle is in JavaScript. Program should be run with + * --main-cycle-in-js option. Script gets run one time at all and gets + * API of 2 global functions: "read_line" and "print". It should read input + * and print converted lines to output itself. This a sample script: + +while (true) { + var line = read_line(); + if (!line) { + break; + } + var res = line + " | " + line; + print(res); +} + + * + * When run with "-p" argument, the program starts V8 Debugger Agent and + * allows remote debugger to attach and debug JavaScript code. + * + * Interesting aspects: + * 1. Wait for remote debugger to attach + * Normally the program compiles custom script and immediately runs it. + * If programmer needs to debug script from the very beginning, he should + * run this sample program with "--wait-for-connection" command line parameter. + * This way V8 will suspend on the first statement and wait for + * debugger to attach. + * + * 2. Unresponsive V8 + * V8 Debugger Agent holds a connection with remote debugger, but it does + * respond only when V8 is running some script. In particular, when this program + * is waiting for input, all requests from debugger get deferred until V8 + * is called again. See how "--callback" command-line parameter in this sample + * fixes this issue. + */ + +enum MainCycleType { + CycleInCpp, + CycleInJs +}; + +const char* ToCString(const v8::String::Utf8Value& value); +void ReportException(v8::TryCatch* handler); +v8::Handle ReadFile(const char* name); +v8::Handle ReadLine(); + +v8::Handle Print(const v8::Arguments& args); +v8::Handle ReadLine(const v8::Arguments& args); +bool RunCppCycle(v8::Handle script, v8::Local context, + bool report_exceptions); + +v8::Persistent debug_message_context; + + +void DispatchDebugMessages() { + // We are in some random thread. We should already have v8::Locker acquired + // (we requested this when registered this callback). We was called + // because new debug messages arrived; they may have already been processed, + // but we shouldn't worry about this. + // + // All we have to do is to set context and call ProcessDebugMessages. + // + // We should decide which V8 context to use here. This is important for + // "evaluate" command, because it must be executed some context. + // In our sample we have only one context, so there is nothing really to + // think about. + v8::Context::Scope scope(debug_message_context); + + v8::Debug::ProcessDebugMessages(); +} + + +int RunMain(int argc, char* argv[]) { + v8::V8::SetFlagsFromCommandLine(&argc, argv, true); + v8::HandleScope handle_scope; + + v8::Handle script_source(NULL); + v8::Handle script_name(NULL); + int script_param_counter = 0; + + int port_number = -1; + bool wait_for_connection = false; + bool support_callback = false; + MainCycleType cycle_type = CycleInCpp; + + for (int i = 1; i < argc; i++) { + const char* str = argv[i]; + if (strcmp(str, "-f") == 0) { + // Ignore any -f flags for compatibility with the other stand- + // alone JavaScript engines. + continue; + } else if (strcmp(str, "--callback") == 0) { + support_callback = true; + } else if (strcmp(str, "--wait-for-connection") == 0) { + wait_for_connection = true; + } else if (strcmp(str, "--main-cycle-in-cpp") == 0) { + cycle_type = CycleInCpp; + } else if (strcmp(str, "--main-cycle-in-js") == 0) { + cycle_type = CycleInJs; + } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { + port_number = atoi(argv[i + 1]); + i++; + } else if (strncmp(str, "--", 2) == 0) { + printf("Warning: unknown flag %s.\nTry --help for options\n", str); + } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { + script_source = v8::String::New(argv[i + 1]); + script_name = v8::String::New("unnamed"); + i++; + script_param_counter++; + } else { + // Use argument as a name of file to load. + script_source = ReadFile(str); + script_name = v8::String::New(str); + if (script_source.IsEmpty()) { + printf("Error reading '%s'\n", str); + return 1; + } + script_param_counter++; + } + } + + if (script_param_counter == 0) { + printf("Script is not specified\n"); + return 1; + } + if (script_param_counter != 1) { + printf("Only one script may be specified\n"); + return 1; + } + + // Create a template for the global object. + v8::Handle global = v8::ObjectTemplate::New(); + + // Bind the global 'print' function to the C++ Print callback. + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); + + if (cycle_type == CycleInJs) { + // Bind the global 'read_line' function to the C++ Print callback. + global->Set(v8::String::New("read_line"), + v8::FunctionTemplate::New(ReadLine)); + } + + // Create a new execution environment containing the built-in + // functions + v8::Handle context = v8::Context::New(NULL, global); + debug_message_context = v8::Persistent::New(context); + + + // Enter the newly created execution environment. + v8::Context::Scope context_scope(context); + + v8::Locker locker; + + if (support_callback) { + v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true); + } + + if (port_number != -1) { + const char* auto_break_param = "--debugger_auto_break"; + v8::V8::SetFlagsFromString(auto_break_param, strlen(auto_break_param)); + v8::Debug::EnableAgent("lineprocessor", port_number, wait_for_connection); + } + + bool report_exceptions = true; + + v8::Handle script; + { + // Compile script in try/catch context. + v8::TryCatch try_catch; + script = v8::Script::Compile(script_source, script_name); + if (script.IsEmpty()) { + // Print errors that happened during compilation. + if (report_exceptions) + ReportException(&try_catch); + return 1; + } + } + + { + v8::TryCatch try_catch; + + script->Run(); + if (try_catch.HasCaught()) { + if (report_exceptions) + ReportException(&try_catch); + return 1; + } + } + + if (cycle_type == CycleInCpp) { + bool res = RunCppCycle(script, v8::Context::GetCurrent(), + report_exceptions); + return !res; + } else { + // All is already done. + } + return 0; +} + + +bool RunCppCycle(v8::Handle script, v8::Local context, + bool report_exceptions) { + v8::Locker lock; + + v8::Handle fun_name = v8::String::New("ProcessLine"); + v8::Handle process_val = + v8::Context::GetCurrent()->Global()->Get(fun_name); + + // If there is no Process function, or if it is not a function, + // bail out + if (!process_val->IsFunction()) { + printf("Error: Script does not declare 'ProcessLine' global function.\n"); + return 1; + } + + // It is a function; cast it to a Function + v8::Handle process_fun = + v8::Handle::Cast(process_val); + + + while (!feof(stdin)) { + v8::HandleScope handle_scope; + + v8::Handle input_line = ReadLine(); + if (input_line == v8::Undefined()) { + continue; + } + + const int argc = 1; + v8::Handle argv[argc] = { input_line }; + + v8::Handle result; + { + v8::TryCatch try_catch; + result = process_fun->Call(v8::Context::GetCurrent()->Global(), + argc, argv); + if (try_catch.HasCaught()) { + if (report_exceptions) + ReportException(&try_catch); + return false; + } + } + v8::String::Utf8Value str(result); + const char* cstr = ToCString(str); + printf("%s\n", cstr); + } + + return true; +} + +int main(int argc, char* argv[]) { + int result = RunMain(argc, argv); + v8::V8::Dispose(); + return result; +} + + +// Extracts a C string from a V8 Utf8Value. +const char* ToCString(const v8::String::Utf8Value& value) { + return *value ? *value : ""; +} + + +// Reads a file into a v8 string. +v8::Handle ReadFile(const char* name) { + FILE* file = fopen(name, "rb"); + if (file == NULL) return v8::Handle(); + + fseek(file, 0, SEEK_END); + int size = ftell(file); + rewind(file); + + char* chars = new char[size + 1]; + chars[size] = '\0'; + for (int i = 0; i < size;) { + int read = fread(&chars[i], 1, size - i, file); + i += read; + } + fclose(file); + v8::Handle result = v8::String::New(chars, size); + delete[] chars; + return result; +} + + +void ReportException(v8::TryCatch* try_catch) { + v8::HandleScope handle_scope; + v8::String::Utf8Value exception(try_catch->Exception()); + const char* exception_string = ToCString(exception); + v8::Handle message = try_catch->Message(); + if (message.IsEmpty()) { + // V8 didn't provide any extra information about this error; just + // print the exception. + printf("%s\n", exception_string); + } else { + // Print (filename):(line number): (message). + v8::String::Utf8Value filename(message->GetScriptResourceName()); + const char* filename_string = ToCString(filename); + int linenum = message->GetLineNumber(); + printf("%s:%i: %s\n", filename_string, linenum, exception_string); + // Print line of source code. + v8::String::Utf8Value sourceline(message->GetSourceLine()); + const char* sourceline_string = ToCString(sourceline); + printf("%s\n", sourceline_string); + // Print wavy underline (GetUnderline is deprecated). + int start = message->GetStartColumn(); + for (int i = 0; i < start; i++) { + printf(" "); + } + int end = message->GetEndColumn(); + for (int i = start; i < end; i++) { + printf("^"); + } + printf("\n"); + } +} + + +// The callback that is invoked by v8 whenever the JavaScript 'print' +// function is called. Prints its arguments on stdout separated by +// spaces and ending with a newline. +v8::Handle Print(const v8::Arguments& args) { + bool first = true; + for (int i = 0; i < args.Length(); i++) { + v8::HandleScope handle_scope; + if (first) { + first = false; + } else { + printf(" "); + } + v8::String::Utf8Value str(args[i]); + const char* cstr = ToCString(str); + printf("%s", cstr); + } + printf("\n"); + fflush(stdout); + return v8::Undefined(); +} + + +// The callback that is invoked by v8 whenever the JavaScript 'read_line' +// function is called. Reads a string from standard input and returns. +v8::Handle ReadLine(const v8::Arguments& args) { + if (args.Length() > 0) { + return v8::ThrowException(v8::String::New("Unexpected arguments")); + } + return ReadLine(); +} + +v8::Handle ReadLine() { + const int kBufferSize = 1024 + 1; + char buffer[kBufferSize]; + + char* res; + { + v8::Unlocker unlocker; + res = fgets(buffer, kBufferSize, stdin); + } + if (res == NULL) { + v8::Handle t = v8::Undefined(); + return reinterpret_cast&>(t); + } + // remove newline char + for (char* pos = buffer; *pos != '\0'; pos++) { + if (*pos == '\n') { + *pos = '\0'; + break; + } + } + return v8::String::New(buffer); +} diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript index 9f8e4190bf..ebda77ac20 100755 --- a/deps/v8/src/SConscript +++ b/deps/v8/src/SConscript @@ -50,6 +50,7 @@ SOURCES = { contexts.cc conversions.cc counters.cc + data-flow.cc dateparser.cc debug-agent.cc debug.cc @@ -60,6 +61,7 @@ SOURCES = { flags.cc frame-element.cc frames.cc + full-codegen.cc func-name-inferrer.cc global-handles.cc handles.cc @@ -114,6 +116,7 @@ SOURCES = { arm/disasm-arm.cc arm/fast-codegen-arm.cc arm/frames-arm.cc + arm/full-codegen-arm.cc arm/ic-arm.cc arm/jump-target-arm.cc arm/macro-assembler-arm.cc @@ -137,6 +140,7 @@ SOURCES = { ia32/disasm-ia32.cc ia32/fast-codegen-ia32.cc ia32/frames-ia32.cc + ia32/full-codegen-ia32.cc ia32/ic-ia32.cc ia32/jump-target-ia32.cc ia32/macro-assembler-ia32.cc @@ -154,6 +158,7 @@ SOURCES = { x64/disasm-x64.cc x64/fast-codegen-x64.cc x64/frames-x64.cc + x64/full-codegen-x64.cc x64/ic-x64.cc x64/jump-target-x64.cc x64/macro-assembler-x64.cc @@ -239,7 +244,7 @@ def ConfigureObjectFiles(): env.Replace(**context.flags['v8']) context.ApplyEnvOverrides(env) env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C) - env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE"') + env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions') # Build the standard platform-independent source files. source_files = context.GetRelevantSources(SOURCES) diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc index 56cf135981..5a029285e8 100644 --- a/deps/v8/src/accessors.cc +++ b/deps/v8/src/accessors.cc @@ -493,11 +493,11 @@ Object* Accessors::FunctionGetLength(Object* object, void*) { // If the function isn't compiled yet, the length is not computed // correctly yet. Compile it now and return the right length. HandleScope scope; - Handle function_handle(function); - if (!CompileLazy(function_handle, KEEP_EXCEPTION)) { + Handle shared(function->shared()); + if (!CompileLazyShared(shared, KEEP_EXCEPTION)) { return Failure::Exception(); } - return Smi::FromInt(function_handle->shared()->length()); + return Smi::FromInt(shared->length()); } else { return Smi::FromInt(function->shared()->length()); } diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index ab5d0a5608..322c90fc5a 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -3669,7 +3669,6 @@ void Debug::SetMessageHandler(v8::Debug::MessageHandler handler, void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) { EnsureInitialized("v8::Debug::SetMessageHandler"); ENTER_V8; - HandleScope scope; i::Debugger::SetMessageHandler(handler); } @@ -3691,10 +3690,10 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler, void Debug::SetDebugMessageDispatchHandler( - DebugMessageDispatchHandler handler) { + DebugMessageDispatchHandler handler, bool provide_locker) { EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler"); ENTER_V8; - i::Debugger::SetDebugMessageDispatchHandler(handler); + i::Debugger::SetDebugMessageDispatchHandler(handler, provide_locker); } @@ -3744,6 +3743,11 @@ Local Debug::GetMirror(v8::Handle obj) { bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) { return i::Debugger::StartAgent(name, port, wait_for_connection); } + +void Debug::ProcessDebugMessages() { + i::Execution::ProcessDebugMesssages(true); +} + #endif // ENABLE_DEBUGGER_SUPPORT namespace internal { diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h index fd2fcd3059..354436cb14 100644 --- a/deps/v8/src/arm/assembler-arm-inl.h +++ b/deps/v8/src/arm/assembler-arm-inl.h @@ -174,20 +174,6 @@ Operand::Operand(const ExternalReference& f) { } -Operand::Operand(Object** opp) { - rm_ = no_reg; - imm32_ = reinterpret_cast(opp); - rmode_ = RelocInfo::NONE; -} - - -Operand::Operand(Context** cpp) { - rm_ = no_reg; - imm32_ = reinterpret_cast(cpp); - rmode_ = RelocInfo::NONE; -} - - Operand::Operand(Smi* value) { rm_ = no_reg; imm32_ = reinterpret_cast(value); diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index 07da800903..74547be6e2 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -30,9 +30,9 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. -// The original source code covered by the above license above has been modified -// significantly by Google Inc. -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// 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. #include "v8.h" @@ -1371,6 +1371,36 @@ void Assembler::stc2(Coprocessor coproc, // Support for VFP. +void Assembler::vldr(const DwVfpRegister dst, + const Register base, + int offset, + const Condition cond) { + // Ddst = MEM(Rbase + offset). + // Instruction details available in ARM DDI 0406A, A8-628. + // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) | + // Vdst(15-12) | 1011(11-8) | offset + ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(offset % 4 == 0); + emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 | + 0xB*B8 | ((offset / 4) & 255)); +} + + +void Assembler::vstr(const DwVfpRegister src, + const Register base, + int offset, + const Condition cond) { + // MEM(Rbase + offset) = Dsrc. + // Instruction details available in ARM DDI 0406A, A8-786. + // cond(31-28) | 1101(27-24)| 1000(23-20) | | Rbase(19-16) | + // Vsrc(15-12) | 1011(11-8) | (offset/4) + ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(offset % 4 == 0); + emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 | + 0xB*B8 | ((offset / 4) & 255)); +} + + void Assembler::vmov(const DwVfpRegister dst, const Register src1, const Register src2, diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index cd53dd6097..208d583ce1 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -30,9 +30,9 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. -// The original source code covered by the above license above has been modified -// significantly by Google Inc. -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// 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. // A light-weight ARM Assembler // Generates user mode instructions for the ARM architecture up to version 5 @@ -398,8 +398,6 @@ class Operand BASE_EMBEDDED { RelocInfo::Mode rmode = RelocInfo::NONE)); INLINE(explicit Operand(const ExternalReference& f)); INLINE(explicit Operand(const char* s)); - INLINE(explicit Operand(Object** opp)); - INLINE(explicit Operand(Context** cpp)); explicit Operand(Handle handle); INLINE(explicit Operand(Smi* value)); @@ -796,6 +794,14 @@ class Assembler : public Malloced { // However, some simple modifications can allow // these APIs to support D16 to D31. + void vldr(const DwVfpRegister dst, + const Register base, + int offset, // Offset must be a multiple of 4. + const Condition cond = al); + void vstr(const DwVfpRegister src, + const Register base, + int offset, // Offset must be a multiple of 4. + const Condition cond = al); void vmov(const DwVfpRegister dst, const Register src1, const Register src2, diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index 5389a3c5f5..ae7dae3b08 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -38,15 +38,32 @@ namespace internal { #define __ ACCESS_MASM(masm) -void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { - // TODO(428): Don't pass the function in a static variable. - __ mov(ip, Operand(ExternalReference::builtin_passed_function())); - __ str(r1, MemOperand(ip, 0)); - - // The actual argument count has already been loaded into register - // r0, but JumpToRuntime expects r0 to contain the number of - // arguments including the receiver. - __ add(r0, r0, Operand(1)); +void Builtins::Generate_Adaptor(MacroAssembler* masm, + CFunctionId id, + BuiltinExtraArguments extra_args) { + // ----------- S t a t e ------------- + // -- r0 : number of arguments excluding receiver + // -- r1 : called function (only guaranteed when + // extra_args requires it) + // -- cp : context + // -- sp[0] : last argument + // -- ... + // -- sp[4 * (argc - 1)] : first argument (argc == r0) + // -- sp[4 * argc] : receiver + // ----------------------------------- + + // Insert extra arguments. + int num_extra_args = 0; + if (extra_args == NEEDS_CALLED_FUNCTION) { + num_extra_args = 1; + __ push(r1); + } else { + ASSERT(extra_args == NO_EXTRA_ARGUMENTS); + } + + // JumpToRuntime expects r0 to contain the number of arguments + // including the receiver and the extra arguments. + __ add(r0, r0, Operand(num_extra_args + 1)); __ JumpToRuntime(ExternalReference(id)); } @@ -491,7 +508,8 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { } -void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { +static void Generate_JSConstructStubHelper(MacroAssembler* masm, + bool is_api_function) { // Enter a construct frame. __ EnterConstructFrame(); @@ -727,8 +745,17 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // Call the function. // r0: number of arguments // r1: constructor function - ParameterCount actual(r0); - __ InvokeFunction(r1, actual, CALL_FUNCTION); + if (is_api_function) { + __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); + Handle code = Handle( + Builtins::builtin(Builtins::HandleApiCallConstruct)); + ParameterCount expected(0); + __ InvokeCode(code, expected, expected, + RelocInfo::CODE_TARGET, CALL_FUNCTION); + } else { + ParameterCount actual(r0); + __ InvokeFunction(r1, actual, CALL_FUNCTION); + } // Pop the function from the stack. // sp[0]: constructor function @@ -783,6 +810,16 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { } +void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { + Generate_JSConstructStubHelper(masm, false); +} + + +void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { + Generate_JSConstructStubHelper(masm, true); +} + + static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, bool is_construct) { // Called from Generate_JS_Entry diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index 70d8ab4955..ea4b165fd3 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -1,4 +1,4 @@ -// Copyright 2006-2009 the V8 project authors. All rights reserved. +// Copyright 2010 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: @@ -47,7 +47,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Condition cc, bool never_nan_nan); static void EmitSmiNonsmiComparison(MacroAssembler* masm, - Label* rhs_not_nan, + Label* lhs_not_nan, Label* slow, bool strict); static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc); @@ -121,12 +121,13 @@ CodeGenState::~CodeGenState() { // ------------------------------------------------------------------------- // CodeGenerator implementation -CodeGenerator::CodeGenerator(int buffer_size, Handle