Source code drop for the Actionscript virtual machine in the Adobe Flash Player for December 2013
212 lines
6.0 KiB
C++
212 lines
6.0 KiB
C++
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
|
|
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef __avmshell__
|
|
#define __avmshell__
|
|
|
|
#include "avmplus.h"
|
|
|
|
#include "extensions-tracers.h"
|
|
#include "avmshell-tracers.h"
|
|
|
|
#ifdef VMCFG_SELFTEST
|
|
// Allow selftests coded directly to nanojit APIs.
|
|
#include "../nanojit/nanojit.h"
|
|
#endif
|
|
|
|
#if defined AVMPLUS_MAC || defined AVMPLUS_UNIX
|
|
// Support for the -workers switch and distributing files across
|
|
// multiple AvmCores on multiple threads. Only the code in the
|
|
// shell depends on this setting; the AVM core code works out of
|
|
// the box.
|
|
//
|
|
// Requires pthreads.
|
|
#define VMCFG_WORKERTHREADS
|
|
#endif
|
|
|
|
#if defined VMCFG_TESTING
|
|
// We simulate Flash's use of API versioning for testing only.
|
|
#define VMCFG_TEST_VERSIONING
|
|
#endif
|
|
|
|
#if !defined(UNDER_CE) && !defined(AVM_SHELL_NO_PROJECTOR)
|
|
# define AVMSHELL_PROJECTOR_SUPPORT
|
|
#endif
|
|
|
|
#ifndef INT32_T_MAX
|
|
#define INT32_T_MAX (int32_t(0x7FFFFFFFL)) //max value for a 32-bit integer
|
|
#endif
|
|
#ifndef UINT32_T_MAX
|
|
#define UINT32_T_MAX (uint32_t(0xFFFFFFFFUL)) //max value for a 32-bit unsigned integer
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable:4996) // 'scanf' was declared deprecated
|
|
#endif
|
|
|
|
// forward declarations for shell_toplevel.h
|
|
namespace avmshell
|
|
{
|
|
class SystemClass;
|
|
}
|
|
namespace avmplus
|
|
{
|
|
class SampleObject;
|
|
class StackFrameObject;
|
|
class NewObjectSampleObject;
|
|
class TraceClass;
|
|
class Isolate;
|
|
|
|
}
|
|
|
|
#include "shell_toplevel.h"
|
|
|
|
namespace avmshell
|
|
{
|
|
class Shell;
|
|
class ShellIsolate;
|
|
class ShellCodeContext;
|
|
class ShellCore;
|
|
class ShellCoreImpl;
|
|
class ShellSettings;
|
|
class ShellToplevel;
|
|
class EnvelopeClass;
|
|
class EnvelopeObject;
|
|
|
|
}
|
|
|
|
#include "Selftest.h"
|
|
#include "Platform.h"
|
|
#include "File.h"
|
|
|
|
#include "FileInputStream.h"
|
|
#include "ConsoleOutputStream.h"
|
|
#include "SystemClass.h"
|
|
#include "FileClass.h"
|
|
#include "DomainClass.h"
|
|
#include "DebugCLI.h"
|
|
#include "DataIO.h"
|
|
#include "DictionaryGlue.h"
|
|
#include "SamplerScript.h"
|
|
#include "ShellCore.h"
|
|
#include "ShellWorkerGlue.h"
|
|
#include "ShellWorkerDomainGlue.h"
|
|
|
|
#include "shell_toplevel-classes.hh"
|
|
|
|
namespace avmshell
|
|
{
|
|
// The stack margin is the amount of stack that should be available to native
|
|
// code that does not itself check for stack overflow. The execution engines
|
|
// in the VM will reserve this amount of stack.
|
|
|
|
#ifdef AVMPLUS_64BIT
|
|
const size_t kStackMargin = 262144;
|
|
#elif (defined AVMPLUS_WIN32 && (defined UNDER_CE || defined UNDER_RT) ) || defined VMCFG_SYMBIAN
|
|
// FIXME: all embedded platforms, but we have no way of expressing that now
|
|
const size_t kStackMargin = 32768;
|
|
#else
|
|
const size_t kStackMargin = 131072;
|
|
#endif
|
|
|
|
// The fallback stack size is probably not safe but is used by the shell code
|
|
// if it fails to obtain the stack size from the operating system.
|
|
// 512KB is the traditional value.
|
|
|
|
const size_t kStackSizeFallbackValue = 512*1024;
|
|
|
|
// exit codes
|
|
enum {
|
|
OUT_OF_MEMORY = 128
|
|
};
|
|
|
|
// swf support, impl code in swf.cpp
|
|
bool isSwf(avmplus::ScriptBuffer);
|
|
bool handleSwf(const char *, avmplus::ScriptBuffer, avmplus::Toplevel*, avmplus::CodeContext*, bool test_only);
|
|
|
|
#ifdef VMCFG_AOT
|
|
// AOT support, impl code in aot.cpp
|
|
void handleAOT(avmplus::AvmCore*, avmplus::Domain*, avmplus::DomainEnv*, avmplus::Toplevel*, avmplus::CodeContext*);
|
|
#endif
|
|
|
|
class ShellSettings : public ShellCoreSettings
|
|
{
|
|
public:
|
|
ShellSettings();
|
|
|
|
char* programFilename; // name of the executable, or NULL
|
|
char** filenames; // non-terminated array of file names, never NULL
|
|
int numfiles; // number of entries in 'filenames'
|
|
bool do_selftest;
|
|
bool do_repl;
|
|
bool do_log;
|
|
bool do_projector;
|
|
int numthreads;
|
|
int numworkers;
|
|
int repeats;
|
|
uint32_t stackSize;
|
|
char st_mem[200]; // Selftest scratch memory. 200 chars ought to be enough for anyone
|
|
};
|
|
|
|
class ShellIsolate : public avmplus::Isolate
|
|
{
|
|
|
|
public:
|
|
ShellIsolate(int32_t desc, int32_t parentDesc, avmplus::Aggregate* aggregate);
|
|
virtual void doRun();
|
|
virtual void copyByteCode(avmplus::ByteArrayObject* ba);
|
|
virtual avmplus::ScriptObject* newWorkerObject(avmplus::Toplevel* toplevel);
|
|
|
|
void evalCodeBlobs(bool enter_debugger_on_launch);
|
|
};
|
|
|
|
/**
|
|
* Shell driver and command line parser.
|
|
*/
|
|
class Shell : public avmplus::Aggregate {
|
|
friend class PrimordialShellIsolate;
|
|
friend class ShellIsolate;
|
|
public:
|
|
static int run(int argc, char *argv[]);
|
|
|
|
private:
|
|
#ifdef VMCFG_WORKERTHREADS
|
|
static void multiWorker(ShellSettings& settings);
|
|
#endif
|
|
static void repl(ShellCore* shellCore);
|
|
static void initializeLogging(const char* basename);
|
|
void parseCommandLine(int argc, char* argv[]);
|
|
static void usage();
|
|
ShellSettings settings;
|
|
};
|
|
|
|
|
|
/**
|
|
* A subclass of ShellCore that provides an implementation of setStackLimit().
|
|
*/
|
|
class ShellCoreImpl : public ShellCore {
|
|
public:
|
|
/**
|
|
* @param gc The garbage collector for this core
|
|
* @param mainthread True if this core is being used on the main thread and not on a spawned
|
|
* thread. It must be one or the other; a core created on a spawned thread
|
|
* cannot be used on the main thread or vice versa.
|
|
*/
|
|
ShellCoreImpl(MMgc::GC* gc, ShellSettings& settings, bool mainthread);
|
|
|
|
/**
|
|
* Set AvmCore::minstack appropriately for the current thread.
|
|
*/
|
|
virtual void setStackLimit();
|
|
|
|
private:
|
|
ShellSettings& settings;
|
|
bool mainthread;
|
|
};
|
|
}
|
|
|
|
#endif /* __avmshell__ */
|