説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "v8.h"
00029
00030 #include "bootstrapper.h"
00031 #include "debug.h"
00032 #include "scopeinfo.h"
00033
00034 namespace v8 { namespace internal {
00035
00036 JSBuiltinsObject* Context::builtins() {
00037 GlobalObject* object = global();
00038 if (object->IsJSGlobalObject()) {
00039 return JSGlobalObject::cast(object)->builtins();
00040 } else {
00041 ASSERT(object->IsJSBuiltinsObject());
00042 return JSBuiltinsObject::cast(object);
00043 }
00044 }
00045
00046
00047 Context* Context::global_context() {
00048
00049
00050
00051 if (global()->IsGlobalObject()) {
00052 return global()->global_context();
00053 }
00054
00055
00056 Context* current = this;
00057 while (!current->IsGlobalContext()) {
00058 current = Context::cast(JSFunction::cast(current->closure())->context());
00059 }
00060 return current;
00061 }
00062
00063
00064 JSObject* Context::global_proxy() {
00065 return global_context()->global_proxy_object();
00066 }
00067
00068 void Context::set_global_proxy(JSObject* object) {
00069 global_context()->set_global_proxy_object(object);
00070 }
00071
00072
00073 Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
00074 int* index_, PropertyAttributes* attributes) {
00075 Handle<Context> context(this);
00076
00077
00078 if (kDebug && !Debug::InDebugger()) {
00079 StackFrameLocator locator;
00080 ASSERT(context->fcontext() ==
00081 Context::cast(
00082 locator.FindJavaScriptFrame(0)->context())->fcontext());
00083 }
00084
00085 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0;
00086 *index_ = -1;
00087 *attributes = ABSENT;
00088
00089 if (FLAG_trace_contexts) {
00090 PrintF("Context::Lookup(");
00091 name->ShortPrint();
00092 PrintF(")\n");
00093 }
00094
00095 do {
00096 if (FLAG_trace_contexts) {
00097 PrintF(" - looking in context %p", *context);
00098 if (context->IsGlobalContext()) PrintF(" (global context)");
00099 PrintF("\n");
00100 }
00101
00102
00103 if (context->has_extension()) {
00104 Handle<JSObject> extension = Handle<JSObject>(context->extension());
00105 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) {
00106 *attributes = extension->GetLocalPropertyAttribute(*name);
00107 } else {
00108 *attributes = extension->GetPropertyAttribute(*name);
00109 }
00110 if (*attributes != ABSENT) {
00111
00112 if (FLAG_trace_contexts) {
00113 PrintF("=> found property in context object %p\n", *extension);
00114 }
00115 return extension;
00116 }
00117 }
00118
00119 if (context->is_function_context()) {
00120
00121
00122
00123 Handle<Code> code(context->closure()->code());
00124 Variable::Mode mode;
00125 int index = ScopeInfo<>::ContextSlotIndex(*code, *name, &mode);
00126 ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
00127 if (index >= 0) {
00128
00129 if (FLAG_trace_contexts) {
00130 PrintF("=> found local in context slot %d (mode = %d)\n",
00131 index, mode);
00132 }
00133 *index_ = index;
00134
00135
00136
00137
00138
00139
00140 switch (mode) {
00141 case Variable::INTERNAL :
00142 case Variable::VAR : *attributes = NONE; break;
00143 case Variable::CONST : *attributes = READ_ONLY; break;
00144 case Variable::DYNAMIC : UNREACHABLE(); break;
00145 case Variable::TEMPORARY: UNREACHABLE(); break;
00146 }
00147 return context;
00148 }
00149
00150
00151 int param_index = ScopeInfo<>::ParameterIndex(*code, *name);
00152 if (param_index >= 0) {
00153
00154 int index =
00155 ScopeInfo<>::ContextSlotIndex(*code,
00156 Heap::arguments_shadow_symbol(),
00157 NULL);
00158 ASSERT(index >= 0);
00159 Handle<JSObject> arguments(JSObject::cast(context->get(index)));
00160 ASSERT(arguments->HasLocalProperty(Heap::length_symbol()));
00161 if (FLAG_trace_contexts) {
00162 PrintF("=> found parameter %d in arguments object\n", param_index);
00163 }
00164 *index_ = param_index;
00165 *attributes = NONE;
00166 return arguments;
00167 }
00168
00169
00170 if (follow_context_chain) {
00171 int index = ScopeInfo<>::FunctionContextSlotIndex(*code, *name);
00172 if (index >= 0) {
00173
00174 if (FLAG_trace_contexts) {
00175 PrintF("=> found intermediate function in context slot %d\n",
00176 index);
00177 }
00178 *index_ = index;
00179 *attributes = READ_ONLY;
00180 return context;
00181 }
00182 }
00183 }
00184
00185
00186 if (context->IsGlobalContext()) {
00187 follow_context_chain = false;
00188 } else if (context->is_function_context()) {
00189 context = Handle<Context>(Context::cast(context->closure()->context()));
00190 } else {
00191 context = Handle<Context>(context->previous());
00192 }
00193 } while (follow_context_chain);
00194
00195
00196 if (FLAG_trace_contexts) {
00197 PrintF("=> no property/slot found\n");
00198 }
00199 return Handle<Object>::null();
00200 }
00201
00202
00203 #ifdef DEBUG
00204 bool Context::IsBootstrappingOrContext(Object* object) {
00205
00206
00207 return Bootstrapper::IsActive() || object->IsContext();
00208 }
00209
00210
00211 bool Context::IsBootstrappingOrGlobalObject(Object* object) {
00212
00213
00214 return Bootstrapper::IsActive() || object->IsGlobalObject();
00215 }
00216 #endif
00217
00218 } }