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 @@ ...@@ -28,6 +28,7 @@
import platform import platform
import re import re
import sys import sys
import os
from os.path import join, dirname, abspath from os.path import join, dirname, abspath
root_dir = dirname(File('SConstruct').rfile().abspath) root_dir = dirname(File('SConstruct').rfile().abspath)
sys.path.append(join(root_dir, 'tools')) sys.path.append(join(root_dir, 'tools'))
...@@ -41,7 +42,8 @@ LIBRARY_FLAGS = { ...@@ -41,7 +42,8 @@ LIBRARY_FLAGS = {
'gcc': { 'gcc': {
'all': { 'all': {
'DIALECTFLAGS': ['-ansi'], 'DIALECTFLAGS': ['-ansi'],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS',
'-fno-strict-aliasing'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'], 'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LIBS': ['pthread'] 'LIBS': ['pthread']
}, },
...@@ -52,6 +54,9 @@ LIBRARY_FLAGS = { ...@@ -52,6 +54,9 @@ LIBRARY_FLAGS = {
'mode:release': { 'mode:release': {
'CCFLAGS': ['-O2'] 'CCFLAGS': ['-O2']
}, },
'wordsize:64': {
'CCFLAGS': ['-m32']
},
}, },
'msvc': { 'msvc': {
'all': { 'all': {
...@@ -83,10 +88,13 @@ LIBRARY_FLAGS = { ...@@ -83,10 +88,13 @@ LIBRARY_FLAGS = {
V8_EXTRA_FLAGS = { V8_EXTRA_FLAGS = {
'gcc': { 'gcc': {
'all': { 'all': {
'CXXFLAGS': ['-fvisibility=hidden'], 'CXXFLAGS': [], #['-fvisibility=hidden'],
'WARNINGFLAGS': ['-pedantic', '-Wall', '-Werror', '-W', 'WARNINGFLAGS': ['-pedantic', '-Wall', '-Werror', '-W',
'-Wno-unused-parameter'] '-Wno-unused-parameter']
}, },
'arch:arm': {
'CPPDEFINES': ['ARM']
},
}, },
'msvc': { 'msvc': {
'all': { 'all': {
...@@ -95,6 +103,9 @@ V8_EXTRA_FLAGS = { ...@@ -95,6 +103,9 @@ V8_EXTRA_FLAGS = {
'library:shared': { 'library:shared': {
'CPPDEFINES': ['BUILDING_V8_SHARED'] 'CPPDEFINES': ['BUILDING_V8_SHARED']
}, },
'arch:arm': {
'CPPDEFINES': ['ARM']
},
} }
} }
...@@ -143,6 +154,9 @@ CCTEST_EXTRA_FLAGS = { ...@@ -143,6 +154,9 @@ CCTEST_EXTRA_FLAGS = {
} }
}, },
'msvc': { 'msvc': {
'all': {
'CPPDEFINES': ['_HAS_EXCEPTIONS=0']
},
'library:shared': { 'library:shared': {
'CPPDEFINES': ['USING_V8_SHARED'] 'CPPDEFINES': ['USING_V8_SHARED']
} }
...@@ -198,17 +212,24 @@ def GuessOS(): ...@@ -198,17 +212,24 @@ def GuessOS():
elif id == 'Windows': elif id == 'Windows':
return 'win32' return 'win32'
else: else:
return '<none>' return None
def GuessProcessor(): def GuessArchitecture():
id = platform.machine() id = platform.machine()
if id.startswith('arm'): if id.startswith('arm'):
return 'arm' return 'arm'
elif (not id) or (not re.match('(x|i[3-6])86', id) is None): elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
return 'ia32' return 'ia32'
else: else:
return '<none>' return None
def GuessWordsize():
if '64' in platform.machine():
return '64'
else:
return '32'
def GuessToolchain(os): def GuessToolchain(os):
...@@ -218,21 +239,61 @@ def GuessToolchain(os): ...@@ -218,21 +239,61 @@ def GuessToolchain(os):
elif 'msvc' in tools: elif 'msvc' in tools:
return 'msvc' return 'msvc'
else: 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(): def GetOptions():
result = Options() result = Options()
os_guess = GuessOS()
toolchain_guess = GuessToolchain(os_guess)
processor_guess = GuessProcessor()
result.Add('mode', 'compilation mode (debug, release)', 'release') 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)', '') 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 return result
...@@ -252,51 +313,46 @@ def IsLegal(env, option, values): ...@@ -252,51 +313,46 @@ def IsLegal(env, option, values):
def VerifyOptions(env): def VerifyOptions(env):
if not IsLegal(env, 'mode', ['debug', 'release']): if not IsLegal(env, 'mode', ['debug', 'release']):
return False 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"]): if not IsLegal(env, 'sample', ["shell", "process"]):
return False 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): class BuildContext(object):
def __init__(self, os, arch, toolchain, snapshot, library, samples, mode): def __init__(self, options, samples):
self.library_targets = [] self.library_targets = []
self.cctest_targets = [] self.cctest_targets = []
self.sample_targets = [] self.sample_targets = []
self.os = os self.options = options
self.arch = arch
self.toolchain = toolchain
self.snapshot = snapshot
self.library = library
self.samples = samples self.samples = samples
self.mode = mode self.use_snapshot = (options['snapshot'] == 'on')
self.use_snapshot = (snapshot == 'on')
self.flags = None self.flags = None
def AddRelevantFlags(self, initial, flags): def AddRelevantFlags(self, initial, flags):
result = initial.copy() result = initial.copy()
self.AppendFlags(result, flags.get('all')) self.AppendFlags(result, flags.get('all'))
self.AppendFlags(result, flags[self.toolchain].get('all')) toolchain = self.options['toolchain']
self.AppendFlags(result, flags[self.toolchain].get('mode:' + self.mode)) self.AppendFlags(result, flags[toolchain].get('all'))
self.AppendFlags(result, flags[self.toolchain].get('library:' + self.library)) for option in sorted(self.options.keys()):
value = self.options[option]
self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
return result return result
def GetRelevantSources(self, source): def GetRelevantSources(self, source):
result = [] result = []
result += source.get('all', []) result += source.get('all', [])
result += source.get('arch:' + self.arch, []) for (name, value) in self.options.items():
result += source.get('os:' + self.os, []) result += source.get(name + ':' + value, [])
result += source.get('mode:' + self.mode, []) return sorted(result)
return result
def AppendFlags(self, options, added): def AppendFlags(self, options, added):
if not added: if not added:
...@@ -306,28 +362,39 @@ class BuildContext(object): ...@@ -306,28 +362,39 @@ class BuildContext(object):
options[key] = value options[key] = value
else: else:
options[key] = options[key] + value options[key] = options[key] + value
def ConfigureObject(self, env, input, **kw): def ConfigureObject(self, env, input, **kw):
if self.library == 'static': if self.options['library'] == 'static':
return env.StaticObject(input, **kw) return env.StaticObject(input, **kw)
elif self.library == 'shared': elif self.options['library'] == 'shared':
return env.SharedObject(input, **kw) return env.SharedObject(input, **kw)
else: else:
return env.Object(input, **kw) 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): def BuildSpecific(env, mode):
context = BuildContext(os=env['os'], arch=env['processor'], options = {'mode': mode}
toolchain=env['toolchain'], snapshot=env['snapshot'], for option in SIMPLE_OPTIONS:
library=env['library'], samples=SplitList(env['sample']), options[option] = env[option]
mode=mode) 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) v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
jscre_flags = context.AddRelevantFlags(library_flags, JSCRE_EXTRA_FLAGS) jscre_flags = context.AddRelevantFlags(library_flags, JSCRE_EXTRA_FLAGS)
dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS) dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_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 = { context.flags = {
'v8': v8_flags, 'v8': v8_flags,
...@@ -351,9 +418,9 @@ def BuildSpecific(env, mode): ...@@ -351,9 +418,9 @@ def BuildSpecific(env, mode):
) )
# Link the object files into a library. # Link the object files into a library.
if context.library == 'static': if context.options['library'] == 'static':
library = env.StaticLibrary(library_name, object_files) 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 # 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. # PDB files when compiling using MSVC so we specify it manually.
# This should not affect any other platforms. # This should not affect any other platforms.
......
...@@ -1673,6 +1673,14 @@ class EXPORT V8 { ...@@ -1673,6 +1673,14 @@ class EXPORT V8 {
*/ */
static void SetFlagsFromString(const char* str, int length); 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. */ /** Get the version string. */
static const char* GetVersion(); static const char* GetVersion();
......
...@@ -62,7 +62,7 @@ class HttpRequestProcessor { ...@@ -62,7 +62,7 @@ class HttpRequestProcessor {
// Initialize this processor. The map contains options that control // Initialize this processor. The map contains options that control
// how requests should be processed. // how requests should be processed.
virtual bool Initialize(map<string, string>* options, virtual bool Initialize(map<string, string>* options,
map<string, string>* output) = 0; map<string, string>* output) = 0;
// Process a single request. // Process a single request.
virtual bool Process(HttpRequest* req) = 0; virtual bool Process(HttpRequest* req) = 0;
...@@ -78,17 +78,17 @@ class JsHttpRequestProcessor : public HttpRequestProcessor { ...@@ -78,17 +78,17 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
// Creates a new processor that processes requests by invoking the // Creates a new processor that processes requests by invoking the
// Process function of the JavaScript script given as an argument. // 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 ~JsHttpRequestProcessor();
virtual bool Initialize(map<string, string>* opts, virtual bool Initialize(map<string, string>* opts,
map<string, string>* output); map<string, string>* output);
virtual bool Process(HttpRequest* req); virtual bool Process(HttpRequest* req);
private: private:
// Execute the script associated with this processor and extract the // Execute the script associated with this processor and extract the
// Process function. Returns true if this succeeded, otherwise false. // Process function. Returns true if this succeeded, otherwise false.
bool ExecuteScript(Handle<String> script); bool ExecuteScript(Handle<String> script);
// Wrap the options and output map in a JavaScript objects and // Wrap the options and output map in a JavaScript objects and
...@@ -108,8 +108,9 @@ class JsHttpRequestProcessor : public HttpRequestProcessor { ...@@ -108,8 +108,9 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
// Callbacks that access maps // Callbacks that access maps
static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info); static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info);
static Handle<Value> MapSet(Local<String> name, Local<Value> value, static Handle<Value> MapSet(Local<String> name,
const AccessorInfo& info); Local<Value> value,
const AccessorInfo& info);
// Utility methods for wrapping C++ objects as JavaScript objects, // Utility methods for wrapping C++ objects as JavaScript objects,
// and going back again. // and going back again.
...@@ -142,7 +143,7 @@ static Handle<Value> LogCallback(const Arguments& args) { ...@@ -142,7 +143,7 @@ static Handle<Value> LogCallback(const Arguments& args) {
// Execute the script and fetch the Process method. // Execute the script and fetch the Process method.
bool JsHttpRequestProcessor::Initialize(map<string, string>* opts, bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
map<string, string>* output) { map<string, string>* output) {
// Create a handle scope to hold the temporary references. // Create a handle scope to hold the temporary references.
HandleScope handle_scope; HandleScope handle_scope;
...@@ -223,7 +224,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { ...@@ -223,7 +224,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts, bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts,
map<string, string>* output) { map<string, string>* output) {
HandleScope handle_scope; HandleScope handle_scope;
// Wrap the map object in a JavaScript wrapper // Wrap the map object in a JavaScript wrapper
...@@ -335,7 +336,7 @@ string ObjectToString(Local<Value> value) { ...@@ -335,7 +336,7 @@ string ObjectToString(Local<Value> value) {
Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name, Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
const AccessorInfo& info) { const AccessorInfo& info) {
// Fetch the map wrapped by this object. // Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder()); map<string, string>* obj = UnwrapMap(info.Holder());
...@@ -355,7 +356,8 @@ Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name, ...@@ -355,7 +356,8 @@ Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
Handle<Value> JsHttpRequestProcessor::MapSet(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. // Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder()); map<string, string>* obj = UnwrapMap(info.Holder());
...@@ -433,7 +435,7 @@ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Handle<Object> obj) { ...@@ -433,7 +435,7 @@ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Handle<Object> obj) {
Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name, Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
const AccessorInfo& info) { const AccessorInfo& info) {
// Extract the C++ request object from the JavaScript wrapper. // Extract the C++ request object from the JavaScript wrapper.
HttpRequest* request = UnwrapRequest(info.Holder()); HttpRequest* request = UnwrapRequest(info.Holder());
...@@ -446,7 +448,7 @@ Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name, ...@@ -446,7 +448,7 @@ Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name, Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
const AccessorInfo& info) { const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder()); HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Referrer(); const string& path = request->Referrer();
return String::New(path.c_str(), path.length()); return String::New(path.c_str(), path.length());
...@@ -454,7 +456,7 @@ Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name, ...@@ -454,7 +456,7 @@ Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name, Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
const AccessorInfo& info) { const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder()); HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Host(); const string& path = request->Host();
return String::New(path.c_str(), path.length()); return String::New(path.c_str(), path.length());
...@@ -462,7 +464,7 @@ Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name, ...@@ -462,7 +464,7 @@ Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name, Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name,
const AccessorInfo& info) { const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder()); HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->UserAgent(); const string& path = request->UserAgent();
return String::New(path.c_str(), path.length()); return String::New(path.c_str(), path.length());
...@@ -499,8 +501,10 @@ void HttpRequestProcessor::Log(const char* event) { ...@@ -499,8 +501,10 @@ void HttpRequestProcessor::Log(const char* event) {
*/ */
class StringHttpRequest : public HttpRequest { class StringHttpRequest : public HttpRequest {
public: public:
StringHttpRequest(const string& path, const string& referrer, StringHttpRequest(const string& path,
const string& host, const string& user_agent); const string& referrer,
const string& host,
const string& user_agent);
virtual const string& Path() { return path_; } virtual const string& Path() { return path_; }
virtual const string& Referrer() { return referrer_; } virtual const string& Referrer() { return referrer_; }
virtual const string& Host() { return host_; } virtual const string& Host() { return host_; }
...@@ -514,15 +518,19 @@ class StringHttpRequest : public HttpRequest { ...@@ -514,15 +518,19 @@ class StringHttpRequest : public HttpRequest {
StringHttpRequest::StringHttpRequest(const string& path, 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), : path_(path),
referrer_(referrer), referrer_(referrer),
host_(host), host_(host),
user_agent_(user_agent) { } user_agent_(user_agent) { }
void ParseOptions(int argc, char* argv[], map<string, string>& options, void ParseOptions(int argc,
string* file) { char* argv[],
map<string, string>& options,
string* file) {
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
string arg = argv[i]; string arg = argv[i];
int index = arg.find('=', 0); int index = arg.find('=', 0);
...@@ -571,7 +579,7 @@ StringHttpRequest kSampleRequests[kSampleSize] = { ...@@ -571,7 +579,7 @@ StringHttpRequest kSampleRequests[kSampleSize] = {
bool ProcessEntries(HttpRequestProcessor* processor, int count, bool ProcessEntries(HttpRequestProcessor* processor, int count,
StringHttpRequest* reqs) { StringHttpRequest* reqs) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (!processor->Process(&reqs[i])) if (!processor->Process(&reqs[i]))
return false; return false;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <v8.h> #include <v8.h>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cstdlib>
void RunShell(v8::Handle<v8::Context> context); void RunShell(v8::Handle<v8::Context> context);
...@@ -35,18 +36,28 @@ bool ExecuteString(v8::Handle<v8::String> source, ...@@ -35,18 +36,28 @@ bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name, v8::Handle<v8::Value> name,
bool print_result); bool print_result);
v8::Handle<v8::Value> Print(const v8::Arguments& args); 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); v8::Handle<v8::String> ReadFile(const char* name);
void ProcessRuntimeFlags(int argc, char* argv[]); void ProcessRuntimeFlags(int argc, char* argv[]);
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
ProcessRuntimeFlags(argc, argv); v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
// Create a template for the global object. // Create a template for the global object.
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the global 'print' function to the C++ Print callback. // Bind the global 'print' function to the C++ Print callback.
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); 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); v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
// Enter the newly created execution environment. // Enter the newly created execution environment.
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
...@@ -55,9 +66,8 @@ int main(int argc, char* argv[]) { ...@@ -55,9 +66,8 @@ int main(int argc, char* argv[]) {
const char* str = argv[i]; const char* str = argv[i];
if (strcmp(str, "--shell") == 0) { if (strcmp(str, "--shell") == 0) {
run_shell = true; run_shell = true;
} else if (strcmp(str, "--runtime-flags") == 0) { } else if (strncmp(str, "--", 2) == 0) {
// Skip the --runtime-flags flag since it was processed earlier. printf("Warning: unknown flag %s.\n", str);
i++;
} else { } else {
// Use all other arguments as names of files to load and run. // Use all other arguments as names of files to load and run.
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
...@@ -93,6 +103,39 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) { ...@@ -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. // Reads a file into a v8 string.
v8::Handle<v8::String> ReadFile(const char* name) { v8::Handle<v8::String> ReadFile(const char* name) {
FILE* file = fopen(name, "rb"); FILE* file = fopen(name, "rb");
...@@ -161,14 +204,3 @@ bool ExecuteString(v8::Handle<v8::String> source, ...@@ -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 = { ...@@ -50,10 +50,11 @@ SOURCES = {
], ],
'arch:arm': ['assembler-arm.cc', 'builtins-arm.cc', 'codegen-arm.cc', 'arch:arm': ['assembler-arm.cc', 'builtins-arm.cc', 'codegen-arm.cc',
'cpu-arm.cc', 'disasm-arm.cc', 'frames-arm.cc', 'ic-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', 'arch:ia32': ['assembler-ia32.cc', 'builtins-ia32.cc', 'codegen-ia32.cc',
'cpu-ia32.cc', 'disasm-ia32.cc', 'frames-ia32.cc', 'ic-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:linux': ['platform-linux.cc'],
'os:macos': ['platform-macos.cc'], 'os:macos': ['platform-macos.cc'],
'os:nullos': ['platform-nullos.cc'], 'os:nullos': ['platform-nullos.cc'],
......
...@@ -223,6 +223,11 @@ void V8::SetFlagsFromString(const char* str, int length) { ...@@ -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) { v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
if (IsDeadCheck("v8::ThrowException()")) return v8::Handle<Value>(); if (IsDeadCheck("v8::ThrowException()")) return v8::Handle<Value>();
i::Top::ScheduleThrow(*Utils::OpenHandle(*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 // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions
// met: // 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 // - Neither the name of Sun Microsystems or the names of contributors may
// notice, this list of conditions and the following disclaimer. // be used to endorse or promote products derived from this software without
// * Redistributions in binary form must reproduce the above // specific prior written permission.
// 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 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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_ #ifndef V8_ASSEMBLER_ARM_INL_H_
#define 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 // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions
// met: // 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 // - Redistribution in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer. // notice, this list of conditions and the following disclaimer in the
// * Redistributions in binary form must reproduce the above // documentation and/or other materials provided with the
// copyright notice, this list of conditions and the following // distribution.
// disclaimer in the documentation and/or other materials provided //
// with the distribution. // - Neither the name of Sun Microsystems or the names of contributors may
// * Neither the name of Google Inc. nor the names of its // be used to endorse or promote products derived from this software without
// contributors may be used to endorse or promote products derived // specific prior written permission.
// from this software without specific prior written permission.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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" #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 // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions
// met: // 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 // - Neither the name of Sun Microsystems or the names of contributors may
// notice, this list of conditions and the following disclaimer. // be used to endorse or promote products derived from this software without
// * Redistributions in binary form must reproduce the above // specific prior written permission.
// 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 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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 // A light-weight ARM Assembler
// Generates user mode instructions for the ARM architecture up to version 5 // Generates user mode instructions for the ARM architecture up to version 5
......
...@@ -379,9 +379,9 @@ Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( ...@@ -379,9 +379,9 @@ Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
// Add prototype. // Add prototype.
PropertyAttributes attributes = static_cast<PropertyAttributes>( PropertyAttributes attributes = static_cast<PropertyAttributes>(
(make_prototype_enumerable ? 0 : DONT_ENUM) (make_prototype_enumerable ? 0 : DONT_ENUM)
| DONT_DELETE | DONT_DELETE
| (make_prototype_read_only ? READ_ONLY : 0)); | (make_prototype_read_only ? READ_ONLY : 0));
result = result =
Factory::CopyAppendProxyDescriptor( Factory::CopyAppendProxyDescriptor(
result, result,
...@@ -481,8 +481,8 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, ...@@ -481,8 +481,8 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
global_context()->set_initial_object_prototype(*prototype); global_context()->set_initial_object_prototype(*prototype);
SetPrototype(object_fun, prototype); SetPrototype(object_fun, prototype);
object_function_map->set_instance_descriptors( object_function_map->
DescriptorArray::cast(Heap::empty_fixed_array())); set_instance_descriptors(Heap::empty_descriptor_array());
} }
// Allocate the empty function as the prototype for function ECMAScript // Allocate the empty function as the prototype for function ECMAScript
...@@ -1192,7 +1192,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -1192,7 +1192,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
} }
case MAP_TRANSITION: case MAP_TRANSITION:
case CONSTANT_TRANSITION: case CONSTANT_TRANSITION:
// Ignore map transitions. case NULL_DESCRIPTOR:
// Ignore non-properties.
break; break;
case NORMAL: case NORMAL:
// Do not occur since the from object has fast properties. // Do not occur since the from object has fast properties.
......
...@@ -352,7 +352,7 @@ BUILTIN_0(HandleApiCall) { ...@@ -352,7 +352,7 @@ BUILTIN_0(HandleApiCall) {
HandleScope scope; HandleScope scope;
// TODO(1238487): This is not nice. We need to get rid of this // 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?. // way - maybe compile specialized stubs lazily?.
#ifdef USE_OLD_CALLING_CONVENTIONS #ifdef USE_OLD_CALLING_CONVENTIONS
Handle<JSFunction> function = Handle<JSFunction> function =
......
This diff is collapsed.
...@@ -555,8 +555,7 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, ...@@ -555,8 +555,7 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
Handle<JSObject> Factory::NewObjectLiteral(int expected_number_of_properties) { Handle<JSObject> Factory::NewObjectLiteral(int expected_number_of_properties) {
Handle<Map> map = Handle<Map>(Top::object_function()->initial_map()); Handle<Map> map = Handle<Map>(Top::object_function()->initial_map());
map = Factory::CopyMap(map); map = Factory::CopyMap(map);
map->set_instance_descriptors( map->set_instance_descriptors(Heap::empty_descriptor_array());
DescriptorArray::cast(Heap::empty_fixed_array()));
map->set_unused_property_fields(expected_number_of_properties); map->set_unused_property_fields(expected_number_of_properties);
CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, TENURED), CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, TENURED),
JSObject); JSObject);
...@@ -704,7 +703,7 @@ Handle<JSFunction> Factory::CreateApiFunction( ...@@ -704,7 +703,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
if (parent->IsUndefined()) break; if (parent->IsUndefined()) break;
obj = Handle<FunctionTemplateInfo>::cast(parent); obj = Handle<FunctionTemplateInfo>::cast(parent);
} }
if (array->length() > 0) { if (!array->IsEmpty()) {
map->set_instance_descriptors(*array); map->set_instance_descriptors(*array);
} }
......
...@@ -281,10 +281,6 @@ class Factory : public AllStatic { ...@@ -281,10 +281,6 @@ class Factory : public AllStatic {
SYMBOL_LIST(SYMBOL_ACCESSOR) SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef 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<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
static Handle<Dictionary> DictionaryAtNumberPut(Handle<Dictionary>, static Handle<Dictionary> DictionaryAtNumberPut(Handle<Dictionary>,
......
...@@ -301,8 +301,16 @@ int FlagList::SetFlagsFromCommandLine(int* argc, ...@@ -301,8 +301,16 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
// lookup the flag // lookup the flag
Flag* flag = Lookup(name); Flag* flag = Lookup(name);
if (flag == NULL) { if (flag == NULL) {
fprintf(stderr, "Error: unrecognized flag %s\n", arg); if (remove_flags) {
return j; // 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 // if we still need a flag value, use the next argument if available
......
...@@ -304,7 +304,8 @@ enum PropertyType { ...@@ -304,7 +304,8 @@ enum PropertyType {
FIELD = 3, // only in fast mode FIELD = 3, // only in fast mode
CALLBACKS = 4, CALLBACKS = 4,
CONSTANT_TRANSITION = 5, // only in fast mode 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) { ...@@ -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) { AllocationSpace Heap::TargetSpace(HeapObject* object) {
// Heap numbers and sequential strings are promoted to code space, all // Heap numbers and sequential strings are promoted to code space, all
// other object types are promoted to old space. We do not use // 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) { ...@@ -861,7 +861,7 @@ Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
map->set_prototype(null_value()); map->set_prototype(null_value());
map->set_constructor(null_value()); map->set_constructor(null_value());
map->set_instance_size(instance_size); 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_code_cache(empty_fixed_array());
map->set_unused_property_fields(0); map->set_unused_property_fields(0);
map->set_bit_field(0); map->set_bit_field(0);
...@@ -894,17 +894,20 @@ bool Heap::CreateInitialMaps() { ...@@ -894,17 +894,20 @@ bool Heap::CreateInitialMaps() {
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
null_value_ = obj; null_value_ = obj;
// Fix the instance_descriptors for the existing maps. // Allocate the empty descriptor array. AllocateMap can now be used.
DescriptorArray* empty_descriptors = obj = AllocateEmptyFixedArray();
DescriptorArray::cast(empty_fixed_array()); 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()); 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()); 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()); oddball_map()->set_code_cache(empty_fixed_array());
// Fix prototype object for existing maps. // Fix prototype object for existing maps.
...@@ -1004,6 +1007,7 @@ bool Heap::CreateInitialMaps() { ...@@ -1004,6 +1007,7 @@ bool Heap::CreateInitialMaps() {
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
shared_function_info_map_ = Map::cast(obj); shared_function_info_map_ = Map::cast(obj);
ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
return true; return true;
} }
...@@ -1701,7 +1705,7 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) { ...@@ -1701,7 +1705,7 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
ASSERT(map->instance_type() != JS_FUNCTION_TYPE); ASSERT(map->instance_type() != JS_FUNCTION_TYPE);
// Allocate the backing storage for the properties. // Allocate the backing storage for the properties.
Object* properties = AllocatePropertyStorageForMap(map); Object* properties = AllocateFixedArray(map->unused_property_fields());
if (properties->IsFailure()) return properties; if (properties->IsFailure()) return properties;
// Allocate the JSObject. // Allocate the JSObject.
...@@ -1749,7 +1753,7 @@ Object* Heap::ReinitializeJSGlobalObject(JSFunction* constructor, ...@@ -1749,7 +1753,7 @@ Object* Heap::ReinitializeJSGlobalObject(JSFunction* constructor,
ASSERT(map->instance_size() == object->map()->instance_size()); ASSERT(map->instance_size() == object->map()->instance_size());
// Allocate the backing storage for the properties. // Allocate the backing storage for the properties.
Object* properties = AllocatePropertyStorageForMap(map); Object* properties = AllocateFixedArray(map->unused_property_fields());
if (properties->IsFailure()) return properties; if (properties->IsFailure()) return properties;
// Reset the map for the object. // Reset the map for the object.
......
...@@ -112,6 +112,7 @@ namespace v8 { namespace internal { ...@@ -112,6 +112,7 @@ namespace v8 { namespace internal {
V(Object, false_value) \ V(Object, false_value) \
V(String, empty_string) \ V(String, empty_string) \
V(FixedArray, empty_fixed_array) \ V(FixedArray, empty_fixed_array) \
V(DescriptorArray, empty_descriptor_array) \
V(Object, the_hole_value) \ V(Object, the_hole_value) \
V(Map, neander_map) \ V(Map, neander_map) \
V(JSObject, message_listeners) \ V(JSObject, message_listeners) \
...@@ -811,10 +812,6 @@ class Heap : public AllStatic { ...@@ -811,10 +812,6 @@ class Heap : public AllStatic {
// inlined). // inlined).
static inline Object* AllocateRawMap(int size_in_bytes); 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. // Initializes a JSObject based on its map.
static void InitializeJSObjectFromMap(JSObject* obj, static void InitializeJSObjectFromMap(JSObject* obj,
......
...@@ -133,6 +133,7 @@ void HeapObject::HeapObjectPrint() { ...@@ -133,6 +133,7 @@ void HeapObject::HeapObjectPrint() {
JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(); JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
break; break;
case JS_VALUE_TYPE: case JS_VALUE_TYPE:
PrintF("Value wrapper around:");
JSValue::cast(this)->value()->Print(); JSValue::cast(this)->value()->Print();
break; break;
case CODE_TYPE: case CODE_TYPE:
......
...@@ -979,6 +979,13 @@ void FixedArray::set_the_hole(int index) { ...@@ -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) { void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
Object* tmp = array->get(first); Object* tmp = array->get(first);
fast_set(array, first, array->get(second)); fast_set(array, first, array->get(second));
......
This diff is collapsed.
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
// - Array // - Array
// - ByteArray // - ByteArray
// - FixedArray // - FixedArray
// - DescriptorArray
// - HashTable // - HashTable
// - Dictionary // - Dictionary
// - SymbolTable // - SymbolTable
...@@ -135,8 +136,7 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -135,8 +136,7 @@ class PropertyDetails BASE_EMBEDDED {
bool IsTransition() { bool IsTransition() {
PropertyType t = type(); PropertyType t = type();
ASSERT(t != INTERCEPTOR); ASSERT(t != INTERCEPTOR);
if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true; return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
return false;
} }
PropertyAttributes attributes() { return AttributesField::decode(value_); } PropertyAttributes attributes() { return AttributesField::decode(value_); }
...@@ -1095,23 +1095,20 @@ class HeapNumber: public HeapObject { ...@@ -1095,23 +1095,20 @@ class HeapNumber: public HeapObject {
class JSObject: public HeapObject { class JSObject: public HeapObject {
public: public:
// [properties]: Backing storage for properties. // [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(); 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 bool HasFastProperties();
inline Dictionary* property_dictionary(); // Gets slow properties.
// Do we want to keep the elements in fast case when increasing the // [elements]: The elements (properties with names that are integers).
// capacity? // elements is a FixedArray in the fast case, and a Dictionary in the slow
bool KeepInFastCase(int new_capacity); // case.
DECL_ACCESSORS(elements, HeapObject) // Get and set fast elements.
// Accessors for slow properties inline void initialize_elements();
inline Dictionary* property_dictionary(); // asserts !HasFastProperties inline bool HasFastElements();
inline Dictionary* element_dictionary(); // asserts !HasFastElements inline Dictionary* element_dictionary(); // Gets slow elements.
Object* SetProperty(String* key, Object* SetProperty(String* key,
Object* value, Object* value,
...@@ -1188,14 +1185,14 @@ class JSObject: public HeapObject { ...@@ -1188,14 +1185,14 @@ class JSObject: public HeapObject {
// Tests for the fast common case for property enumeration. // Tests for the fast common case for property enumeration.
bool IsSimpleEnum(); bool IsSimpleEnum();
// Tells whether the backing storage for elements is fast (FixedArray). // Do we want to keep the elements in fast case when increasing the
inline bool HasFastElements(); // capacity?
bool ShouldConvertToSlowElements(int new_capacity);
// Returns true if the backing storage for the slow-case elements of // 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 // this object takes up nearly as much space as a fast-case backing
// storage would. In that case the JSObject should have fast // storage would. In that case the JSObject should have fast
// elements. // elements.
bool ShouldHaveFastElements(); bool ShouldConvertToFastElements();
// Return the object's prototype (might be Heap::null_value()). // Return the object's prototype (might be Heap::null_value()).
inline Object* GetPrototype(); inline Object* GetPrototype();
...@@ -1370,6 +1367,7 @@ class JSObject: public HeapObject { ...@@ -1370,6 +1367,7 @@ class JSObject: public HeapObject {
static const uint32_t kMaxGap = 1024; static const uint32_t kMaxGap = 1024;
static const int kMaxFastElementsLength = 5000; static const int kMaxFastElementsLength = 5000;
static const int kMaxFastProperties = 8;
// Layout description. // Layout description.
static const int kPropertiesOffset = HeapObject::kSize; static const int kPropertiesOffset = HeapObject::kSize;
...@@ -1477,6 +1475,8 @@ class FixedArray: public Array { ...@@ -1477,6 +1475,8 @@ class FixedArray: public Array {
#ifdef DEBUG #ifdef DEBUG
void FixedArrayPrint(); void FixedArrayPrint();
void FixedArrayVerify(); void FixedArrayVerify();
// Checks if two FixedArrays have identical contents.
bool IsEqualTo(FixedArray* other);
#endif #endif
// Swap two elements. // Swap two elements.
...@@ -1505,14 +1505,15 @@ class FixedArray: public Array { ...@@ -1505,14 +1505,15 @@ class FixedArray: public Array {
// //
class DescriptorArray: public FixedArray { class DescriptorArray: public FixedArray {
public: public:
// Is this the singleton empty_descriptor_array?
inline bool IsEmpty();
// Returns the number of descriptors in the array. // Returns the number of descriptors in the array.
int number_of_descriptors() { int number_of_descriptors() {
int len = length(); return IsEmpty() ? 0 : length() - kFirstIndex;
return len == 0 ? 0 : len - kFirstIndex;
} }
int NextEnumerationIndex() { int NextEnumerationIndex() {
if (length() == 0) return PropertyDetails::kInitialIndex; if (IsEmpty()) return PropertyDetails::kInitialIndex;
Object* obj = get(kEnumerationIndexIndex); Object* obj = get(kEnumerationIndexIndex);
if (obj->IsSmi()) { if (obj->IsSmi()) {
return Smi::cast(obj)->value(); return Smi::cast(obj)->value();
...@@ -1524,11 +1525,12 @@ class DescriptorArray: public FixedArray { ...@@ -1524,11 +1525,12 @@ class DescriptorArray: public FixedArray {
// Set next enumeration index and flush any enum cache. // Set next enumeration index and flush any enum cache.
void SetNextEnumerationIndex(int value) { void SetNextEnumerationIndex(int value) {
fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value)); if (!IsEmpty()) {
fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value));
}
} }
bool HasEnumCache() { bool HasEnumCache() {
return length() > 0 && !get(kEnumerationIndexIndex)->IsSmi(); return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi();
} }
Object* GetEnumCache() { Object* GetEnumCache() {
...@@ -1579,6 +1581,9 @@ class DescriptorArray: public FixedArray { ...@@ -1579,6 +1581,9 @@ class DescriptorArray: public FixedArray {
// with low=0 and high=2. // with low=0 and high=2.
int BinarySearch(String* name, int low, int high); 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); static Object* Allocate(int number_of_descriptors);
// Casting. // Casting.
...@@ -1612,6 +1617,9 @@ class DescriptorArray: public FixedArray { ...@@ -1612,6 +1617,9 @@ class DescriptorArray: public FixedArray {
// Is the descriptor array sorted and without duplicates? // Is the descriptor array sorted and without duplicates?
bool IsSortedNoDuplicates(); bool IsSortedNoDuplicates();
// Are two DescriptorArrays equal?
bool IsEqualTo(DescriptorArray* other);
#endif #endif
// The maximum number of descriptors we want in a descriptor array (should // The maximum number of descriptors we want in a descriptor array (should
......
...@@ -2726,9 +2726,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -2726,9 +2726,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
int literal_index = temp_scope_->NextMaterializedLiteralIndex(); int literal_index = temp_scope_->NextMaterializedLiteralIndex();
if (is_pre_parsing_) return NULL; if (is_pre_parsing_) return NULL;
Handle<FixedArray> constant_properties = (number_of_constant_properties == 0) Handle<FixedArray> constant_properties =
? Factory::empty_fixed_array() Factory::NewFixedArray(number_of_constant_properties * 2, TENURED);
: Factory::NewFixedArray(number_of_constant_properties*2, TENURED);
int position = 0; int position = 0;
for (int i = 0; i < properties.length(); i++) { for (int i = 0; i < properties.length(); i++) {
ObjectLiteral::Property* property = properties.at(i); ObjectLiteral::Property* property = properties.at(i);
......
...@@ -87,6 +87,9 @@ void LookupResult::Print() { ...@@ -87,6 +87,9 @@ void LookupResult::Print() {
case CONSTANT_TRANSITION: case CONSTANT_TRANSITION:
PrintF(" -type = constant property transition\n"); PrintF(" -type = constant property transition\n");
break; break;
case NULL_DESCRIPTOR:
PrintF(" =type = null descriptor\n");
break;
} }
} }
......
...@@ -348,8 +348,11 @@ class DescriptorReader: public DescriptorStream { ...@@ -348,8 +348,11 @@ class DescriptorReader: public DescriptorStream {
bool IsTransition() { bool IsTransition() {
PropertyType t = type(); PropertyType t = type();
ASSERT(t != INTERCEPTOR); ASSERT(t != INTERCEPTOR);
if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true; return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
return false; }
bool IsNullDescriptor() {
return type() == NULL_DESCRIPTOR;
} }
JSFunction* GetConstantFunction() { return JSFunction::cast(GetValue()); } JSFunction* GetConstantFunction() { return JSFunction::cast(GetValue()); }
......
...@@ -247,8 +247,7 @@ static Object* Runtime_CreateApiFunction(Arguments args) { ...@@ -247,8 +247,7 @@ static Object* Runtime_CreateApiFunction(Arguments args) {
static Object* Runtime_IsTemplate(Arguments args) { static Object* Runtime_IsTemplate(Arguments args) {
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
Object* arg = args[0]; Object* arg = args[0];
bool result = arg->IsObjectTemplateInfo() bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
|| arg->IsFunctionTemplateInfo();
return Heap::ToBoolean(result); return Heap::ToBoolean(result);
} }
...@@ -794,11 +793,12 @@ static Object* Runtime_FunctionSetLength(Arguments args) { ...@@ -794,11 +793,12 @@ static Object* Runtime_FunctionSetLength(Arguments args) {
static Object* Runtime_FunctionSetPrototype(Arguments args) { static Object* Runtime_FunctionSetPrototype(Arguments args) {
HandleScope scope; NoHandleAllocation ha;
ASSERT(args.length() == 2); ASSERT(args.length() == 2);
CONVERT_CHECKED(JSFunction, fun, args[0]); 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 return args[0]; // return TOS
} }
...@@ -858,14 +858,12 @@ static Object* Runtime_SetCode(Arguments args) { ...@@ -858,14 +858,12 @@ static Object* Runtime_SetCode(Arguments args) {
static Object* CharCodeAt(String* subject, Object* index) { static Object* CharCodeAt(String* subject, Object* index) {
uint32_t i = 0; uint32_t i = 0;
if (!Array::IndexFromObject(index, &i)) if (!Array::IndexFromObject(index, &i)) return Heap::nan_value();
return Heap::nan_value();
// Flatten the string. If someone wants to get a char at an index // 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 // in a cons string, it is likely that more indices will be
// accessed. // accessed.
subject->TryFlatten(); subject->TryFlatten();
if (i >= static_cast<uint32_t>(subject->length())) if (i >= static_cast<uint32_t>(subject->length())) return Heap::nan_value();
return Heap::nan_value();
return Smi::FromInt(subject->Get(i)); return Smi::FromInt(subject->Get(i));
} }
...@@ -1315,12 +1313,13 @@ Object* Runtime::SetObjectProperty(Handle<Object> object, ...@@ -1315,12 +1313,13 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
return *value; return *value;
} }
HandleScope scope;
// Handlify object and value before calling into JavaScript again. // Handlify object and value before calling into JavaScript again.
Handle<JSObject> object_handle = Handle<JSObject>::cast(object); Handle<JSObject> object_handle = Handle<JSObject>::cast(object);
Handle<Object> value_handle = value; Handle<Object> value_handle = value;
// Call-back into JavaScript to convert the key to a string. // Call-back into JavaScript to convert the key to a string.
HandleScope scope;
bool has_pending_exception = false; bool has_pending_exception = false;
Handle<Object> converted = Execution::ToString(key, &has_pending_exception); Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception(); if (has_pending_exception) return Failure::Exception();
...@@ -1562,8 +1561,7 @@ static Object* Runtime_Typeof(Arguments args) { ...@@ -1562,8 +1561,7 @@ static Object* Runtime_Typeof(Arguments args) {
HeapObject* heap_obj = HeapObject::cast(obj); HeapObject* heap_obj = HeapObject::cast(obj);
// typeof an undetectable object is 'undefined' // typeof an undetectable object is 'undefined'
if (heap_obj->map()->is_undetectable()) if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol();
return Heap::undefined_symbol();
InstanceType instance_type = heap_obj->map()->instance_type(); InstanceType instance_type = heap_obj->map()->instance_type();
if (instance_type < FIRST_NONSTRING_TYPE) { if (instance_type < FIRST_NONSTRING_TYPE) {
...@@ -1888,7 +1886,7 @@ static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; ...@@ -1888,7 +1886,7 @@ static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;
template <class Converter> template <class Converter>
static Object* ConvertCase(Arguments args, static Object* ConvertCase(Arguments args,
unibrow::Mapping<Converter, 128> *mapping) { unibrow::Mapping<Converter, 128>* mapping) {
NoHandleAllocation ha; NoHandleAllocation ha;
CONVERT_CHECKED(String, s, args[0]); CONVERT_CHECKED(String, s, args[0]);
...@@ -1916,12 +1914,10 @@ static Object* ConvertCase(Arguments args, ...@@ -1916,12 +1914,10 @@ static Object* ConvertCase(Arguments args,
Object* o = s->IsAscii() Object* o = s->IsAscii()
? Heap::AllocateRawAsciiString(length) ? Heap::AllocateRawAsciiString(length)
: Heap::AllocateRawTwoByteString(length); : Heap::AllocateRawTwoByteString(length);
if (o->IsFailure()) if (o->IsFailure()) return o;
return o;
String* result = String::cast(o); String* result = String::cast(o);
bool has_changed_character = false; bool has_changed_character = false;
// Convert all characters to upper case, assuming that they will fit // Convert all characters to upper case, assuming that they will fit
// in the buffer // in the buffer
Access<StringInputBuffer> buffer(&string_input_buffer); Access<StringInputBuffer> buffer(&string_input_buffer);
...@@ -2047,10 +2043,7 @@ static Object* Runtime_NumberToInteger(Arguments args) { ...@@ -2047,10 +2043,7 @@ static Object* Runtime_NumberToInteger(Arguments args) {
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
Object* obj = args[0]; Object* obj = args[0];
if (obj->IsSmi()) return obj;
if (obj->IsSmi())
return obj;
CONVERT_DOUBLE_CHECKED(number, obj); CONVERT_DOUBLE_CHECKED(number, obj);
return Heap::NumberFromDouble(DoubleToInteger(number)); return Heap::NumberFromDouble(DoubleToInteger(number));
} }
...@@ -2184,8 +2177,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) { ...@@ -2184,8 +2177,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
return Top::Throw(Heap::illegal_argument_symbol()); return Top::Throw(Heap::illegal_argument_symbol());
} }
FixedArray* fixed_array = FixedArray::cast(array->elements()); FixedArray* fixed_array = FixedArray::cast(array->elements());
if (fixed_array->length() < array_length) if (fixed_array->length() < array_length) {
array_length = fixed_array->length(); array_length = fixed_array->length();
}
if (array_length == 0) { if (array_length == 0) {
return Heap::empty_string(); return Heap::empty_string();
...@@ -2214,8 +2208,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) { ...@@ -2214,8 +2208,9 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
return Failure::OutOfMemoryException(); return Failure::OutOfMemoryException();
} }
position += element_length; position += element_length;
if (ascii && !element->IsAscii()) if (ascii && !element->IsAscii()) {
ascii = false; ascii = false;
}
} else { } else {
return Top::Throw(Heap::illegal_argument_symbol()); return Top::Throw(Heap::illegal_argument_symbol());
} }
...@@ -2408,17 +2403,15 @@ static Object* Runtime_StringCompare(Arguments args) { ...@@ -2408,17 +2403,15 @@ static Object* Runtime_StringCompare(Arguments args) {
// A few fast case tests before we flatten. // A few fast case tests before we flatten.
if (x == y) return Smi::FromInt(EQUAL); if (x == y) return Smi::FromInt(EQUAL);
if (y->length() == 0) { if (y->length() == 0) {
if (x->length() == 0) if (x->length() == 0) return Smi::FromInt(EQUAL);
return Smi::FromInt(EQUAL);
return Smi::FromInt(GREATER); return Smi::FromInt(GREATER);
} else if (x->length() == 0) { } else if (x->length() == 0) {
return Smi::FromInt(LESS); return Smi::FromInt(LESS);
} }
{
int d = x->Get(0) - y->Get(0); int d = x->Get(0) - y->Get(0);
if (d < 0) return Smi::FromInt(LESS); if (d < 0) return Smi::FromInt(LESS);
else if (d > 0) return Smi::FromInt(GREATER); else if (d > 0) return Smi::FromInt(GREATER);
}
x->TryFlatten(); x->TryFlatten();
y->TryFlatten(); y->TryFlatten();
...@@ -2821,8 +2814,6 @@ static Object* Runtime_LookupContext(Arguments args) { ...@@ -2821,8 +2814,6 @@ static Object* Runtime_LookupContext(Arguments args) {
} }
// A mechanism to return pairs of Object*'s. This is somewhat // A mechanism to return pairs of Object*'s. This is somewhat
// compiler-dependent as it assumes that a 64-bit value (a long long) // 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 // 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) { ...@@ -2888,7 +2879,7 @@ static ObjPair LoadContextSlotHelper(Arguments args, bool throw_error) {
if (throw_error) { if (throw_error) {
// The property doesn't exist - throw exception. // The property doesn't exist - throw exception.
Handle<Object> reference_error = 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); return MakePair(Top::Throw(*reference_error), NULL);
} else { } else {
// The property doesn't exist - return undefined // The property doesn't exist - return undefined
...@@ -2913,7 +2904,7 @@ static Object* Runtime_StoreContextSlot(Arguments args) { ...@@ -2913,7 +2904,7 @@ static Object* Runtime_StoreContextSlot(Arguments args) {
Handle<Object> value(args[0]); Handle<Object> value(args[0]);
CONVERT_ARG_CHECKED(Context, context, 1); CONVERT_ARG_CHECKED(Context, context, 1);
Handle<String> name(String::cast(args[2])); CONVERT_ARG_CHECKED(String, name, 2);
int index; int index;
PropertyAttributes attributes; PropertyAttributes attributes;
...@@ -3473,8 +3464,7 @@ static Object* Runtime_GetArrayKeys(Arguments args) { ...@@ -3473,8 +3464,7 @@ static Object* Runtime_GetArrayKeys(Arguments args) {
CONVERT_CHECKED(JSArray, raw_array, args[0]); CONVERT_CHECKED(JSArray, raw_array, args[0]);
Handle<JSArray> array(raw_array); Handle<JSArray> array(raw_array);
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
HeapObject* elements = array->elements(); if (array->elements()->IsDictionary()) {
if (elements->IsDictionary()) {
// Create an array and get all the keys into it, then remove all the // 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. // keys that are not integers in the range 0 to length-1.
Handle<FixedArray> keys = GetKeysInFixedArrayFor(array); Handle<FixedArray> keys = GetKeysInFixedArrayFor(array);
...@@ -3606,14 +3596,15 @@ static Object* DebugLookupResultValue(LookupResult* result) { ...@@ -3606,14 +3596,15 @@ static Object* DebugLookupResultValue(LookupResult* result) {
case CONSTANT_FUNCTION: case CONSTANT_FUNCTION:
return result->GetConstantFunction(); return result->GetConstantFunction();
case CALLBACKS: case CALLBACKS:
return Heap::undefined_value();
case MAP_TRANSITION:
return Heap::undefined_value();
case INTERCEPTOR: case INTERCEPTOR:
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
return Heap::undefined_value(); return Heap::undefined_value();
default: default:
UNREACHABLE(); UNREACHABLE();
} }
UNREACHABLE();
return Heap::undefined_value(); return Heap::undefined_value();
} }
...@@ -3788,8 +3779,7 @@ static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { ...@@ -3788,8 +3779,7 @@ static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) {
CONVERT_ARG_CHECKED(String, name, 1); CONVERT_ARG_CHECKED(String, name, 1);
PropertyAttributes attributes; PropertyAttributes attributes;
Object* result = obj->GetPropertyWithInterceptor(*obj, *name, &attributes); return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
return result;
} }
...@@ -3803,8 +3793,7 @@ static Object* Runtime_DebugIndexedInterceptorElementValue(Arguments args) { ...@@ -3803,8 +3793,7 @@ static Object* Runtime_DebugIndexedInterceptorElementValue(Arguments args) {
RUNTIME_ASSERT(obj->HasIndexedInterceptor()); RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Object* result = obj->GetElementWithInterceptor(*obj, index); return obj->GetElementWithInterceptor(*obj, index);
return result;
} }
...@@ -3868,8 +3857,8 @@ static Object* Runtime_GetFrameDetails(Arguments args) { ...@@ -3868,8 +3857,8 @@ static Object* Runtime_GetFrameDetails(Arguments args) {
ASSERT(args.length() == 2); ASSERT(args.length() == 2);
// Check arguments. // Check arguments.
Object* result = Runtime_CheckExecutionState(args); Object* check = Runtime_CheckExecutionState(args);
if (result->IsFailure()) return result; if (check->IsFailure()) return check;
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
// Find the relevant frame with the requested index. // Find the relevant frame with the requested index.
...@@ -4258,8 +4247,8 @@ static Object* Runtime_PrepareStep(Arguments args) { ...@@ -4258,8 +4247,8 @@ static Object* Runtime_PrepareStep(Arguments args) {
HandleScope scope; HandleScope scope;
ASSERT(args.length() == 3); ASSERT(args.length() == 3);
// Check arguments. // Check arguments.
Object* check_result = Runtime_CheckExecutionState(args); Object* check = Runtime_CheckExecutionState(args);
if (check_result->IsFailure()) return check_result; if (check->IsFailure()) return check;
if (!args[1]->IsNumber() || !args[2]->IsNumber()) { if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
return Top::Throw(Heap::illegal_argument_symbol()); return Top::Throw(Heap::illegal_argument_symbol());
} }
......
...@@ -212,7 +212,8 @@ $Object.prototype.constructor = $Object; ...@@ -212,7 +212,8 @@ $Object.prototype.constructor = $Object;
%AddProperty(global, "execScript", function(expr, lang) { %AddProperty(global, "execScript", function(expr, lang) {
// NOTE: We don't care about the character casing. // NOTE: We don't care about the character casing.
if (!lang || /javascript/i.test(lang)) { if (!lang || /javascript/i.test(lang)) {
%CompileString(ToString(expr), false)(); var f = %CompileString(ToString(expr), false);
f.call(global);
} }
return null; return null;
}, DONT_ENUM); }, DONT_ENUM);
......
...@@ -25,17 +25,18 @@ ...@@ -25,17 +25,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <v8.h>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include "cctest.h" #include "cctest.h"
CcTest* CcTest::first_ = NULL; CcTest* CcTest::last_ = NULL;
CcTest::CcTest(TestFunction* callback, const char* file, const char* name) 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). // Find the base name of this test (const_cast required on Windows).
char *basename = strrchr(const_cast<char *>(file), '/'); char *basename = strrchr(const_cast<char *>(file), '/');
if (!basename) { if (!basename) {
...@@ -51,15 +52,67 @@ CcTest::CcTest(TestFunction* callback, const char* file, const char* name) ...@@ -51,15 +52,67 @@ CcTest::CcTest(TestFunction* callback, const char* file, const char* name)
if (extension) *extension = 0; if (extension) *extension = 0;
// Install this test in the list of tests // Install this test in the list of tests
file_ = basename; file_ = basename;
prev_ = first_; prev_ = last_;
first_ = this; last_ = this;
} }
int main(int argc, char *argv[]) { static void PrintTestList(CcTest* current) {
CcTest* current = CcTest::first(); if (current == NULL) return;
while (current != NULL) { PrintTestList(current->prev());
printf("%s/%s\n", current->file(), current->name()); printf("%s/%s\n", current->file(), current->name());
current = current->prev(); }
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 { ...@@ -40,17 +40,17 @@ class CcTest {
public: public:
typedef void (TestFunction)(); typedef void (TestFunction)();
CcTest(TestFunction* callback, const char* file, const char* name); CcTest(TestFunction* callback, const char* file, const char* name);
void Run() { callback_(); }
static int test_count(); static int test_count();
static CcTest* first() { return first_; } static CcTest* last() { return last_; }
CcTest* prev() { return prev_; } CcTest* prev() { return prev_; }
const char* file() { return file_; } const char* file() { return file_; }
const char* name() { return name_; } const char* name() { return name_; }
private: private:
TestFunction* callback_; TestFunction* callback_;
const char* file_; const char* file_;
const char* name_; const char* name_;
static CcTest* first_; static CcTest* last_;
CcTest* prev_; CcTest* prev_;
}; };
......
This diff is collapsed.
...@@ -124,10 +124,10 @@ TEST(Flags4) { ...@@ -124,10 +124,10 @@ TEST(Flags4) {
SetFlagsToDefault(); SetFlagsToDefault();
int argc = 3; int argc = 3;
const char* argv[] = { "Test4", "--bool_flag", "--foo" }; const char* argv[] = { "Test4", "--bool_flag", "--foo" };
CHECK_EQ(2, FlagList::SetFlagsFromCommandLine(&argc, CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
const_cast<char **>(argv), const_cast<char **>(argv),
true)); 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 @@ ...@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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. // Get the Debug object exposed from the debug context global object.
Debug = debug.Debug Debug = debug.Debug
...@@ -55,7 +55,7 @@ for (i = 0; i < scripts.length; i++) { ...@@ -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. // This has to be updated if the number of native and extension scripts change.
assertEquals(12, native_count); assertEquals(12, native_count);
assertEquals(5, extension_count); assertEquals(1, extension_count);
assertEquals(2, normal_count); // This script and mjsunit.js. assertEquals(2, normal_count); // This script and mjsunit.js.
// Test a builtins script. // Test a builtins script.
...@@ -80,7 +80,7 @@ assertEquals(Debug.ScriptType.Extension, extension_gc_script.type); ...@@ -80,7 +80,7 @@ assertEquals(Debug.ScriptType.Extension, extension_gc_script.type);
// Test a normal script. // Test a normal script.
var mjsunit_js_script = Debug.findScript(/mjsunit.js/); 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); assertEquals(Debug.ScriptType.Normal, mjsunit_js_script.type);
// Check a nonexistent script. // Check a nonexistent script.
......
...@@ -47,5 +47,3 @@ function g() { ...@@ -47,5 +47,3 @@ function g() {
assertEquals(Debug.scriptSource(f), Debug.scriptSource(g)); assertEquals(Debug.scriptSource(f), Debug.scriptSource(g));
f(); f();
g(); g();
assertEquals("function print() { [native code] }", print);
...@@ -48,7 +48,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) { ...@@ -48,7 +48,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) {
assertTrue(mirror.prototypeObject() instanceof debug.Mirror); assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
assertFalse(mirror.hasNamedInterceptor(), "hasNamedInterceptor()"); assertFalse(mirror.hasNamedInterceptor(), "hasNamedInterceptor()");
assertFalse(mirror.hasIndexedInterceptor(), "hasIndexedInterceptor()"); assertFalse(mirror.hasIndexedInterceptor(), "hasIndexedInterceptor()");
var names = mirror.propertyNames(); var names = mirror.propertyNames();
var properties = mirror.properties() var properties = mirror.properties()
assertEquals(names.length, properties.length); assertEquals(names.length, properties.length);
...@@ -77,10 +77,11 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) { ...@@ -77,10 +77,11 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) {
assertEquals('object', fromJSON.type); assertEquals('object', fromJSON.type);
assertEquals(cls_name, fromJSON.className); assertEquals(cls_name, fromJSON.className);
assertEquals('function', fromJSON.constructorFunction.type); 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.namedInterceptor);
assertEquals(void 0, fromJSON.indexedInterceptor); assertEquals(void 0, fromJSON.indexedInterceptor);
// For array the index properties are seperate from named properties. // For array the index properties are seperate from named properties.
if (!cls_name == 'Array') { if (!cls_name == 'Array') {
assertEquals(names.length, fromJSON.properties.length, 'Some properties missing in JSON'); assertEquals(names.length, fromJSON.properties.length, 'Some properties missing in JSON');
...@@ -134,7 +135,7 @@ testObjectMirror({}, 'Object', 'Object'); ...@@ -134,7 +135,7 @@ testObjectMirror({}, 'Object', 'Object');
testObjectMirror({'a':1,'b':2}, '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({'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(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([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array'); testObjectMirror([1,2], 'Array', 'Array');
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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. * @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:(.*)") ...@@ -36,21 +36,24 @@ FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
class MjsunitTestCase(test.TestCase): class MjsunitTestCase(test.TestCase):
def __init__(self, path, file, config): def __init__(self, path, file, mode, context, config):
super(MjsunitTestCase, self).__init__(path) super(MjsunitTestCase, self).__init__(context, path)
self.file = file self.file = file
self.config = config self.config = config
self.mode = mode
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self): def GetName(self):
return self.path[-1] return self.path[-1]
def GetCommand(self): def GetCommand(self):
result = [self.config.context.vm] result = [self.config.context.GetVm(self.mode)]
source = open(self.file).read() source = open(self.file).read()
flags_match = FLAGS_PATTERN.search(source) flags_match = FLAGS_PATTERN.search(source)
if flags_match: if flags_match:
runtime_flags = flags_match.group(1).strip().split() result += flags_match.group(1).strip().split()
result += ["--runtime-flags", " ".join(runtime_flags)]
framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js') framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js')
result += [framework, self.file] result += [framework, self.file]
return result return result
...@@ -65,29 +68,21 @@ class MjsunitTestConfiguration(test.TestConfiguration): ...@@ -65,29 +68,21 @@ class MjsunitTestConfiguration(test.TestConfiguration):
def SelectTest(name): def SelectTest(name):
return name.endswith('.js') and name != 'mjsunit.js' return name.endswith('.js') and name != 'mjsunit.js'
return [f[:-3] for f in os.listdir(path) if SelectTest(f)] 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): def ListTests(self, current_path, path, mode):
mjsunit = [[t] for t in self.Ls(self.root)] mjsunit = [current_path + [t] for t in self.Ls(self.root)]
regress = [['regress', t] for t in self.Ls(join(self.root, 'regress'))] regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))]
all_tests = mjsunit + regress all_tests = mjsunit + regress
result = [] result = []
for test in all_tests: for test in all_tests:
if self.Contains(path, test): if self.Contains(path, test):
full_name = current_path + test full_name = current_path + test
file_path = join(self.root, reduce(join, test, "") + ".js") file_path = join(self.root, reduce(join, test[1:], "") + ".js")
result.append(MjsunitTestCase(full_name, file_path, self)) result.append(MjsunitTestCase(full_name, file_path, mode, self.context, self))
return result return result
def GetBuildRequirements(self): def GetBuildRequirements(self):
return ['sample=shell'] return ['sample', 'sample=shell']
def GetConfiguration(context, root): 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