Changed shell sample to take flags directly from the command-line. Added api...

Changed shell sample to take flags directly from the command-line.  Added api call that implements this.

Added better test support.

Added load, quit and version functions to the shell sample so it's easier to run benchmarks and tests.



git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c42f5829
......@@ -28,6 +28,7 @@
import platform
import re
import sys
import os
from os.path import join, dirname, abspath
root_dir = dirname(File('SConstruct').rfile().abspath)
sys.path.append(join(root_dir, 'tools'))
......@@ -41,7 +42,8 @@ LIBRARY_FLAGS = {
'gcc': {
'all': {
'DIALECTFLAGS': ['-ansi'],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS',
'-fno-strict-aliasing'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LIBS': ['pthread']
},
......@@ -52,6 +54,9 @@ LIBRARY_FLAGS = {
'mode:release': {
'CCFLAGS': ['-O2']
},
'wordsize:64': {
'CCFLAGS': ['-m32']
},
},
'msvc': {
'all': {
......@@ -83,10 +88,13 @@ LIBRARY_FLAGS = {
V8_EXTRA_FLAGS = {
'gcc': {
'all': {
'CXXFLAGS': ['-fvisibility=hidden'],
'CXXFLAGS': [], #['-fvisibility=hidden'],
'WARNINGFLAGS': ['-pedantic', '-Wall', '-Werror', '-W',
'-Wno-unused-parameter']
},
'arch:arm': {
'CPPDEFINES': ['ARM']
},
},
'msvc': {
'all': {
......@@ -95,6 +103,9 @@ V8_EXTRA_FLAGS = {
'library:shared': {
'CPPDEFINES': ['BUILDING_V8_SHARED']
},
'arch:arm': {
'CPPDEFINES': ['ARM']
},
}
}
......@@ -143,6 +154,9 @@ CCTEST_EXTRA_FLAGS = {
}
},
'msvc': {
'all': {
'CPPDEFINES': ['_HAS_EXCEPTIONS=0']
},
'library:shared': {
'CPPDEFINES': ['USING_V8_SHARED']
}
......@@ -198,17 +212,24 @@ def GuessOS():
elif id == 'Windows':
return 'win32'
else:
return '<none>'
return None
def GuessProcessor():
def GuessArchitecture():
id = platform.machine()
if id.startswith('arm'):
return 'arm'
elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
return 'ia32'
else:
return '<none>'
return None
def GuessWordsize():
if '64' in platform.machine():
return '64'
else:
return '32'
def GuessToolchain(os):
......@@ -218,21 +239,61 @@ def GuessToolchain(os):
elif 'msvc' in tools:
return 'msvc'
else:
return '<none>'
return None
OS_GUESS = GuessOS()
TOOLCHAIN_GUESS = GuessToolchain(OS_GUESS)
ARCH_GUESS = GuessArchitecture()
WORDSIZE_GUESS = GuessWordsize()
SIMPLE_OPTIONS = {
'toolchain': {
'values': ['gcc', 'msvc'],
'default': TOOLCHAIN_GUESS,
'help': 'the toolchain to use'
},
'os': {
'values': ['linux', 'macos', 'win32'],
'default': OS_GUESS,
'help': 'the os to build for'
},
'arch': {
'values':['arm', 'ia32'],
'default': ARCH_GUESS,
'help': 'the architecture to build for'
},
'snapshot': {
'values': ['on', 'off'],
'default': 'off',
'help': 'build using snapshots for faster start-up'
},
'library': {
'values': ['static', 'shared', 'default'],
'default': 'default',
'help': 'the type of library to produce'
},
'wordsize': {
'values': ['64', '32'],
'default': WORDSIZE_GUESS,
'help': 'the word size'
},
'simulator': {
'values': ['arm', 'none'],
'default': 'none',
'help': 'build with simulator'
}
}
def GetOptions():
result = Options()
os_guess = GuessOS()
toolchain_guess = GuessToolchain(os_guess)
processor_guess = GuessProcessor()
result.Add('mode', 'compilation mode (debug, release)', 'release')
result.Add('toolchain', 'the toolchain to use (gcc, msvc)', toolchain_guess)
result.Add('os', 'the os to build for (linux, macos, win32)', os_guess)
result.Add('processor', 'the processor to build for (arm, ia32)', processor_guess)
result.Add('snapshot', 'build using snapshots for faster start-up (on, off)', 'off')
result.Add('library', 'which type of library to produce (static, shared, default)', 'default')
result.Add('sample', 'build sample (shell, process)', '')
for (name, option) in SIMPLE_OPTIONS.items():
help = '%s (%s)' % (name, ", ".join(option['values']))
result.Add(name, help, option.get('default'))
return result
......@@ -252,51 +313,46 @@ def IsLegal(env, option, values):
def VerifyOptions(env):
if not IsLegal(env, 'mode', ['debug', 'release']):
return False
if not env['toolchain'] in ['gcc', 'msvc']:
Abort("Unknown toolchain '%s'." % env['toolchain'])
if not env['os'] in ['linux', 'macos', 'win32']:
Abort("Unknown os '%s'." % env['os'])
if not env['processor'] in ['arm', 'ia32']:
Abort("Unknown processor '%s'." % env['processor'])
if not env['snapshot'] in ['on', 'off']:
Abort("Illegal value for option snapshot: '%s'." % env['snapshot'])
if not env['library'] in ['static', 'shared', 'default']:
Abort("Illegal value for option library: '%s'." % env['library'])
if not IsLegal(env, 'sample', ["shell", "process"]):
return False
for (name, option) in SIMPLE_OPTIONS.items():
if (not option.get('default')) and (name not in ARGUMENTS):
message = ("A value for option %s must be specified (%s)." %
(name, ", ".join(option['values'])))
Abort(message)
if not env[name] in option['values']:
message = ("Unknown %s value '%s'. Possible values are (%s)." %
(name, env[name], ", ".join(option['values'])))
Abort(message)
class BuildContext(object):
def __init__(self, os, arch, toolchain, snapshot, library, samples, mode):
def __init__(self, options, samples):
self.library_targets = []
self.cctest_targets = []
self.sample_targets = []
self.os = os
self.arch = arch
self.toolchain = toolchain
self.snapshot = snapshot
self.library = library
self.options = options
self.samples = samples
self.mode = mode
self.use_snapshot = (snapshot == 'on')
self.use_snapshot = (options['snapshot'] == 'on')
self.flags = None
def AddRelevantFlags(self, initial, flags):
result = initial.copy()
self.AppendFlags(result, flags.get('all'))
self.AppendFlags(result, flags[self.toolchain].get('all'))
self.AppendFlags(result, flags[self.toolchain].get('mode:' + self.mode))
self.AppendFlags(result, flags[self.toolchain].get('library:' + self.library))
toolchain = self.options['toolchain']
self.AppendFlags(result, flags[toolchain].get('all'))
for option in sorted(self.options.keys()):
value = self.options[option]
self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
return result
def GetRelevantSources(self, source):
result = []
result += source.get('all', [])
result += source.get('arch:' + self.arch, [])
result += source.get('os:' + self.os, [])
result += source.get('mode:' + self.mode, [])
return result
for (name, value) in self.options.items():
result += source.get(name + ':' + value, [])
return sorted(result)
def AppendFlags(self, options, added):
if not added:
......@@ -306,28 +362,39 @@ class BuildContext(object):
options[key] = value
else:
options[key] = options[key] + value
def ConfigureObject(self, env, input, **kw):
if self.library == 'static':
if self.options['library'] == 'static':
return env.StaticObject(input, **kw)
elif self.library == 'shared':
elif self.options['library'] == 'shared':
return env.SharedObject(input, **kw)
else:
return env.Object(input, **kw)
def PostprocessOptions(options):
# Adjust architecture if the simulator option has been set
if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
if 'arch' in ARGUMENTS:
# Print a warning if arch has explicitly been set
print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
options['arch'] = options['simulator']
def BuildSpecific(env, mode):
context = BuildContext(os=env['os'], arch=env['processor'],
toolchain=env['toolchain'], snapshot=env['snapshot'],
library=env['library'], samples=SplitList(env['sample']),
mode=mode)
options = {'mode': mode}
for option in SIMPLE_OPTIONS:
options[option] = env[option]
PostprocessOptions(options)
context = BuildContext(options, samples=SplitList(env['sample']))
library_flags = context.AddRelevantFlags({}, LIBRARY_FLAGS)
library_flags = context.AddRelevantFlags(os.environ, LIBRARY_FLAGS)
v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
jscre_flags = context.AddRelevantFlags(library_flags, JSCRE_EXTRA_FLAGS)
dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
sample_flags = context.AddRelevantFlags({}, SAMPLE_FLAGS)
sample_flags = context.AddRelevantFlags(os.environ, SAMPLE_FLAGS)
context.flags = {
'v8': v8_flags,
......@@ -351,9 +418,9 @@ def BuildSpecific(env, mode):
)
# Link the object files into a library.
if context.library == 'static':
if context.options['library'] == 'static':
library = env.StaticLibrary(library_name, object_files)
elif context.library == 'shared':
elif context.options['library'] == 'shared':
# There seems to be a glitch in the way scons decides where to put
# PDB files when compiling using MSVC so we specify it manually.
# This should not affect any other platforms.
......
......@@ -1673,6 +1673,14 @@ class EXPORT V8 {
*/
static void SetFlagsFromString(const char* str, int length);
/**
* Sets v8 flags from command line.
* TODO(758124): Describe flags?
*/
static void SetFlagsFromCommandLine(int* argc,
char** argv,
bool remove_flags);
/** Get the version string. */
static const char* GetVersion();
......
......@@ -62,7 +62,7 @@ class HttpRequestProcessor {
// Initialize this processor. The map contains options that control
// how requests should be processed.
virtual bool Initialize(map<string, string>* options,
map<string, string>* output) = 0;
map<string, string>* output) = 0;
// Process a single request.
virtual bool Process(HttpRequest* req) = 0;
......@@ -78,17 +78,17 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
// Creates a new processor that processes requests by invoking the
// Process function of the JavaScript script given as an argument.
JsHttpRequestProcessor(Handle<String> script) : script_(script) { }
explicit JsHttpRequestProcessor(Handle<String> script) : script_(script) { }
virtual ~JsHttpRequestProcessor();
virtual bool Initialize(map<string, string>* opts,
map<string, string>* output);
map<string, string>* output);
virtual bool Process(HttpRequest* req);
private:
// Execute the script associated with this processor and extract the
// Process function. Returns true if this succeeded, otherwise false.
// Execute the script associated with this processor and extract the
// Process function. Returns true if this succeeded, otherwise false.
bool ExecuteScript(Handle<String> script);
// Wrap the options and output map in a JavaScript objects and
......@@ -108,8 +108,9 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
// Callbacks that access maps
static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info);
static Handle<Value> MapSet(Local<String> name, Local<Value> value,
const AccessorInfo& info);
static Handle<Value> MapSet(Local<String> name,
Local<Value> value,
const AccessorInfo& info);
// Utility methods for wrapping C++ objects as JavaScript objects,
// and going back again.
......@@ -142,7 +143,7 @@ static Handle<Value> LogCallback(const Arguments& args) {
// Execute the script and fetch the Process method.
bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
map<string, string>* output) {
map<string, string>* output) {
// Create a handle scope to hold the temporary references.
HandleScope handle_scope;
......@@ -223,7 +224,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts,
map<string, string>* output) {
map<string, string>* output) {
HandleScope handle_scope;
// Wrap the map object in a JavaScript wrapper
......@@ -335,7 +336,7 @@ string ObjectToString(Local<Value> value) {
Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
const AccessorInfo& info) {
const AccessorInfo& info) {
// Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder());
......@@ -355,7 +356,8 @@ Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
Handle<Value> JsHttpRequestProcessor::MapSet(Local<String> name,
Local<Value> value_obj, const AccessorInfo& info) {
Local<Value> value_obj,
const AccessorInfo& info) {
// Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder());
......@@ -433,7 +435,7 @@ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Handle<Object> obj) {
Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
const AccessorInfo& info) {
const AccessorInfo& info) {
// Extract the C++ request object from the JavaScript wrapper.
HttpRequest* request = UnwrapRequest(info.Holder());
......@@ -446,7 +448,7 @@ Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
const AccessorInfo& info) {
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Referrer();
return String::New(path.c_str(), path.length());
......@@ -454,7 +456,7 @@ Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
const AccessorInfo& info) {
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Host();
return String::New(path.c_str(), path.length());
......@@ -462,7 +464,7 @@ Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name,
const AccessorInfo& info) {
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->UserAgent();
return String::New(path.c_str(), path.length());
......@@ -499,8 +501,10 @@ void HttpRequestProcessor::Log(const char* event) {
*/
class StringHttpRequest : public HttpRequest {
public:
StringHttpRequest(const string& path, const string& referrer,
const string& host, const string& user_agent);
StringHttpRequest(const string& path,
const string& referrer,
const string& host,
const string& user_agent);
virtual const string& Path() { return path_; }
virtual const string& Referrer() { return referrer_; }
virtual const string& Host() { return host_; }
......@@ -514,15 +518,19 @@ class StringHttpRequest : public HttpRequest {
StringHttpRequest::StringHttpRequest(const string& path,
const string& referrer, const string& host, const string& user_agent)
const string& referrer,
const string& host,
const string& user_agent)
: path_(path),
referrer_(referrer),
host_(host),
user_agent_(user_agent) { }
void ParseOptions(int argc, char* argv[], map<string, string>& options,
string* file) {
void ParseOptions(int argc,
char* argv[],
map<string, string>& options,
string* file) {
for (int i = 1; i < argc; i++) {
string arg = argv[i];
int index = arg.find('=', 0);
......@@ -571,7 +579,7 @@ StringHttpRequest kSampleRequests[kSampleSize] = {
bool ProcessEntries(HttpRequestProcessor* processor, int count,
StringHttpRequest* reqs) {
StringHttpRequest* reqs) {
for (int i = 0; i < count; i++) {
if (!processor->Process(&reqs[i]))
return false;
......
......@@ -28,6 +28,7 @@
#include <v8.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
void RunShell(v8::Handle<v8::Context> context);
......@@ -35,18 +36,28 @@ bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name,
bool print_result);
v8::Handle<v8::Value> Print(const v8::Arguments& args);
v8::Handle<v8::Value> Load(const v8::Arguments& args);
v8::Handle<v8::Value> Quit(const v8::Arguments& args);
v8::Handle<v8::Value> Version(const v8::Arguments& args);
v8::Handle<v8::String> ReadFile(const char* name);
void ProcessRuntimeFlags(int argc, char* argv[]);
int main(int argc, char* argv[]) {
ProcessRuntimeFlags(argc, argv);
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
v8::HandleScope handle_scope;
// Create a template for the global object.
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the global 'print' function to the C++ Print callback.
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
// Create a new execution environment containing the 'print' function.
// Bind the global 'load' function to the C++ Load callback.
global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
// Bind the 'quit' function
global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
// Bind the 'version' function
global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
// Create a new execution environment containing the built-in
// functions
v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
// Enter the newly created execution environment.
v8::Context::Scope context_scope(context);
......@@ -55,9 +66,8 @@ int main(int argc, char* argv[]) {
const char* str = argv[i];
if (strcmp(str, "--shell") == 0) {
run_shell = true;
} else if (strcmp(str, "--runtime-flags") == 0) {
// Skip the --runtime-flags flag since it was processed earlier.
i++;
} else if (strncmp(str, "--", 2) == 0) {
printf("Warning: unknown flag %s.\n", str);
} else {
// Use all other arguments as names of files to load and run.
v8::HandleScope handle_scope;
......@@ -93,6 +103,39 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
}
// The callback that is invoked by v8 whenever the JavaScript 'load'
// function is called. Loads, compiles and executes its argument
// JavaScript file.
v8::Handle<v8::Value> Load(const v8::Arguments& args) {
for (int i = 0; i < args.Length(); i++) {
v8::HandleScope handle_scope;
v8::String::AsciiValue file(args[i]);
v8::Handle<v8::String> source = ReadFile(*file);
if (source.IsEmpty()) {
return v8::ThrowException(v8::String::New("Error loading file"));
}
ExecuteString(source, v8::String::New(*file), false);
}
return v8::Undefined();
}
// The callback that is invoked by v8 whenever the JavaScript 'quit'
// function is called. Quits.
v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
// If not arguments are given args[0] will yield undefined which
// converts to the integer value 0.
int exit_code = args[0]->Int32Value();
exit(exit_code);
return v8::Undefined();
}
v8::Handle<v8::Value> Version(const v8::Arguments& args) {
return v8::String::New(v8::V8::GetVersion());
}
// Reads a file into a v8 string.
v8::Handle<v8::String> ReadFile(const char* name) {
FILE* file = fopen(name, "rb");
......@@ -161,14 +204,3 @@ bool ExecuteString(v8::Handle<v8::String> source,
}
}
}
// Set the vm flags before using the vm.
void ProcessRuntimeFlags(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--runtime-flags") == 0 && i + 1 < argc) {
i++;
v8::V8::SetFlagsFromString(argv[i], strlen(argv[i]));
}
}
}
......@@ -50,10 +50,11 @@ SOURCES = {
],
'arch:arm': ['assembler-arm.cc', 'builtins-arm.cc', 'codegen-arm.cc',
'cpu-arm.cc', 'disasm-arm.cc', 'frames-arm.cc', 'ic-arm.cc',
'macro-assembler-arm.cc', 'simulator-arm.cc', 'stub-cache-arm.cc'],
'macro-assembler-arm.cc', 'stub-cache-arm.cc'],
'arch:ia32': ['assembler-ia32.cc', 'builtins-ia32.cc', 'codegen-ia32.cc',
'cpu-ia32.cc', 'disasm-ia32.cc', 'frames-ia32.cc', 'ic-ia32.cc',
'macro-assembler-ia32.cc', 'simulator-ia32.cc', 'stub-cache-ia32.cc'],
'macro-assembler-ia32.cc', 'stub-cache-ia32.cc'],
'simulator:arm': ['simulator-arm.cc'],
'os:linux': ['platform-linux.cc'],
'os:macos': ['platform-macos.cc'],
'os:nullos': ['platform-nullos.cc'],
......
......@@ -223,6 +223,11 @@ void V8::SetFlagsFromString(const char* str, int length) {
}
void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
}
v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
if (IsDeadCheck("v8::ThrowException()")) return v8::Handle<Value>();
i::Top::ScheduleThrow(*Utils::OpenHandle(*value));
......
// Copyright 2007-2008 Google Inc. All Rights Reserved.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 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.
//
// - Redistribution 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.
//
// * 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.
// - Neither the name of Sun Microsystems or the names of 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.
// 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.
// The original source code covered by the above license above has been modified
// significantly by Google Inc.
// Copyright 2006-2008 Google Inc. All Rights Reserved.
#ifndef V8_ASSEMBLER_ARM_INL_H_
#define V8_ASSEMBLER_ARM_INL_H_
......
// Copyright 2006-2008 Google Inc. All Rights Reserved.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 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 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.
// - Redistribution 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 Sun Microsystems or the names of 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.
// 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.
// The original source code covered by the above license above has been modified
// significantly by Google Inc.
// Copyright 2006-2008 Google Inc. All Rights Reserved.
#include "v8.h"
......
// Copyright 2007-2008 Google Inc. All Rights Reserved.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 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.
//
// - Redistribution 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.
//
// * 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.
// - Neither the name of Sun Microsystems or the names of 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.
// 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.
// The original source code covered by the above license above has been modified
// significantly by Google Inc.
// Copyright 2006-2008 Google Inc. All Rights Reserved.
// A light-weight ARM Assembler
// Generates user mode instructions for the ARM architecture up to version 5
......
......@@ -379,9 +379,9 @@ Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
// Add prototype.
PropertyAttributes attributes = static_cast<PropertyAttributes>(
(make_prototype_enumerable ? 0 : DONT_ENUM)
| DONT_DELETE
| (make_prototype_read_only ? READ_ONLY : 0));
(make_prototype_enumerable ? 0 : DONT_ENUM)
| DONT_DELETE
| (make_prototype_read_only ? READ_ONLY : 0));
result =
Factory::CopyAppendProxyDescriptor(
result,
......@@ -481,8 +481,8 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
global_context()->set_initial_object_prototype(*prototype);
SetPrototype(object_fun, prototype);
object_function_map->set_instance_descriptors(
DescriptorArray::cast(Heap::empty_fixed_array()));
object_function_map->
set_instance_descriptors(Heap::empty_descriptor_array());
}
// Allocate the empty function as the prototype for function ECMAScript
......@@ -1192,7 +1192,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
// Ignore map transitions.
case NULL_DESCRIPTOR:
// Ignore non-properties.
break;
case NORMAL:
// Do not occur since the from object has fast properties.
......
......@@ -352,7 +352,7 @@ BUILTIN_0(HandleApiCall) {
HandleScope scope;
// TODO(1238487): This is not nice. We need to get rid of this
// retarded behavior and start handling API calls in a more direct
// kludgy behavior and start handling API calls in a more direct
// way - maybe compile specialized stubs lazily?.
#ifdef USE_OLD_CALLING_CONVENTIONS
Handle<JSFunction> function =
......
This diff is collapsed.
......@@ -555,8 +555,7 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
Handle<JSObject> Factory::NewObjectLiteral(int expected_number_of_properties) {
Handle<Map> map = Handle<Map>(Top::object_function()->initial_map());
map = Factory::CopyMap(map);
map->set_instance_descriptors(
DescriptorArray::cast(Heap::empty_fixed_array()));
map->set_instance_descriptors(Heap::empty_descriptor_array());
map->set_unused_property_fields(expected_number_of_properties);
CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, TENURED),
JSObject);
......@@ -704,7 +703,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
if (parent->IsUndefined()) break;
obj = Handle<FunctionTemplateInfo>::cast(parent);
}
if (array->length() > 0) {
if (!array->IsEmpty()) {
map->set_instance_descriptors(*array);
}
......
......@@ -281,10 +281,6 @@ class Factory : public AllStatic {
SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
static Handle<DescriptorArray> empty_descriptor_array() {
return Handle<DescriptorArray>::cast(empty_fixed_array());
}
static Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
static Handle<Dictionary> DictionaryAtNumberPut(Handle<Dictionary>,
......
......@@ -301,8 +301,16 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
// lookup the flag
Flag* flag = Lookup(name);
if (flag == NULL) {
fprintf(stderr, "Error: unrecognized flag %s\n", arg);
return j;
if (remove_flags) {
// We don't recognize this flag but since we're removing
// the flags we recognize we assume that the remaining flags
// will be processed somewhere else so this flag might make
// sense there.
continue;
} else {
fprintf(stderr, "Error: unrecognized flag %s\n", arg);
return j;
}
}
// if we still need a flag value, use the next argument if available
......
......@@ -304,7 +304,8 @@ enum PropertyType {
FIELD = 3, // only in fast mode
CALLBACKS = 4,
CONSTANT_TRANSITION = 5, // only in fast mode
INTERCEPTOR = 6
INTERCEPTOR = 6,
NULL_DESCRIPTOR = 7 // only in fast mode
};
......
......@@ -160,14 +160,6 @@ void Heap::RecordWrite(Address address, int offset) {
}
Object* Heap::AllocatePropertyStorageForMap(Map* map) {
if (map->unused_property_fields() > 0) {
return AllocateFixedArray(map->unused_property_fields());
}
return Heap::empty_fixed_array();
}
AllocationSpace Heap::TargetSpace(HeapObject* object) {
// Heap numbers and sequential strings are promoted to code space, all
// other object types are promoted to old space. We do not use
......
......@@ -861,7 +861,7 @@ Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
map->set_prototype(null_value());
map->set_constructor(null_value());
map->set_instance_size(instance_size);
map->set_instance_descriptors(DescriptorArray::cast(empty_fixed_array()));
map->set_instance_descriptors(empty_descriptor_array());
map->set_code_cache(empty_fixed_array());
map->set_unused_property_fields(0);
map->set_bit_field(0);
......@@ -894,17 +894,20 @@ bool Heap::CreateInitialMaps() {
if (obj->IsFailure()) return false;
null_value_ = obj;
// Fix the instance_descriptors for the existing maps.
DescriptorArray* empty_descriptors =
DescriptorArray::cast(empty_fixed_array());
// Allocate the empty descriptor array. AllocateMap can now be used.
obj = AllocateEmptyFixedArray();
if (obj->IsFailure()) return false;
// There is a check against empty_descriptor_array() in cast().
empty_descriptor_array_ = reinterpret_cast<DescriptorArray*>(obj);
meta_map()->set_instance_descriptors(empty_descriptors);
// Fix the instance_descriptors for the existing maps.
meta_map()->set_instance_descriptors(empty_descriptor_array());
meta_map()->set_code_cache(empty_fixed_array());
fixed_array_map()->set_instance_descriptors(empty_descriptors);
fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
fixed_array_map()->set_code_cache(empty_fixed_array());
oddball_map()->set_instance_descriptors(empty_descriptors);
oddball_map()->set_instance_descriptors(empty_descriptor_array());
oddball_map()->set_code_cache(empty_fixed_array());
// Fix prototype object for existing maps.
......@@ -1004,6 +1007,7 @@ bool Heap::CreateInitialMaps() {
if (obj->IsFailure()) return false;
shared_function_info_map_ = Map::cast(obj);
ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
return true;
}
......@@ -1701,7 +1705,7 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
ASSERT(map->instance_type() != JS_FUNCTION_TYPE);
// Allocate the backing storage for the properties.
Object* properties = AllocatePropertyStorageForMap(map);
Object* properties = AllocateFixedArray(map->unused_property_fields());
if (properties->IsFailure()) return properties;
// Allocate the JSObject.
......@@ -1749,7 +1753,7 @@ Object* Heap::ReinitializeJSGlobalObject(JSFunction* constructor,
ASSERT(map->instance_size() == object->map()->instance_size());
// Allocate the backing storage for the properties.
Object* properties = AllocatePropertyStorageForMap(map);
Object* properties = AllocateFixedArray(map->unused_property_fields());
if (properties->IsFailure()) return properties;
// Reset the map for the object.
......
......@@ -112,6 +112,7 @@ namespace v8 { namespace internal {
V(Object, false_value) \
V(String, empty_string) \
V(FixedArray, empty_fixed_array) \
V(DescriptorArray, empty_descriptor_array) \
V(Object, the_hole_value) \
V(Map, neander_map) \
V(JSObject, message_listeners) \
......@@ -811,10 +812,6 @@ class Heap : public AllStatic {
// inlined).
static inline Object* AllocateRawMap(int size_in_bytes);
// Allocate storage for JSObject properties.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
static inline Object* AllocatePropertyStorageForMap(Map* map);
// Initializes a JSObject based on its map.
static void InitializeJSObjectFromMap(JSObject* obj,
......
......@@ -133,6 +133,7 @@ void HeapObject::HeapObjectPrint() {
JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
break;
case JS_VALUE_TYPE:
PrintF("Value wrapper around:");
JSValue::cast(this)->value()->Print();
break;
case CODE_TYPE:
......
......@@ -979,6 +979,13 @@ void FixedArray::set_the_hole(int index) {
}
bool DescriptorArray::IsEmpty() {
ASSERT(this == Heap::empty_descriptor_array() ||
this->length() > 2);
return this == Heap::empty_descriptor_array();
}
void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
Object* tmp = array->get(first);
fast_set(array, first, array->get(second));
......
This diff is collapsed.
......@@ -52,6 +52,7 @@
// - Array
// - ByteArray
// - FixedArray
// - DescriptorArray
// - HashTable
// - Dictionary
// - SymbolTable
......@@ -135,8 +136,7 @@ class PropertyDetails BASE_EMBEDDED {
bool IsTransition() {
PropertyType t = type();
ASSERT(t != INTERCEPTOR);
if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true;
return false;
return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
}
PropertyAttributes attributes() { return AttributesField::decode(value_); }
......@@ -1095,23 +1095,20 @@ class HeapNumber: public HeapObject {
class JSObject: public HeapObject {
public:
// [properties]: Backing storage for properties.
DECL_ACCESSORS(properties, FixedArray)
// properties is a FixedArray in the fast case, and a Dictionary in the
// slow case.
DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
inline void initialize_properties();
// [elements]: The elements in the fast case.
DECL_ACCESSORS(elements, HeapObject)
inline void initialize_elements();
// Accessors for properties.
inline bool HasFastProperties();
inline Dictionary* property_dictionary(); // Gets slow properties.
// Do we want to keep the elements in fast case when increasing the
// capacity?
bool KeepInFastCase(int new_capacity);
// Accessors for slow properties
inline Dictionary* property_dictionary(); // asserts !HasFastProperties
inline Dictionary* element_dictionary(); // asserts !HasFastElements
// [elements]: The elements (properties with names that are integers).
// elements is a FixedArray in the fast case, and a Dictionary in the slow
// case.
DECL_ACCESSORS(elements, HeapObject) // Get and set fast elements.
inline void initialize_elements();
inline bool HasFastElements();
inline Dictionary* element_dictionary(); // Gets slow elements.
Object* SetProperty(String* key,
Object* value,
......@@ -1188,14 +1185,14 @@ class JSObject: public HeapObject {
// Tests for the fast common case for property enumeration.
bool IsSimpleEnum();
// Tells whether the backing storage for elements is fast (FixedArray).
inline bool HasFastElements();
// Do we want to keep the elements in fast case when increasing the
// capacity?
bool ShouldConvertToSlowElements(int new_capacity);
// Returns true if the backing storage for the slow-case elements of
// this object takes up nearly as much space as a fast-case backing
// storage would. In that case the JSObject should have fast
// elements.
bool ShouldHaveFastElements();
bool ShouldConvertToFastElements();
// Return the object's prototype (might be Heap::null_value()).
inline Object* GetPrototype();
......@@ -1370,6 +1367,7 @@ class JSObject: public HeapObject {
static const uint32_t kMaxGap = 1024;
static const int kMaxFastElementsLength = 5000;
static const int kMaxFastProperties = 8;
// Layout description.
static const int kPropertiesOffset = HeapObject::kSize;
......@@ -1477,6 +1475,8 @@ class FixedArray: public Array {
#ifdef DEBUG
void FixedArrayPrint();
void FixedArrayVerify();
// Checks if two FixedArrays have identical contents.
bool IsEqualTo(FixedArray* other);
#endif
// Swap two elements.
......@@ -1505,14 +1505,15 @@ class FixedArray: public Array {
//
class DescriptorArray: public FixedArray {
public:
// Is this the singleton empty_descriptor_array?
inline bool IsEmpty();
// Returns the number of descriptors in the array.
int number_of_descriptors() {
int len = length();
return len == 0 ? 0 : len - kFirstIndex;
return IsEmpty() ? 0 : length() - kFirstIndex;
}
int NextEnumerationIndex() {
if (length() == 0) return PropertyDetails::kInitialIndex;
if (IsEmpty()) return PropertyDetails::kInitialIndex;
Object* obj = get(kEnumerationIndexIndex);
if (obj->IsSmi()) {
return Smi::cast(obj)->value();
......@@ -1524,11 +1525,12 @@ class DescriptorArray: public FixedArray {
// Set next enumeration index and flush any enum cache.
void SetNextEnumerationIndex(int value) {
fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value));
if (!IsEmpty()) {
fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value));
}
}
bool HasEnumCache() {
return length() > 0 && !get(kEnumerationIndexIndex)->IsSmi();
return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi();
}
Object* GetEnumCache() {
......@@ -1579,6 +1581,9 @@ class DescriptorArray: public FixedArray {
// with low=0 and high=2.
int BinarySearch(String* name, int low, int high);
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
static Object* Allocate(int number_of_descriptors);
// Casting.
......@@ -1612,6 +1617,9 @@ class DescriptorArray: public FixedArray {
// Is the descriptor array sorted and without duplicates?
bool IsSortedNoDuplicates();
// Are two DescriptorArrays equal?
bool IsEqualTo(DescriptorArray* other);
#endif
// The maximum number of descriptors we want in a descriptor array (should
......
......@@ -2726,9 +2726,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
int literal_index = temp_scope_->NextMaterializedLiteralIndex();
if (is_pre_parsing_) return NULL;
Handle<FixedArray> constant_properties = (number_of_constant_properties == 0)
? Factory::empty_fixed_array()
: Factory::NewFixedArray(number_of_constant_properties*2, TENURED);
Handle<FixedArray> constant_properties =
Factory::NewFixedArray(number_of_constant_properties * 2, TENURED);
int position = 0;
for (int i = 0; i < properties.length(); i++) {
ObjectLiteral::Property* property = properties.at(i);
......
......@@ -87,6 +87,9 @@ void LookupResult::Print() {
case CONSTANT_TRANSITION:
PrintF(" -type = constant property transition\n");
break;
case NULL_DESCRIPTOR:
PrintF(" =type = null descriptor\n");
break;
}
}
......
......@@ -348,8 +348,11 @@ class DescriptorReader: public DescriptorStream {
bool IsTransition() {
PropertyType t = type();
ASSERT(t != INTERCEPTOR);
if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true;
return false;
return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
}
bool IsNullDescriptor() {
return type() == NULL_DESCRIPTOR;
}
JSFunction* GetConstantFunction() { return JSFunction::cast(GetValue()); }
......
......@@ -247,8 +247,7 @@ static Object* Runtime_CreateApiFunction(Arguments args) {
static Object* Runtime_IsTemplate(Arguments args) {
ASSERT(args.length() == 1);
Object* arg = args[0];
bool result = arg->IsObjectTemplateInfo()
|| arg->IsFunctionTemplateInfo();
bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
return Heap::ToBoolean(result);
}
......@@ -794,11 +793,12 @@ static Object* Runtime_FunctionSetLength(Arguments args) {
static Object* Runtime_FunctionSetPrototype(Arguments args) {
HandleScope scope;
NoHandleAllocation ha;
ASSERT(args.length() == 2);
CONVERT_CHECKED(JSFunction, fun, args[0]);
Accessors::FunctionSetPrototype(fun, args[1], NULL);
Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL);
if (obj->IsFailure()) return obj;
return args[0]; // return TOS
}
......@@ -858,14 +858,12 @@ static Object* Runtime_SetCode(Arguments args) {
static Object* CharCodeAt(String* subject, Object* index) {
uint32_t i = 0;
if (!Array::IndexFromObject(index, &i))
return Heap::nan_value();
if (!Array::IndexFromObject(index, &i)) return Heap::nan_value();
// Flatten the string. If someone wants to get a char at an index
// in a cons string, it is likely that more indices will be
// accessed.
subject->TryFlatten();
if (i >= static_cast<uint32_t>(subject->length()))
return Heap::nan_value();
if (i >= static_cast<uint32_t>(subject->length())) return Heap::nan_value();
return Smi::FromInt(subject->Get(i));
}
......@@ -1315,12 +1313,13 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
return *value;
}
HandleScope scope;
// Handlify object and value before calling into JavaScript again.
Handle<JSObject> object_handle = Handle<JSObject>::cast(object);
Handle<Object> value_handle = value;
// Call-back into JavaScript to convert the key to a string.
HandleScope scope;
bool has_pending_exception = false;
Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
......@@ -1562,8 +1561,7 @@ static Object* Runtime_Typeof(Arguments args) {
HeapObject* heap_obj = HeapObject::cast(obj);
// typeof an undetectable object is 'undefined'
if (heap_obj->map()->is_undetectable())
return Heap::undefined_symbol();
if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol();
InstanceType instance_type = heap_obj->map()->instance_type();
if (instance_type < FIRST_NONSTRING_TYPE) {
......@@ -1888,7 +1886,7 @@ static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;
template <class Converter>
static Object* ConvertCase(Arguments args,
unibrow::Mapping<Converter, 128> *mapping) {
unibrow::Mapping<Converter, 128>* mapping) {
NoHandleAllocation ha;
CONVERT_CHECKED(String, s, args[0]);
......@@ -1916,12 +1914,10 @@ static Object* ConvertCase(Arguments args,
Object* o = s->IsAscii()
? Heap::AllocateRawAsciiString(length)
: Heap::AllocateRawTwoByteString(length);
if (o->IsFailure())
return o;
if (o->IsFailure()) return o;
String* result = String::cast(o);
bool has_changed_character = false;
// Convert all characters to upper case, assuming that they will fit
// in the buffer
Access<StringInputBuffer> buffer(&string_input_buffer);
......@@ -2047,10 +2043,7 @@ static Object* Runtime_NumberToInteger(Arguments args) {
ASSERT(args.length() == 1);
Object* obj = args[0];
if (obj->IsSmi())
return obj;
if (obj->IsSmi()) return obj;
CONVERT_DOUBLE_CHECKED(number, obj);
return Heap::NumberFromDouble(DoubleToInteger(number));
}
......@@ -2184,8 +2177,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
return Top::Throw(Heap::illegal_argument_symbol());
}
FixedArray* fixed_array = FixedArray::cast(array->elements());
if (fixed_array->length() < array_length)
if (fixed_array->length() < array_length) {
array_length = fixed_array->length();
}
if (array_length == 0) {
return Heap::empty_string();
......@@ -2214,8 +2208,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
return Failure::OutOfMemoryException();
}
position += element_length;
if (ascii && !element->IsAscii())
if (ascii && !element->IsAscii()) {
ascii = false;
}
} else {
return Top::Throw(Heap::illegal_argument_symbol());
}
......@@ -2408,17 +2403,15 @@ static Object* Runtime_StringCompare(Arguments args) {
// A few fast case tests before we flatten.
if (x == y) return Smi::FromInt(EQUAL);
if (y->length() == 0) {
if (x->length() == 0)
return Smi::FromInt(EQUAL);
if (x->length() == 0) return Smi::FromInt(EQUAL);
return Smi::FromInt(GREATER);
} else if (x->length() == 0) {
return Smi::FromInt(LESS);
}
{
int d = x->Get(0) - y->Get(0);
if (d < 0) return Smi::FromInt(LESS);
else if (d > 0) return Smi::FromInt(GREATER);
}
int d = x->Get(0) - y->Get(0);
if (d < 0) return Smi::FromInt(LESS);
else if (d > 0) return Smi::FromInt(GREATER);
x->TryFlatten();
y->TryFlatten();
......@@ -2821,8 +2814,6 @@ static Object* Runtime_LookupContext(Arguments args) {
}
// A mechanism to return pairs of Object*'s. This is somewhat
// compiler-dependent as it assumes that a 64-bit value (a long long)
// is returned via two registers (edx:eax on ia32). Both the ia32 and
......@@ -2888,7 +2879,7 @@ static ObjPair LoadContextSlotHelper(Arguments args, bool throw_error) {
if (throw_error) {
// The property doesn't exist - throw exception.
Handle<Object> reference_error =
Factory::NewReferenceError("not_defined", HandleVector(&name, 1));
Factory::NewReferenceError("not_defined", HandleVector(&name, 1));
return MakePair(Top::Throw(*reference_error), NULL);
} else {
// The property doesn't exist - return undefined
......@@ -2913,7 +2904,7 @@ static Object* Runtime_StoreContextSlot(Arguments args) {
Handle<Object> value(args[0]);
CONVERT_ARG_CHECKED(Context, context, 1);
Handle<String> name(String::cast(args[2]));
CONVERT_ARG_CHECKED(String, name, 2);
int index;
PropertyAttributes attributes;
......@@ -3473,8 +3464,7 @@ static Object* Runtime_GetArrayKeys(Arguments args) {
CONVERT_CHECKED(JSArray, raw_array, args[0]);
Handle<JSArray> array(raw_array);
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
HeapObject* elements = array->elements();
if (elements->IsDictionary()) {
if (array->elements()->IsDictionary()) {
// Create an array and get all the keys into it, then remove all the
// keys that are not integers in the range 0 to length-1.
Handle<FixedArray> keys = GetKeysInFixedArrayFor(array);
......@@ -3606,14 +3596,15 @@ static Object* DebugLookupResultValue(LookupResult* result) {
case CONSTANT_FUNCTION:
return result->GetConstantFunction();
case CALLBACKS:
return Heap::undefined_value();
case MAP_TRANSITION:
return Heap::undefined_value();
case INTERCEPTOR:
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
return Heap::undefined_value();
default:
UNREACHABLE();
}
UNREACHABLE();
return Heap::undefined_value();
}
......@@ -3788,8 +3779,7 @@ static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) {
CONVERT_ARG_CHECKED(String, name, 1);
PropertyAttributes attributes;
Object* result = obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
return result;
return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
}
......@@ -3803,8 +3793,7 @@ static Object* Runtime_DebugIndexedInterceptorElementValue(Arguments args) {
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Object* result = obj->GetElementWithInterceptor(*obj, index);
return result;
return obj->GetElementWithInterceptor(*obj, index);
}
......@@ -3868,8 +3857,8 @@ static Object* Runtime_GetFrameDetails(Arguments args) {
ASSERT(args.length() == 2);
// Check arguments.
Object* result = Runtime_CheckExecutionState(args);
if (result->IsFailure()) return result;
Object* check = Runtime_CheckExecutionState(args);
if (check->IsFailure()) return check;
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
// Find the relevant frame with the requested index.
......@@ -4258,8 +4247,8 @@ static Object* Runtime_PrepareStep(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 3);
// Check arguments.
Object* check_result = Runtime_CheckExecutionState(args);
if (check_result->IsFailure()) return check_result;
Object* check = Runtime_CheckExecutionState(args);
if (check->IsFailure()) return check;
if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
return Top::Throw(Heap::illegal_argument_symbol());
}
......
......@@ -212,7 +212,8 @@ $Object.prototype.constructor = $Object;
%AddProperty(global, "execScript", function(expr, lang) {
// NOTE: We don't care about the character casing.
if (!lang || /javascript/i.test(lang)) {
%CompileString(ToString(expr), false)();
var f = %CompileString(ToString(expr), false);
f.call(global);
}
return null;
}, DONT_ENUM);
......
......@@ -25,17 +25,18 @@
// (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 <v8.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include "cctest.h"
CcTest* CcTest::first_ = NULL;
CcTest* CcTest::last_ = NULL;
CcTest::CcTest(TestFunction* callback, const char* file, const char* name)
: callback_(callback), name_(name), prev_(first_) {
: callback_(callback), name_(name), prev_(last_) {
// Find the base name of this test (const_cast required on Windows).
char *basename = strrchr(const_cast<char *>(file), '/');
if (!basename) {
......@@ -51,15 +52,67 @@ CcTest::CcTest(TestFunction* callback, const char* file, const char* name)
if (extension) *extension = 0;
// Install this test in the list of tests
file_ = basename;
prev_ = first_;
first_ = this;
prev_ = last_;
last_ = this;
}
int main(int argc, char *argv[]) {
CcTest* current = CcTest::first();
while (current != NULL) {
printf("%s/%s\n", current->file(), current->name());
current = current->prev();
static void PrintTestList(CcTest* current) {
if (current == NULL) return;
PrintTestList(current->prev());
printf("%s/%s\n", current->file(), current->name());
}
static int RunMatchingTests(CcTest* current, char* file_or_name) {
if (current == NULL) return 0;
int run_count = 0;
if (strcmp(current->file(), file_or_name) == 0
|| strcmp(current->name(), file_or_name) == 0) {
current->Run();
run_count++;
}
return run_count + RunMatchingTests(current->prev(), file_or_name);
}
static int RunMatchingTests(CcTest* current, char* file, char* name) {
if (current == NULL) return 0;
int run_count = 0;
if (strcmp(current->file(), file) == 0
&& strcmp(current->name(), name) == 0) {
current->Run();
run_count++;
}
return run_count + RunMatchingTests(current->prev(), file, name);
}
int main(int argc, char* argv[]) {
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
int tests_run = 0;
bool print_run_count = true;
for (int i = 1; i < argc; i++) {
char* arg = argv[i];
if (strcmp(arg, "--list") == 0) {
PrintTestList(CcTest::last());
print_run_count = false;
} else {
char* arg_copy = strdup(arg);
char* testname = strchr(arg_copy, '/');
if (testname) {
// Split the string in two by nulling the slash and then run
// exact matches.
*testname = 0;
tests_run += RunMatchingTests(CcTest::last(), arg_copy, testname + 1);
} else {
// Run all tests with the specified file or test name.
tests_run += RunMatchingTests(CcTest::last(), arg_copy);
}
free(arg_copy);
}
}
if (print_run_count && tests_run != 1)
printf("Ran %i tests.\n", tests_run);
return 0;
}
......@@ -40,17 +40,17 @@ class CcTest {
public:
typedef void (TestFunction)();
CcTest(TestFunction* callback, const char* file, const char* name);
void Run() { callback_(); }
static int test_count();
static CcTest* first() { return first_; }
static CcTest* last() { return last_; }
CcTest* prev() { return prev_; }
const char* file() { return file_; }
const char* name() { return name_; }
private:
TestFunction* callback_;
const char* file_;
const char* name_;
static CcTest* first_;
static CcTest* last_;
CcTest* prev_;
};
......
This diff is collapsed.
......@@ -124,10 +124,10 @@ TEST(Flags4) {
SetFlagsToDefault();
int argc = 3;
const char* argv[] = { "Test4", "--bool_flag", "--foo" };
CHECK_EQ(2, FlagList::SetFlagsFromCommandLine(&argc,
CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
const_cast<char **>(argv),
true));
CHECK_EQ(3, argc);
CHECK_EQ(2, argc);
}
......
# Copyright 2008 Google Inc. 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.
import test
import os
from os.path import join, dirname
import platform
DEBUG_FLAGS = ['--enable-slow-asserts', '--debug-code', '--verify-heap']
class CcTestCase(test.TestCase):
def __init__(self, path, executable, mode, raw_name, context):
super(CcTestCase, self).__init__(context, path)
self.executable = executable
self.mode = mode
self.raw_name = raw_name
def GetLabel(self):
return "%s %s %s" % (self.mode, self.path[-2], self.path[-1])
def GetName(self):
return self.path[-1]
def GetCommand(self):
result = [ self.executable, self.raw_name ]
if self.mode == 'debug':
result += DEBUG_FLAGS
return result
class CcTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(CcTestConfiguration, self).__init__(context, root)
def GetBuildRequirements(self):
return ['cctests']
def ListTests(self, current_path, path, mode):
executable = join('obj', 'test', mode, 'cctest')
if (platform.system() == 'Windows'):
executable += '.exe'
output = test.Execute([executable, '--list'], self.context)
if output.exit_code != 0:
print output.stdout
print output.stderr
return []
result = []
for raw_test in output.stdout.strip().split():
full_path = current_path + raw_test.split('/')
if self.Contains(path, full_path):
result.append(CcTestCase(full_path, executable, mode, raw_test, self.context))
return result
def GetConfiguration(context, root):
return CcTestConfiguration(context, root)
......@@ -25,7 +25,7 @@
// (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: --expose-debug-as debug
// Flags: --expose-debug-as debug --expose-gc
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
......@@ -55,7 +55,7 @@ for (i = 0; i < scripts.length; i++) {
// This has to be updated if the number of native and extension scripts change.
assertEquals(12, native_count);
assertEquals(5, extension_count);
assertEquals(1, extension_count);
assertEquals(2, normal_count); // This script and mjsunit.js.
// Test a builtins script.
......@@ -80,7 +80,7 @@ assertEquals(Debug.ScriptType.Extension, extension_gc_script.type);
// Test a normal script.
var mjsunit_js_script = Debug.findScript(/mjsunit.js/);
assertEquals('mjsunit.js', mjsunit_js_script.name);
assertTrue(/mjsunit.js/.test(mjsunit_js_script.name));
assertEquals(Debug.ScriptType.Normal, mjsunit_js_script.type);
// Check a nonexistent script.
......
......@@ -47,5 +47,3 @@ function g() {
assertEquals(Debug.scriptSource(f), Debug.scriptSource(g));
f();
g();
assertEquals("function print() { [native code] }", print);
......@@ -48,7 +48,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) {
assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
assertFalse(mirror.hasNamedInterceptor(), "hasNamedInterceptor()");
assertFalse(mirror.hasIndexedInterceptor(), "hasIndexedInterceptor()");
var names = mirror.propertyNames();
var properties = mirror.properties()
assertEquals(names.length, properties.length);
......@@ -77,10 +77,11 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) {
assertEquals('object', fromJSON.type);
assertEquals(cls_name, fromJSON.className);
assertEquals('function', fromJSON.constructorFunction.type);
assertEquals(ctor_name, fromJSON.constructorFunction.name);
if (ctor_name !== undefined)
assertEquals(ctor_name, fromJSON.constructorFunction.name);
assertEquals(void 0, fromJSON.namedInterceptor);
assertEquals(void 0, fromJSON.indexedInterceptor);
// For array the index properties are seperate from named properties.
if (!cls_name == 'Array') {
assertEquals(names.length, fromJSON.properties.length, 'Some properties missing in JSON');
......@@ -134,7 +135,7 @@ testObjectMirror({}, 'Object', 'Object');
testObjectMirror({'a':1,'b':2}, 'Object', 'Object');
testObjectMirror({'1':void 0,'2':null,'f':function pow(x,y){return Math.pow(x,y);}}, 'Object', 'Object');
testObjectMirror(new Point(-1.2,2.003), 'Object', 'Point');
testObjectMirror(this, 'global', 'Object', true); // Global object has special properties
testObjectMirror(this, 'global', undefined, true); // Global object has special properties
testObjectMirror([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array');
......
......@@ -25,7 +25,7 @@
// (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: --trace-calls --preallocated-stack-trace-memory 1000000
// Flags: --trace-calls --preallocate-message-memory
/**
* @fileoverview Check that various regexp constructs work as intended.
......
// Copyright 2008 Google Inc. 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.
// Make sure that 'this' is bound to the global object when using
// execScript.
var result;
execScript("result = this");
assertTrue(result === this);
......@@ -36,21 +36,24 @@ FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
class MjsunitTestCase(test.TestCase):
def __init__(self, path, file, config):
super(MjsunitTestCase, self).__init__(path)
def __init__(self, path, file, mode, context, config):
super(MjsunitTestCase, self).__init__(context, path)
self.file = file
self.config = config
self.mode = mode
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1]
def GetCommand(self):
result = [self.config.context.vm]
result = [self.config.context.GetVm(self.mode)]
source = open(self.file).read()
flags_match = FLAGS_PATTERN.search(source)
if flags_match:
runtime_flags = flags_match.group(1).strip().split()
result += ["--runtime-flags", " ".join(runtime_flags)]
result += flags_match.group(1).strip().split()
framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js')
result += [framework, self.file]
return result
......@@ -65,29 +68,21 @@ class MjsunitTestConfiguration(test.TestConfiguration):
def SelectTest(name):
return name.endswith('.js') and name != 'mjsunit.js'
return [f[:-3] for f in os.listdir(path) if SelectTest(f)]
def Contains(self, path, file):
if len(path) > len(file):
return False
for i in xrange(len(path)):
if path[i] != file[i]:
return False
return True
def ListTests(self, current_path, path, mode):
mjsunit = [[t] for t in self.Ls(self.root)]
regress = [['regress', t] for t in self.Ls(join(self.root, 'regress'))]
mjsunit = [current_path + [t] for t in self.Ls(self.root)]
regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))]
all_tests = mjsunit + regress
result = []
for test in all_tests:
if self.Contains(path, test):
full_name = current_path + test
file_path = join(self.root, reduce(join, test, "") + ".js")
result.append(MjsunitTestCase(full_name, file_path, self))
file_path = join(self.root, reduce(join, test[1:], "") + ".js")
result.append(MjsunitTestCase(full_name, file_path, mode, self.context, self))
return result
def GetBuildRequirements(self):
return ['sample=shell']
return ['sample', 'sample=shell']
def GetConfiguration(context, root):
......
This diff is collapsed.
# Copyright 2008 Google Inc. 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.
import os
from os.path import join, exists
import test
EXCLUDED = ['CVS']
FRAMEWORK = """
browser.js
shell.js
jsref.js
template.js
""".split()
TEST_DIRS = """
ecma
ecma_2
ecma_3
js1_1
js1_2
js1_3
js1_4
js1_5
""".split()
class MozillaTestCase(test.TestCase):
def __init__(self, filename, path, context, mode, framework):
super(MozillaTestCase, self).__init__(context, path)
self.filename = filename
self.mode = mode
self.framework = framework
def IsNegative(self):
return self.filename.endswith('-n.js')
def GetLabel(self):
return "%s mozilla %s" % (self.mode, self.GetName())
def IsFailureOutput(self, output):
if output.exit_code != 0:
return True
return 'FAILED!' in output.stdout
def GetCommand(self):
result = [self.context.GetVm(self.mode), '--expose-gc']
result += self.framework
result.append(self.filename)
return result
def GetName(self):
return self.path[-1]
class MozillaTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(MozillaTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode):
tests = []
for test_dir in TEST_DIRS:
current_root = join(self.root, test_dir)
for root, dirs, files in os.walk(current_root):
for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
for excluded in EXCLUDED:
if excluded in dirs:
dirs.remove(excluded)
root_path = root[len(self.root):].split(os.path.sep)
root_path = current_path + [x for x in root_path if x]
framework = []
for i in xrange(len(root_path)):
if i == 0: dir = root_path[1:]
else: dir = root_path[1:-i]
script = join(self.root, reduce(join, dir, ''), 'shell.js')
if exists(script):
framework.append(script)
framework.reverse()
for file in files:
if (not file in FRAMEWORK) and file.endswith('.js'):
full_path = root_path + [file[:-3]]
if self.Contains(path, full_path):
test = MozillaTestCase(join(root, file), full_path, self.context,
mode, framework)
tests.append(test)
return tests
def GetBuildRequirements(self):
return ['sample', 'sample=shell']
def GetConfiguration(context, root):
return MozillaTestConfiguration(context, root)
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment