blob: a33cbfc6cb2382baf0391fcf9f25a2048f75c941 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "accessors.h"
31#include "api.h"
32#include "bootstrapper.h"
33#include "compiler.h"
34#include "debug.h"
35#include "execution.h"
36#include "global-handles.h"
37#include "natives.h"
38#include "runtime.h"
39
40namespace v8 { namespace internal {
41
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
44 Handle<JSArray> array) {
45 CALL_HEAP_FUNCTION(content->AddKeysFromJSArray(*array), FixedArray);
46}
47
48
49Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
50 Handle<FixedArray> second) {
51 CALL_HEAP_FUNCTION(first->UnionOfKeys(*second), FixedArray);
52}
53
54
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000055Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056 Handle<JSFunction> constructor,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000057 Handle<JSGlobalProxy> global) {
58 CALL_HEAP_FUNCTION(Heap::ReinitializeJSGlobalProxy(*constructor, *global),
59 JSGlobalProxy);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000060}
61
62
63void SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
64 func->shared()->set_expected_nof_properties(nof);
65 if (func->has_initial_map()) {
66 Handle<Map> new_initial_map =
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000067 Factory::CopyMapDropTransitions(Handle<Map>(func->initial_map()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068 new_initial_map->set_unused_property_fields(nof);
69 func->set_initial_map(*new_initial_map);
70 }
71}
72
73
74void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) {
75 CALL_HEAP_FUNCTION_VOID(func->SetPrototype(*value));
76}
77
78
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000079static int ExpectedNofPropertiesFromEstimate(int estimate) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 // TODO(1231235): We need dynamic feedback to estimate the number
81 // of expected properties in an object. The static hack below
82 // is barely a solution.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000083 if (estimate == 0) return 4;
84 return estimate + 2;
85}
86
87
88void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
89 int estimate) {
90 shared->set_expected_nof_properties(
91 ExpectedNofPropertiesFromEstimate(estimate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092}
93
94
95void SetExpectedNofPropertiesFromEstimate(Handle<JSFunction> func,
96 int estimate) {
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000097 SetExpectedNofProperties(
98 func, ExpectedNofPropertiesFromEstimate(estimate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000099}
100
101
102void NormalizeProperties(Handle<JSObject> object) {
103 CALL_HEAP_FUNCTION_VOID(object->NormalizeProperties());
104}
105
106
107void NormalizeElements(Handle<JSObject> object) {
108 CALL_HEAP_FUNCTION_VOID(object->NormalizeElements());
109}
110
111
112void TransformToFastProperties(Handle<JSObject> object,
113 int unused_property_fields) {
114 CALL_HEAP_FUNCTION_VOID(
115 object->TransformToFastProperties(unused_property_fields));
116}
117
118
119void FlattenString(Handle<String> string) {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000120 StringShape shape(*string);
121 if (string->IsFlat(shape)) return;
122 CALL_HEAP_FUNCTION_VOID(string->Flatten(shape));
123 ASSERT(string->IsFlat(StringShape(*string)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124}
125
126
127Handle<Object> SetPrototype(Handle<JSFunction> function,
128 Handle<Object> prototype) {
129 CALL_HEAP_FUNCTION(Accessors::FunctionSetPrototype(*function,
130 *prototype,
131 NULL),
132 Object);
133}
134
135
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000136Handle<Object> SetProperty(Handle<JSObject> object,
137 Handle<String> key,
138 Handle<Object> value,
139 PropertyAttributes attributes) {
140 CALL_HEAP_FUNCTION(object->SetProperty(*key, *value, attributes), Object);
141}
142
143
144Handle<Object> SetProperty(Handle<Object> object,
145 Handle<Object> key,
146 Handle<Object> value,
147 PropertyAttributes attributes) {
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000148 CALL_HEAP_FUNCTION(
149 Runtime::SetObjectProperty(object, key, value, attributes), Object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150}
151
152
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000153Handle<Object> IgnoreAttributesAndSetLocalProperty(Handle<JSObject> object,
154 Handle<String> key,
155 Handle<Object> value,
156 PropertyAttributes attributes) {
157 CALL_HEAP_FUNCTION(object->
158 IgnoreAttributesAndSetLocalProperty(*key, *value, attributes), Object);
159}
160
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
162 Handle<String> key,
163 Handle<Object> value,
164 PropertyAttributes attributes) {
165 CALL_HEAP_FUNCTION(object->SetPropertyWithInterceptor(*key,
166 *value,
167 attributes),
168 Object);
169}
170
171
172Handle<Object> GetProperty(Handle<JSObject> obj,
173 const char* name) {
174 Handle<String> str = Factory::LookupAsciiSymbol(name);
175 CALL_HEAP_FUNCTION(obj->GetProperty(*str), Object);
176}
177
178
179Handle<Object> GetProperty(Handle<Object> obj,
180 Handle<Object> key) {
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000181 CALL_HEAP_FUNCTION(Runtime::GetObjectProperty(obj, key), Object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182}
183
184
185Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
186 Handle<JSObject> holder,
187 Handle<String> name,
188 PropertyAttributes* attributes) {
189 CALL_HEAP_FUNCTION(holder->GetPropertyWithInterceptor(*receiver,
190 *name,
191 attributes),
192 Object);
193}
194
195
196Handle<Object> GetPrototype(Handle<Object> obj) {
197 Handle<Object> result(obj->GetPrototype());
198 return result;
199}
200
201
202Handle<Object> DeleteElement(Handle<JSObject> obj,
203 uint32_t index) {
204 CALL_HEAP_FUNCTION(obj->DeleteElement(index), Object);
205}
206
207
208Handle<Object> DeleteProperty(Handle<JSObject> obj,
209 Handle<String> prop) {
210 CALL_HEAP_FUNCTION(obj->DeleteProperty(*prop), Object);
211}
212
213
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000214Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index) {
215 CALL_HEAP_FUNCTION(Heap::LookupSingleCharacterStringFromCode(index), Object);
216}
217
218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219Handle<String> SubString(Handle<String> str, int start, int end) {
ager@chromium.orgc3e50d82008-11-05 11:53:10 +0000220 CALL_HEAP_FUNCTION(str->Slice(start, end), String);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221}
222
223
224Handle<Object> SetElement(Handle<JSObject> object,
225 uint32_t index,
226 Handle<Object> value) {
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000227 CALL_HEAP_FUNCTION(object->SetElement(index, *value), Object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000228}
229
230
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000231Handle<JSObject> Copy(Handle<JSObject> obj) {
232 CALL_HEAP_FUNCTION(Heap::CopyJSObject(*obj), JSObject);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233}
234
235
236// Wrappers for scripts are kept alive and cached in weak global
237// handles referred from proxy objects held by the scripts as long as
238// they are used. When they are not used anymore, the garbage
239// collector will call the weak callback on the global handle
240// associated with the wrapper and get rid of both the wrapper and the
241// handle.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000242static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243 Handle<Object> cache = Utils::OpenHandle(*handle);
244 JSValue* wrapper = JSValue::cast(*cache);
245 Proxy* proxy = Script::cast(wrapper->value())->wrapper();
246 ASSERT(proxy->proxy() == reinterpret_cast<Address>(cache.location()));
247 proxy->set_proxy(0);
248 GlobalHandles::Destroy(cache.location());
249 Counters::script_wrappers.Decrement();
250}
251
252
253Handle<JSValue> GetScriptWrapper(Handle<Script> script) {
254 Handle<Object> cache(reinterpret_cast<Object**>(script->wrapper()->proxy()));
255 if (!cache.is_null()) {
256 // Return the script wrapper directly from the cache.
257 return Handle<JSValue>(JSValue::cast(*cache));
258 }
259
260 // Construct a new script wrapper.
261 Counters::script_wrappers.Increment();
262 Handle<JSFunction> constructor = Top::script_function();
263 Handle<JSValue> result =
264 Handle<JSValue>::cast(Factory::NewJSObject(constructor));
265 result->set_value(*script);
266
267 // Create a new weak global handle and use it to cache the wrapper
268 // for future use. The cache will automatically be cleared by the
269 // garbage collector when it is not used anymore.
270 Handle<Object> handle = GlobalHandles::Create(*result);
271 GlobalHandles::MakeWeak(handle.location(), NULL, &ClearWrapperCache);
272 script->wrapper()->set_proxy(reinterpret_cast<Address>(handle.location()));
273 return result;
274}
275
276
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000277// Compute the property keys from the interceptor.
278v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
279 Handle<JSObject> object) {
280 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
281 Handle<Object> data(interceptor->data());
282 v8::AccessorInfo info(
283 v8::Utils::ToLocal(receiver),
284 v8::Utils::ToLocal(data),
285 v8::Utils::ToLocal(object));
286 v8::Handle<v8::Array> result;
287 if (!interceptor->enumerator()->IsUndefined()) {
288 v8::NamedPropertyEnumerator enum_fun =
289 v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
290 LOG(ApiObjectAccess("interceptor-named-enum", *object));
291 {
292 // Leaving JavaScript.
293 VMState state(OTHER);
294 result = enum_fun(info);
295 }
296 }
297 return result;
298}
299
300
301// Compute the element keys from the interceptor.
302v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver,
303 Handle<JSObject> object) {
304 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
305 Handle<Object> data(interceptor->data());
306 v8::AccessorInfo info(
307 v8::Utils::ToLocal(receiver),
308 v8::Utils::ToLocal(data),
309 v8::Utils::ToLocal(object));
310 v8::Handle<v8::Array> result;
311 if (!interceptor->enumerator()->IsUndefined()) {
312 v8::IndexedPropertyEnumerator enum_fun =
313 v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
314 LOG(ApiObjectAccess("interceptor-indexed-enum", *object));
315 {
316 // Leaving JavaScript.
317 VMState state(OTHER);
318 result = enum_fun(info);
319 }
320 }
321 return result;
322}
323
324
325Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object) {
326 Handle<FixedArray> content = Factory::empty_fixed_array();
327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000328 JSObject* arguments_boilerplate =
329 Top::context()->global_context()->arguments_boilerplate();
330 JSFunction* arguments_function =
331 JSFunction::cast(arguments_boilerplate->map()->constructor());
332 bool allow_enumeration = (object->map()->constructor() != arguments_function);
333
334 // Only collect keys if access is permitted.
335 if (allow_enumeration) {
336 for (Handle<Object> p = object;
337 *p != Heap::null_value();
338 p = Handle<Object>(p->GetPrototype())) {
339 Handle<JSObject> current(JSObject::cast(*p));
340
ager@chromium.org236ad962008-09-25 09:45:57 +0000341 // Check access rights if required.
342 if (current->IsAccessCheckNeeded() &&
343 !Top::MayNamedAccess(*current, Heap::undefined_value(),
344 v8::ACCESS_KEYS)) {
345 Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
346 break;
347 }
348
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000349 // Compute the property keys.
350 content = UnionOfKeys(content, GetEnumPropertyKeys(current));
351
352 // Add the property keys from the interceptor.
353 if (current->HasNamedInterceptor()) {
354 v8::Handle<v8::Array> result =
355 GetKeysForNamedInterceptor(object, current);
356 if (!result.IsEmpty())
357 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
358 }
359
360 // Compute the element keys.
361 Handle<FixedArray> element_keys =
362 Factory::NewFixedArray(current->NumberOfEnumElements());
363 current->GetEnumElementKeys(*element_keys);
364 content = UnionOfKeys(content, element_keys);
365
366 // Add the element keys from the interceptor.
367 if (current->HasIndexedInterceptor()) {
368 v8::Handle<v8::Array> result =
369 GetKeysForIndexedInterceptor(object, current);
370 if (!result.IsEmpty())
371 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
372 }
373 }
374 }
375 return content;
376}
377
378
379Handle<JSArray> GetKeysFor(Handle<JSObject> object) {
380 Counters::for_in.Increment();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000381 Handle<FixedArray> elements = GetKeysInFixedArrayFor(object);
382 return Factory::NewJSArrayWithElements(elements);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000383}
384
385
386Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object) {
387 int index = 0;
388 if (object->HasFastProperties()) {
389 if (object->map()->instance_descriptors()->HasEnumCache()) {
390 Counters::enum_cache_hits.Increment();
391 DescriptorArray* desc = object->map()->instance_descriptors();
392 return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache()));
393 }
394 Counters::enum_cache_misses.Increment();
395 int num_enum = object->NumberOfEnumProperties();
396 Handle<FixedArray> storage = Factory::NewFixedArray(num_enum);
397 Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum);
398 for (DescriptorReader r(object->map()->instance_descriptors());
399 !r.eos();
400 r.advance()) {
401 if (!r.IsTransition() && !r.IsDontEnum()) {
402 (*storage)->set(index, r.GetKey());
403 (*sort_array)->set(index, Smi::FromInt(r.GetDetails().index()));
404 index++;
405 }
406 }
407 (*storage)->SortPairs(*sort_array);
408 Handle<FixedArray> bridge_storage =
409 Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength);
410 DescriptorArray* desc = object->map()->instance_descriptors();
411 desc->SetEnumCache(*bridge_storage, *storage);
412 ASSERT(storage->length() == index);
413 return storage;
414 } else {
415 int num_enum = object->NumberOfEnumProperties();
416 Handle<FixedArray> storage = Factory::NewFixedArray(num_enum);
417 Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum);
418 object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array);
419 return storage;
420 }
421}
422
423
424bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000425 ClearExceptionFlag flag,
426 int loop_nesting) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 // Compile the source information to a code object.
428 ASSERT(!shared->is_compiled());
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000429 bool result = Compiler::CompileLazy(shared, loop_nesting);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000430 ASSERT(result != Top::has_pending_exception());
431 if (!result && flag == CLEAR_EXCEPTION) Top::clear_pending_exception();
432 return result;
433}
434
435
436bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
437 // Compile the source information to a code object.
438 Handle<SharedFunctionInfo> shared(function->shared());
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000439 return CompileLazyShared(shared, flag, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000440}
441
442
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000443bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag) {
444 // Compile the source information to a code object.
445 Handle<SharedFunctionInfo> shared(function->shared());
446 return CompileLazyShared(shared, flag, 1);
447}
448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000449OptimizedObjectForAddingMultipleProperties::
450OptimizedObjectForAddingMultipleProperties(Handle<JSObject> object,
451 bool condition) {
452 object_ = object;
453 if (condition && object_->HasFastProperties()) {
454 // Normalize the properties of object to avoid n^2 behavior
455 // when extending the object multiple properties.
456 unused_property_fields_ = object->map()->unused_property_fields();
457 NormalizeProperties(object_);
458 has_been_transformed_ = true;
459
460 } else {
461 has_been_transformed_ = false;
462 }
463}
464
465
466OptimizedObjectForAddingMultipleProperties::
467~OptimizedObjectForAddingMultipleProperties() {
468 // Reoptimize the object to allow fast property access.
469 if (has_been_transformed_) {
470 TransformToFastProperties(object_, unused_property_fields_);
471 }
472}
473
474
475void LoadLazy(Handle<JSFunction> fun, bool* pending_exception) {
476 HandleScope scope;
477 Handle<FixedArray> info(FixedArray::cast(fun->shared()->lazy_load_data()));
478 int index = Smi::cast(info->get(0))->value();
479 ASSERT(index >= 0);
480 Handle<Context> compile_context(Context::cast(info->get(1)));
481 Handle<Context> function_context(Context::cast(info->get(2)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000482 Handle<Object> receiver(compile_context->global()->builtins());
483
484 Vector<const char> name = Natives::GetScriptName(index);
485
486 Handle<JSFunction> boilerplate;
487
488 if (!Bootstrapper::NativesCacheLookup(name, &boilerplate)) {
489 Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
490 Handle<String> script_name = Factory::NewStringFromAscii(name);
491 bool allow_natives_syntax = FLAG_allow_natives_syntax;
492 FLAG_allow_natives_syntax = true;
493 boilerplate = Compiler::Compile(source_code, script_name, 0, 0, NULL, NULL);
494 FLAG_allow_natives_syntax = allow_natives_syntax;
495 // If the compilation failed (possibly due to stack overflows), we
496 // should never enter the result in the natives cache. Instead we
497 // return from the function without marking the function as having
498 // been lazily loaded.
499 if (boilerplate.is_null()) {
500 *pending_exception = true;
501 return;
502 }
503 Bootstrapper::NativesCacheAdd(name, boilerplate);
504 }
505
506 // We shouldn't get here if compiling the script failed.
507 ASSERT(!boilerplate.is_null());
508
509 // When the debugger running in its own context touches lazy loaded
510 // functions loading can be triggered. In that case ensure that the
511 // execution of the boilerplate is in the correct context.
512 SaveContext save;
513 if (!Debug::debug_context().is_null() &&
514 Top::context() == *Debug::debug_context()) {
515 Top::set_context(*compile_context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516 }
517
518 // Reset the lazy load data before running the script to make sure
519 // not to get recursive lazy loading.
520 fun->shared()->set_lazy_load_data(Heap::undefined_value());
521
522 // Run the script.
523 Handle<JSFunction> script_fun(
524 Factory::NewFunctionFromBoilerplate(boilerplate, function_context));
525 Execution::Call(script_fun, receiver, 0, NULL, pending_exception);
526
527 // If lazy loading failed, restore the unloaded state of fun.
528 if (*pending_exception) fun->shared()->set_lazy_load_data(*info);
529}
530
531
532void SetupLazy(Handle<JSFunction> fun,
533 int index,
534 Handle<Context> compile_context,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000535 Handle<Context> function_context) {
536 Handle<FixedArray> arr = Factory::NewFixedArray(3);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000537 arr->set(0, Smi::FromInt(index));
538 arr->set(1, *compile_context); // Compile in this context
539 arr->set(2, *function_context); // Set function context to this
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000540 fun->shared()->set_lazy_load_data(*arr);
541}
542
543} } // namespace v8::internal