2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/compiler/analysis/emitter.h"
18 #include "hphp/runtime/base/runtime-option.h"
19 #include "hphp/runtime/base/execution-context.h"
20 #include "hphp/runtime/base/program-functions.h"
21 #include "hphp/runtime/ext/ext.h"
22 #include "hphp/runtime/vm/unit.h"
23 #include "hphp/runtime/vm/bytecode.h"
24 #include "hphp/runtime/vm/repo.h"
25 #include "hphp/runtime/vm/runtime.h"
26 #include "hphp/runtime/ext_hhvm/ext_hhvm.h"
27 #include "hphp/runtime/vm/jit/translator.h"
28 #include "hphp/runtime/base/rds.h"
29 #include "hphp/runtime/vm/jit/fixup.h"
30 #include "hphp/runtime/vm/jit/mc-generator.h"
31 #include "hphp/runtime/base/unit-cache.h"
32 #include "hphp/system/systemlib.h"
33 #include "hphp/util/logger.h"
35 #include <libgen.h> // For dirname(3).
40 ///////////////////////////////////////////////////////////////////////////////
42 #define STRINGIZE_CLASS_NAME(cls) #cls
43 #define pinitSentinel __pinitSentinel
44 #define resource __resource
46 #define SYSTEM_CLASS_STRING(cls) \
47 const StaticString s_##cls(LITSTR_INIT(STRINGIZE_CLASS_NAME(cls)));
48 SYSTEMLIB_CLASSES(SYSTEM_CLASS_STRING
)
52 #undef STRINGIZE_CLASS_NAME
55 // Create the global mcg object
56 JIT::mcg
= new JIT::MCGenerator();
57 JIT::tx
= &JIT::mcg
->tx();
58 JIT::mcg
->initUniqueStubs();
60 // Save the current options, and set things up so that
61 // systemlib.php can be read from and stored in the
63 int db
= RuntimeOption::EvalDumpBytecode
;
64 bool rp
= RuntimeOption::AlwaysUseRelativePath
;
65 bool sf
= RuntimeOption::SafeFileAccess
;
66 bool ah
= RuntimeOption::EvalAllowHhas
;
67 bool wp
= Option::WholeProgram
;
68 RuntimeOption::EvalDumpBytecode
&= ~1;
69 RuntimeOption::AlwaysUseRelativePath
= false;
70 RuntimeOption::SafeFileAccess
= false;
71 RuntimeOption::EvalAllowHhas
= true;
72 Option::WholeProgram
= false;
76 string slib
= get_systemlib(&hhas
);
79 // Die a horrible death.
80 Logger::Error("Unable to find/load systemlib.php");
85 LitstrTable::get().setWriting();
86 Repo::get().loadGlobalData();
88 // Save this in case the debugger needs it. Once we know if this
89 // process does not have debugger support, we'll clear it.
90 SystemLib::s_source
= slib
;
92 SystemLib::s_unit
= compile_systemlib_string(slib
.c_str(), slib
.size(),
95 const StringData
* msg
;
97 if (SystemLib::s_unit
->compileTimeFatal(msg
, line
)) {
98 Logger::Error("An error has been introduced into the systemlib, "
99 "but we cannot give you a file and line number right now.");
100 Logger::Error("Check all of your changes to hphp/system/php");
101 Logger::Error("HipHop Parse Error: %s", msg
->data());
106 SystemLib::s_hhas_unit
= compile_string(hhas
.c_str(), hhas
.size(),
108 if (SystemLib::s_hhas_unit
->compileTimeFatal(msg
, line
)) {
109 Logger::Error("An error has been introduced in the hhas portion of "
111 Logger::Error("Check all of your changes to hhas files in "
113 Logger::Error("HipHop Parse Error: %s", msg
->data());
118 // Load the systemlib unit to build the Class objects
119 SystemLib::s_unit
->merge();
120 if (SystemLib::s_hhas_unit
) {
121 SystemLib::s_hhas_unit
->merge();
124 SystemLib::s_nativeFuncUnit
= build_native_func_unit(hhbc_ext_funcs
,
125 hhbc_ext_funcs_count
);
126 SystemLib::s_nativeFuncUnit
->merge();
127 SystemLib::s_nullFunc
=
128 Unit::lookupFunc(makeStaticString("86null"));
130 // We call a special bytecode emitter function to build the native
131 // unit which will contain all of our cppext functions and classes.
132 // Each function and method will have a bytecode body that will thunk
133 // to the native implementation.
134 Unit
* nativeClassUnit
= build_native_class_unit(hhbc_ext_classes
,
135 hhbc_ext_class_count
);
136 SystemLib::s_nativeClassUnit
= nativeClassUnit
;
138 LitstrTable::get().setReading();
140 // Load the nativelib unit to build the Class objects
141 SystemLib::s_nativeClassUnit
->merge();
143 #define INIT_SYSTEMLIB_CLASS_FIELD(cls) \
145 Class *cls = Unit::GetNamedEntity(s_##cls.get())->clsList(); \
146 assert(!hhbc_ext_class_count || cls); \
147 SystemLib::s_##cls##Class = cls; \
150 // Stash a pointer to the VM Classes for stdclass, Exception,
151 // pinitSentinel and resource
152 SYSTEMLIB_CLASSES(INIT_SYSTEMLIB_CLASS_FIELD
)
154 #undef INIT_SYSTEMLIB_CLASS_FIELD
156 // Retrieve all of the class pointers
157 for (long long i
= 0; i
< hhbc_ext_class_count
; ++i
) {
158 const HhbcExtClassInfo
* info
= hhbc_ext_classes
+ i
;
159 const StringData
* name
= makeStaticString(info
->m_name
);
160 const NamedEntity
* ne
= Unit::GetNamedEntity(name
);
161 Class
* cls
= Unit::lookupClass(ne
);
163 *(info
->m_clsPtr
) = cls
;
166 ClassInfo::InitializeSystemConstants();
167 Stack::ValidateStackSize();
168 SystemLib::s_inited
= true;
170 RuntimeOption::AlwaysUseRelativePath
= rp
;
171 RuntimeOption::SafeFileAccess
= sf
;
172 RuntimeOption::EvalDumpBytecode
= db
;
173 RuntimeOption::EvalAllowHhas
= ah
;
174 Option::WholeProgram
= wp
;
177 ///////////////////////////////////////////////////////////////////////////////