# Copyright 2008 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
from os.path import join, dirname, abspath
root_dir = dirname(File('SConstruct').rfile().abspath)
sys.path.append(join(root_dir, 'tools'))
import js2c
Import('context')


SOURCES = {
  'all': [
    'accessors.cc', 'allocation.cc', 'api.cc', 'assembler.cc', 'ast.cc',
    'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'code-stubs.cc',
    'codegen.cc', 'compilation-cache.cc', 'compiler.cc', 'contexts.cc',
    'conversions.cc', 'counters.cc', 'dateparser.cc', 'debug.cc',
    'debug-agent.cc', 'disassembler.cc', 'execution.cc', 'factory.cc',
    'flags.cc', 'frames.cc', 'func-name-inferrer.cc',
    'global-handles.cc', 'handles.cc', 'hashmap.cc',
    'heap.cc', 'ic.cc', 'interpreter-irregexp.cc', 'jsregexp.cc',
    'jump-target.cc', 'log.cc', 'mark-compact.cc', 'messages.cc', 'objects.cc',
    'oprofile-agent.cc', 'parser.cc', 'property.cc', 'regexp-macro-assembler.cc',
    'regexp-macro-assembler-irregexp.cc', 'regexp-stack.cc',
    'register-allocator.cc', 'rewriter.cc', 'runtime.cc', 'scanner.cc',
    'scopeinfo.cc', 'scopes.cc', 'serialize.cc', 'snapshot-common.cc',
    'spaces.cc', 'string-stream.cc', 'stub-cache.cc', 'token.cc', 'top.cc',
    'unicode.cc', 'usage-analyzer.cc', 'utils.cc', 'v8-counters.cc',
    'v8.cc', 'v8threads.cc', 'variables.cc', 'virtual-frame.cc', 'zone.cc'
  ],
  'arch:arm': [
    'arm/assembler-arm.cc', 'arm/builtins-arm.cc',
    'arm/codegen-arm.cc', 'arm/cpu-arm.cc', 'arm/disasm-arm.cc',
    'arm/debug-arm.cc', 'arm/frames-arm.cc', 'arm/ic-arm.cc',
    'arm/jump-target-arm.cc', 'arm/macro-assembler-arm.cc',
    'arm/register-allocator-arm.cc', 'arm/stub-cache-arm.cc',
    'arm/regexp-macro-assembler-arm.cc', 'arm/virtual-frame-arm.cc'
  ],
  'arch:ia32': [
    'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc',
    'ia32/codegen-ia32.cc', 'ia32/cpu-ia32.cc', 'ia32/disasm-ia32.cc',
    'ia32/debug-ia32.cc', 'ia32/frames-ia32.cc', 'ia32/ic-ia32.cc',
    'ia32/jump-target-ia32.cc', 'ia32/macro-assembler-ia32.cc',
    'ia32/register-allocator-ia32.cc', 'ia32/stub-cache-ia32.cc',
    'ia32/regexp-macro-assembler-ia32.cc', 'ia32/virtual-frame-ia32.cc'
  ],
  'simulator:arm': ['arm/simulator-arm.cc'],
  'os:freebsd': ['platform-freebsd.cc', 'platform-posix.cc'],
  'os:linux':   ['platform-linux.cc', 'platform-posix.cc'],
  'os:android': ['platform-linux.cc', 'platform-posix.cc'],
  'os:macos':   ['platform-macos.cc', 'platform-posix.cc'],
  'os:nullos':  ['platform-nullos.cc'],
  'os:win32':   ['platform-win32.cc'],
  'mode:release': [],
  'mode:debug': [
    'objects-debug.cc', 'prettyprinter.cc', 'regexp-macro-assembler-tracer.cc'
  ]
}


D8_FILES = {
  'all': [
    'd8.cc', 'd8-debug.cc'
  ],
  'os:linux': [
    'd8-posix.cc'
  ],
  'os:macos': [
    'd8-posix.cc'
  ],
  'os:android': [
    'd8-posix.cc'
  ],
  'os:freebsd': [
    'd8-posix.cc'
  ],
  'os:win32': [
    'd8-windows.cc'
  ],
  'os:nullos': [
    'd8-windows.cc'   # Empty implementation at the moment.
  ],
  'console:readline': [
    'd8-readline.cc'
  ]
}


LIBRARY_FILES = '''
runtime.js
v8natives.js
array.js
string.js
uri.js
math.js
messages.js
apinatives.js
debug-delay.js
mirror-delay.js
date-delay.js
regexp-delay.js
json-delay.js
'''.split()


def Abort(message):
  print message
  sys.exit(1)


def ConfigureObjectFiles():
  env = Environment()
  env.Replace(**context.flags['v8'])
  context.ApplyEnvOverrides(env)
  env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
  env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE"')

  # Build the standard platform-independent source files.
  source_files = context.GetRelevantSources(SOURCES)

  d8_files = context.GetRelevantSources(D8_FILES)
  d8_js = env.JS2C('d8-js.cc', 'd8.js', TYPE='D8')
  d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.'])
  d8_objs = [context.ConfigureObject(env, [d8_files]), d8_js_obj]

  # Combine the JavaScript library files into a single C++ file and
  # compile it.
  library_files = [s for s in LIBRARY_FILES]
  library_files.append('macros.py')
  libraries_src, libraries_empty_src = env.JS2C(['libraries.cc', 'libraries-empty.cc'], library_files, TYPE='CORE')
  libraries_obj = context.ConfigureObject(env, libraries_src, CPPPATH=['.'])

  # Build dtoa.
  dtoa_env = env.Copy()
  dtoa_env.Replace(**context.flags['dtoa'])
  dtoa_files = ['dtoa-config.c']
  dtoa_obj = context.ConfigureObject(dtoa_env, dtoa_files)

  source_objs = context.ConfigureObject(env, source_files)
  non_snapshot_files = [dtoa_obj, source_objs]

  # Create snapshot if necessary.
  empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc')
  mksnapshot_env = env.Copy()
  mksnapshot_env.Replace(**context.flags['mksnapshot'])
  mksnapshot_src = 'mksnapshot.cc'
  mksnapshot = mksnapshot_env.Program('mksnapshot', [mksnapshot_src, libraries_obj, non_snapshot_files, empty_snapshot_obj], PDB='mksnapshot.exe.pdb')
  if context.use_snapshot:
    if context.build_snapshot:
      snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath)
    else:
      snapshot_cc = Command('snapshot.cc', [], [])
    snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
    libraries_obj = context.ConfigureObject(env, libraries_empty_src, CPPPATH=['.'])
  else:
    snapshot_obj = empty_snapshot_obj
  library_objs = [non_snapshot_files, libraries_obj, snapshot_obj]
  return (library_objs, d8_objs, [mksnapshot])


(library_objs, d8_objs, mksnapshot) = ConfigureObjectFiles()
Return('library_objs d8_objs mksnapshot')
