[ES6] implement block scoping to enable 'let'
[WebKit-https.git] / Source / JavaScriptCore / runtime / CommonSlowPaths.cpp
1 /*
2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "CommonSlowPaths.h"
28 #include "ArityCheckFailReturnThunks.h"
29 #include "ArrayConstructor.h"
30 #include "CallFrame.h"
31 #include "ClonedArguments.h"
32 #include "CodeProfiling.h"
33 #include "CommonSlowPathsExceptions.h"
34 #include "DirectArguments.h"
35 #include "Error.h"
36 #include "ErrorHandlingScope.h"
37 #include "ExceptionFuzz.h"
38 #include "GetterSetter.h"
39 #include "HostCallReturnValue.h"
40 #include "Interpreter.h"
41 #include "JIT.h"
42 #include "JITStubs.h"
43 #include "JSCInlines.h"
44 #include "JSCJSValue.h"
45 #include "JSGlobalObjectFunctions.h"
46 #include "JSLexicalEnvironment.h"
47 #include "JSNameScope.h"
48 #include "JSPropertyNameEnumerator.h"
49 #include "JSString.h"
50 #include "JSWithScope.h"
51 #include "LLIntCommon.h"
52 #include "LLIntExceptions.h"
53 #include "LowLevelInterpreter.h"
54 #include "ObjectConstructor.h"
55 #include "ScopedArguments.h"
56 #include "StructureRareDataInlines.h"
57 #include "TypeProfilerLog.h"
58 #include <wtf/StringPrintStream.h>
59
60 namespace JSC {
61
62 #define BEGIN_NO_SET_PC() \
63     VM& vm = exec->vm();      \
64     NativeCallFrameTracer tracer(&vm, exec)
65
66 #ifndef NDEBUG
67 #define SET_PC_FOR_STUBS() do { \
68         exec->codeBlock()->bytecodeOffset(pc); \
69         exec->setCurrentVPC(pc + 1); \
70     } while (false)
71 #else
72 #define SET_PC_FOR_STUBS() do { \
73         exec->setCurrentVPC(pc + 1); \
74     } while (false)
75 #endif
76
77 #define RETURN_TO_THROW(exec, pc)   pc = LLInt::returnToThrow(exec)
78
79 #define BEGIN()                           \
80     BEGIN_NO_SET_PC();                    \
81     SET_PC_FOR_STUBS()
82
83 #define OP(index) (exec->uncheckedR(pc[index].u.operand))
84 #define OP_C(index) (exec->r(pc[index].u.operand))
85
86 #define RETURN_TWO(first, second) do {       \
87         return encodeResult(first, second);        \
88     } while (false)
89
90 #define END_IMPL() RETURN_TWO(pc, exec)
91
92 #define THROW(exceptionToThrow) do {                        \
93         vm.throwException(exec, exceptionToThrow);          \
94         RETURN_TO_THROW(exec, pc);                          \
95         END_IMPL();                                         \
96     } while (false)
97
98 #define CHECK_EXCEPTION() do {                    \
99         doExceptionFuzzingIfEnabled(exec, "CommonSlowPaths", pc);   \
100         if (UNLIKELY(vm.exception())) {           \
101             RETURN_TO_THROW(exec, pc);               \
102             END_IMPL();                           \
103         }                                               \
104     } while (false)
105
106 #define END() do {                        \
107         CHECK_EXCEPTION();                \
108         END_IMPL();                       \
109     } while (false)
110
111 #define BRANCH(opcode, condition) do {                      \
112         bool bCondition = (condition);                         \
113         CHECK_EXCEPTION();                                  \
114         if (bCondition)                                        \
115             pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand;        \
116         else                                                      \
117             pc += OPCODE_LENGTH(opcode);                          \
118         END_IMPL();                                         \
119     } while (false)
120
121 #define RETURN(value) do {                \
122         JSValue rReturnValue = (value);      \
123         CHECK_EXCEPTION();                \
124         OP(1) = rReturnValue;          \
125         END_IMPL();                       \
126     } while (false)
127
128 #define RETURN_PROFILED(opcode, value) do {                  \
129         JSValue rpPeturnValue = (value);                     \
130         CHECK_EXCEPTION();                                   \
131         OP(1) = rpPeturnValue;                               \
132         PROFILE_VALUE(opcode, rpPeturnValue);                \
133         END_IMPL();                                          \
134     } while (false)
135
136 #define PROFILE_VALUE(opcode, value) do { \
137         pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
138         JSValue::encode(value);                  \
139     } while (false)
140
141 #define CALL_END_IMPL(exec, callTarget) RETURN_TWO((callTarget), (exec))
142
143 #define CALL_THROW(exec, pc, exceptionToThrow) do {                     \
144         ExecState* ctExec = (exec);                                     \
145         Instruction* ctPC = (pc);                                       \
146         vm.throwException(exec, exceptionToThrow);                      \
147         CALL_END_IMPL(ctExec, LLInt::callToThrow(ctExec));              \
148     } while (false)
149
150 #define CALL_CHECK_EXCEPTION(exec, pc) do {                          \
151         ExecState* cceExec = (exec);                                 \
152         Instruction* ccePC = (pc);                                   \
153         if (UNLIKELY(vm.exception()))                                \
154             CALL_END_IMPL(cceExec, LLInt::callToThrow(cceExec));     \
155     } while (false)
156
157 #define CALL_RETURN(exec, pc, callTarget) do {                    \
158         ExecState* crExec = (exec);                                  \
159         Instruction* crPC = (pc);                                    \
160         void* crCallTarget = (callTarget);                           \
161         CALL_CHECK_EXCEPTION(crExec->callerFrame(), crPC);  \
162         CALL_END_IMPL(crExec, crCallTarget);                \
163     } while (false)
164
165 static CommonSlowPaths::ArityCheckData* setupArityCheckData(VM& vm, int slotsToAdd)
166 {
167     CommonSlowPaths::ArityCheckData* result = vm.arityCheckData.get();
168     result->paddedStackSpace = slotsToAdd;
169 #if ENABLE(JIT)
170     if (vm.canUseJIT()) {
171         result->thunkToCall = vm.getCTIStub(arityFixupGenerator).code().executableAddress();
172         result->returnPC = vm.arityCheckFailReturnThunks->returnPCFor(vm, slotsToAdd * stackAlignmentRegisters()).executableAddress();
173     } else
174 #endif
175     {
176         result->thunkToCall = 0;
177         result->returnPC = 0;
178     }
179     return result;
180 }
181
182 SLOW_PATH_DECL(slow_path_call_arityCheck)
183 {
184     BEGIN();
185     int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall);
186     if (slotsToAdd < 0) {
187         exec = exec->callerFrame();
188         ErrorHandlingScope errorScope(exec->vm());
189         CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
190         RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
191     }
192     RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd));
193 }
194
195 SLOW_PATH_DECL(slow_path_construct_arityCheck)
196 {
197     BEGIN();
198     int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct);
199     if (slotsToAdd < 0) {
200         exec = exec->callerFrame();
201         ErrorHandlingScope errorScope(exec->vm());
202         CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
203         RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
204     }
205     RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd));
206 }
207
208 SLOW_PATH_DECL(slow_path_create_direct_arguments)
209 {
210     BEGIN();
211     RETURN(DirectArguments::createByCopying(exec));
212 }
213
214 SLOW_PATH_DECL(slow_path_create_scoped_arguments)
215 {
216     BEGIN();
217     JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue());
218     ScopedArgumentsTable* table = exec->codeBlock()->symbolTable()->arguments();
219     RETURN(ScopedArguments::createByCopying(exec, table, scope));
220 }
221
222 SLOW_PATH_DECL(slow_path_create_out_of_band_arguments)
223 {
224     BEGIN();
225     RETURN(ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned));
226 }
227
228 SLOW_PATH_DECL(slow_path_create_this)
229 {
230     BEGIN();
231     JSFunction* constructor = jsCast<JSFunction*>(OP(2).jsValue().asCell());
232     
233 #if !ASSERT_DISABLED
234     ConstructData constructData;
235     ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
236 #endif
237
238     auto& cacheWriteBarrier = pc[4].u.jsCell;
239     if (!cacheWriteBarrier)
240         cacheWriteBarrier.set(exec->vm(), exec->codeBlock()->ownerExecutable(), constructor);
241     else if (cacheWriteBarrier.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cacheWriteBarrier.get() != constructor)
242         cacheWriteBarrier.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
243
244     size_t inlineCapacity = pc[3].u.operand;
245     Structure* structure = constructor->rareData(exec, inlineCapacity)->allocationProfile()->structure();
246     RETURN(constructEmptyObject(exec, structure));
247 }
248
249 SLOW_PATH_DECL(slow_path_to_this)
250 {
251     BEGIN();
252     JSValue v1 = OP(1).jsValue();
253     if (v1.isCell()) {
254         Structure* myStructure = v1.asCell()->structure(vm);
255         Structure* otherStructure = pc[2].u.structure.get();
256         if (myStructure != otherStructure) {
257             if (otherStructure)
258                 pc[3].u.toThisStatus = ToThisConflicted;
259             pc[2].u.structure.set(vm, exec->codeBlock()->ownerExecutable(), myStructure);
260         }
261     } else {
262         pc[3].u.toThisStatus = ToThisConflicted;
263         pc[2].u.structure.clear();
264     }
265     RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode));
266 }
267
268 SLOW_PATH_DECL(slow_path_throw_tdz_error)
269 {
270     BEGIN();
271     THROW(createTDZError(exec));
272 }
273
274 SLOW_PATH_DECL(slow_path_not)
275 {
276     BEGIN();
277     RETURN(jsBoolean(!OP_C(2).jsValue().toBoolean(exec)));
278 }
279
280 SLOW_PATH_DECL(slow_path_eq)
281 {
282     BEGIN();
283     RETURN(jsBoolean(JSValue::equal(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
284 }
285
286 SLOW_PATH_DECL(slow_path_neq)
287 {
288     BEGIN();
289     RETURN(jsBoolean(!JSValue::equal(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
290 }
291
292 SLOW_PATH_DECL(slow_path_stricteq)
293 {
294     BEGIN();
295     RETURN(jsBoolean(JSValue::strictEqual(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
296 }
297
298 SLOW_PATH_DECL(slow_path_nstricteq)
299 {
300     BEGIN();
301     RETURN(jsBoolean(!JSValue::strictEqual(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
302 }
303
304 SLOW_PATH_DECL(slow_path_less)
305 {
306     BEGIN();
307     RETURN(jsBoolean(jsLess<true>(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
308 }
309
310 SLOW_PATH_DECL(slow_path_lesseq)
311 {
312     BEGIN();
313     RETURN(jsBoolean(jsLessEq<true>(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
314 }
315
316 SLOW_PATH_DECL(slow_path_greater)
317 {
318     BEGIN();
319     RETURN(jsBoolean(jsLess<false>(exec, OP_C(3).jsValue(), OP_C(2).jsValue())));
320 }
321
322 SLOW_PATH_DECL(slow_path_greatereq)
323 {
324     BEGIN();
325     RETURN(jsBoolean(jsLessEq<false>(exec, OP_C(3).jsValue(), OP_C(2).jsValue())));
326 }
327
328 SLOW_PATH_DECL(slow_path_inc)
329 {
330     BEGIN();
331     RETURN(jsNumber(OP(1).jsValue().toNumber(exec) + 1));
332 }
333
334 SLOW_PATH_DECL(slow_path_dec)
335 {
336     BEGIN();
337     RETURN(jsNumber(OP(1).jsValue().toNumber(exec) - 1));
338 }
339
340 SLOW_PATH_DECL(slow_path_to_number)
341 {
342     BEGIN();
343     RETURN(jsNumber(OP_C(2).jsValue().toNumber(exec)));
344 }
345
346 SLOW_PATH_DECL(slow_path_to_string)
347 {
348     BEGIN();
349     RETURN(OP_C(2).jsValue().toString(exec));
350 }
351
352 SLOW_PATH_DECL(slow_path_negate)
353 {
354     BEGIN();
355     RETURN(jsNumber(-OP_C(2).jsValue().toNumber(exec)));
356 }
357
358 SLOW_PATH_DECL(slow_path_add)
359 {
360     BEGIN();
361     JSValue v1 = OP_C(2).jsValue();
362     JSValue v2 = OP_C(3).jsValue();
363     
364     if (v1.isString() && !v2.isObject())
365         RETURN(jsString(exec, asString(v1), v2.toString(exec)));
366     
367     if (v1.isNumber() && v2.isNumber())
368         RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
369     
370     RETURN(jsAddSlowCase(exec, v1, v2));
371 }
372
373 // The following arithmetic and bitwise operations need to be sure to run
374 // toNumber() on their operands in order.  (A call to toNumber() is idempotent
375 // if an exception is already set on the ExecState.)
376
377 SLOW_PATH_DECL(slow_path_mul)
378 {
379     BEGIN();
380     double a = OP_C(2).jsValue().toNumber(exec);
381     double b = OP_C(3).jsValue().toNumber(exec);
382     RETURN(jsNumber(a * b));
383 }
384
385 SLOW_PATH_DECL(slow_path_sub)
386 {
387     BEGIN();
388     double a = OP_C(2).jsValue().toNumber(exec);
389     double b = OP_C(3).jsValue().toNumber(exec);
390     RETURN(jsNumber(a - b));
391 }
392
393 SLOW_PATH_DECL(slow_path_div)
394 {
395     BEGIN();
396     double a = OP_C(2).jsValue().toNumber(exec);
397     double b = OP_C(3).jsValue().toNumber(exec);
398     RETURN(jsNumber(a / b));
399 }
400
401 SLOW_PATH_DECL(slow_path_mod)
402 {
403     BEGIN();
404     double a = OP_C(2).jsValue().toNumber(exec);
405     double b = OP_C(3).jsValue().toNumber(exec);
406     RETURN(jsNumber(fmod(a, b)));
407 }
408
409 SLOW_PATH_DECL(slow_path_lshift)
410 {
411     BEGIN();
412     int32_t a = OP_C(2).jsValue().toInt32(exec);
413     uint32_t b = OP_C(3).jsValue().toUInt32(exec);
414     RETURN(jsNumber(a << (b & 31)));
415 }
416
417 SLOW_PATH_DECL(slow_path_rshift)
418 {
419     BEGIN();
420     int32_t a = OP_C(2).jsValue().toInt32(exec);
421     uint32_t b = OP_C(3).jsValue().toUInt32(exec);
422     RETURN(jsNumber(a >> (b & 31)));
423 }
424
425 SLOW_PATH_DECL(slow_path_urshift)
426 {
427     BEGIN();
428     uint32_t a = OP_C(2).jsValue().toUInt32(exec);
429     uint32_t b = OP_C(3).jsValue().toUInt32(exec);
430     RETURN(jsNumber(static_cast<int32_t>(a >> (b & 31))));
431 }
432
433 SLOW_PATH_DECL(slow_path_unsigned)
434 {
435     BEGIN();
436     uint32_t a = OP_C(2).jsValue().toUInt32(exec);
437     RETURN(jsNumber(a));
438 }
439
440 SLOW_PATH_DECL(slow_path_bitand)
441 {
442     BEGIN();
443     int32_t a = OP_C(2).jsValue().toInt32(exec);
444     int32_t b = OP_C(3).jsValue().toInt32(exec);
445     RETURN(jsNumber(a & b));
446 }
447
448 SLOW_PATH_DECL(slow_path_bitor)
449 {
450     BEGIN();
451     int32_t a = OP_C(2).jsValue().toInt32(exec);
452     int32_t b = OP_C(3).jsValue().toInt32(exec);
453     RETURN(jsNumber(a | b));
454 }
455
456 SLOW_PATH_DECL(slow_path_bitxor)
457 {
458     BEGIN();
459     int32_t a = OP_C(2).jsValue().toInt32(exec);
460     int32_t b = OP_C(3).jsValue().toInt32(exec);
461     RETURN(jsNumber(a ^ b));
462 }
463
464 SLOW_PATH_DECL(slow_path_typeof)
465 {
466     BEGIN();
467     RETURN(jsTypeStringForValue(exec, OP_C(2).jsValue()));
468 }
469
470 SLOW_PATH_DECL(slow_path_is_object_or_null)
471 {
472     BEGIN();
473     RETURN(jsBoolean(jsIsObjectTypeOrNull(exec, OP_C(2).jsValue())));
474 }
475
476 SLOW_PATH_DECL(slow_path_is_function)
477 {
478     BEGIN();
479     RETURN(jsBoolean(jsIsFunctionType(OP_C(2).jsValue())));
480 }
481
482 SLOW_PATH_DECL(slow_path_in)
483 {
484     BEGIN();
485     RETURN(jsBoolean(CommonSlowPaths::opIn(exec, OP_C(2).jsValue(), OP_C(3).jsValue())));
486 }
487
488 SLOW_PATH_DECL(slow_path_del_by_val)
489 {
490     BEGIN();
491     JSValue baseValue = OP_C(2).jsValue();
492     JSObject* baseObject = baseValue.toObject(exec);
493     
494     JSValue subscript = OP_C(3).jsValue();
495     
496     bool couldDelete;
497     
498     uint32_t i;
499     if (subscript.getUInt32(i))
500         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
501     else {
502         CHECK_EXCEPTION();
503         auto property = subscript.toPropertyKey(exec);
504         CHECK_EXCEPTION();
505         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
506     }
507     
508     if (!couldDelete && exec->codeBlock()->isStrictMode())
509         THROW(createTypeError(exec, "Unable to delete property."));
510     
511     RETURN(jsBoolean(couldDelete));
512 }
513
514 SLOW_PATH_DECL(slow_path_strcat)
515 {
516     BEGIN();
517     RETURN(jsStringFromRegisterArray(exec, &OP(2), pc[3].u.operand));
518 }
519
520 SLOW_PATH_DECL(slow_path_to_primitive)
521 {
522     BEGIN();
523     RETURN(OP_C(2).jsValue().toPrimitive(exec));
524 }
525
526 SLOW_PATH_DECL(slow_path_enter)
527 {
528     BEGIN();
529     ScriptExecutable* ownerExecutable = exec->codeBlock()->ownerExecutable();
530     Heap::heap(ownerExecutable)->writeBarrier(ownerExecutable);
531     END();
532 }
533
534 SLOW_PATH_DECL(slow_path_get_enumerable_length)
535 {
536     BEGIN();
537     JSValue enumeratorValue = OP(2).jsValue();
538     if (enumeratorValue.isUndefinedOrNull())
539         RETURN(jsNumber(0));
540
541     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorValue.asCell());
542
543     RETURN(jsNumber(enumerator->indexedLength()));
544 }
545
546 SLOW_PATH_DECL(slow_path_has_indexed_property)
547 {
548     BEGIN();
549     JSObject* base = OP(2).jsValue().toObject(exec);
550     JSValue property = OP(3).jsValue();
551     pc[4].u.arrayProfile->observeStructure(base->structure(vm));
552     ASSERT(property.isUInt32());
553     RETURN(jsBoolean(base->hasProperty(exec, property.asUInt32())));
554 }
555
556 SLOW_PATH_DECL(slow_path_has_structure_property)
557 {
558     BEGIN();
559     JSObject* base = OP(2).jsValue().toObject(exec);
560     JSValue property = OP(3).jsValue();
561     ASSERT(property.isString());
562     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell());
563     if (base->structure(vm)->id() == enumerator->cachedStructureID())
564         RETURN(jsBoolean(true));
565     RETURN(jsBoolean(base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec))));
566 }
567
568 SLOW_PATH_DECL(slow_path_has_generic_property)
569 {
570     BEGIN();
571     JSObject* base = OP(2).jsValue().toObject(exec);
572     JSValue property = OP(3).jsValue();
573     bool result;
574     if (property.isString())
575         result = base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec));
576     else {
577         ASSERT(property.isUInt32());
578         result = base->hasProperty(exec, property.asUInt32());
579     }
580     RETURN(jsBoolean(result));
581 }
582
583 SLOW_PATH_DECL(slow_path_get_direct_pname)
584 {
585     BEGIN();
586     JSValue baseValue = OP_C(2).jsValue();
587     JSValue property = OP(3).jsValue();
588     ASSERT(property.isString());
589     RETURN(baseValue.get(exec, asString(property)->toIdentifier(exec)));
590 }
591
592 SLOW_PATH_DECL(slow_path_get_property_enumerator)
593 {
594     BEGIN();
595     JSValue baseValue = OP(2).jsValue();
596     if (baseValue.isUndefinedOrNull())
597         RETURN(JSPropertyNameEnumerator::create(vm));
598
599     JSObject* base = baseValue.toObject(exec);
600
601     RETURN(propertyNameEnumerator(exec, base));
602 }
603
604 SLOW_PATH_DECL(slow_path_next_structure_enumerator_pname)
605 {
606     BEGIN();
607     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
608     uint32_t index = OP(3).jsValue().asUInt32();
609
610     JSString* propertyName = nullptr;
611     if (index < enumerator->endStructurePropertyIndex())
612         propertyName = enumerator->propertyNameAtIndex(index);
613     RETURN(propertyName ? propertyName : jsNull());
614 }
615
616 SLOW_PATH_DECL(slow_path_next_generic_enumerator_pname)
617 {
618     BEGIN();
619     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
620     uint32_t index = OP(3).jsValue().asUInt32();
621
622     JSString* propertyName = nullptr;
623     if (enumerator->endStructurePropertyIndex() <= index && index < enumerator->endGenericPropertyIndex())
624         propertyName = enumerator->propertyNameAtIndex(index);
625     RETURN(propertyName ? propertyName : jsNull());
626 }
627
628 SLOW_PATH_DECL(slow_path_to_index_string)
629 {
630     BEGIN();
631     RETURN(jsString(exec, Identifier::from(exec, OP(2).jsValue().asUInt32()).string()));
632 }
633
634 SLOW_PATH_DECL(slow_path_profile_type_clear_log)
635 {
636     BEGIN();
637     vm.typeProfilerLog()->processLogEntries(ASCIILiteral("LLInt log full."));
638     END();
639 }
640
641 SLOW_PATH_DECL(slow_path_create_lexical_environment)
642 {
643     BEGIN();
644     int scopeReg = pc[2].u.operand;
645     JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
646     SymbolTable* symbolTable = jsCast<SymbolTable*>(OP_C(3).jsValue());
647     JSValue initialValue = OP_C(4).jsValue();
648     ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
649     JSScope* newScope = JSLexicalEnvironment::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, initialValue);
650     RETURN(newScope);
651 }
652
653 } // namespace JSC