diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/CommonSlowPaths.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/CommonSlowPaths.cpp | 468 |
1 files changed, 94 insertions, 374 deletions
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp index 78b43c4d3..f6a142e6d 100644 --- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp +++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2016 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,34 +25,32 @@ #include "config.h" #include "CommonSlowPaths.h" + +#if ENABLE(JIT) || ENABLE(LLINT) + +#include "Arguments.h" #include "ArrayConstructor.h" #include "CallFrame.h" -#include "ClonedArguments.h" #include "CodeProfiling.h" #include "CommonSlowPathsExceptions.h" -#include "DirectArguments.h" -#include "Error.h" -#include "ErrorHandlingScope.h" -#include "ExceptionFuzz.h" -#include "GeneratorFrame.h" #include "GetterSetter.h" #include "HostCallReturnValue.h" #include "Interpreter.h" #include "JIT.h" -#include "JSCInlines.h" +#include "JITStubs.h" +#include "JSActivation.h" #include "JSCJSValue.h" #include "JSGlobalObjectFunctions.h" -#include "JSLexicalEnvironment.h" -#include "JSPropertyNameEnumerator.h" +#include "JSNameScope.h" +#include "JSPropertyNameIterator.h" #include "JSString.h" #include "JSWithScope.h" #include "LLIntCommon.h" #include "LLIntExceptions.h" #include "LowLevelInterpreter.h" #include "ObjectConstructor.h" -#include "ScopedArguments.h" +#include "Operations.h" #include "StructureRareDataInlines.h" -#include "TypeProfilerLog.h" #include <wtf/StringPrintStream.h> namespace JSC { @@ -72,7 +70,11 @@ namespace JSC { } while (false) #endif +#if ENABLE(LLINT) #define RETURN_TO_THROW(exec, pc) pc = LLInt::returnToThrow(exec) +#else +#define RETURN_TO_THROW(exec, pc) +#endif #define BEGIN() \ BEGIN_NO_SET_PC(); \ @@ -94,7 +96,6 @@ namespace JSC { } while (false) #define CHECK_EXCEPTION() do { \ - doExceptionFuzzingIfEnabled(exec, "CommonSlowPaths", pc); \ if (UNLIKELY(vm.exception())) { \ RETURN_TO_THROW(exec, pc); \ END_IMPL(); \ @@ -116,19 +117,20 @@ namespace JSC { END_IMPL(); \ } while (false) -#define RETURN_WITH_PROFILING(value__, profilingAction__) do { \ - JSValue returnValue__ = (value__); \ - CHECK_EXCEPTION(); \ - OP(1) = returnValue__; \ - profilingAction__; \ - END_IMPL(); \ +#define RETURN(value) do { \ + JSValue rReturnValue = (value); \ + CHECK_EXCEPTION(); \ + OP(1) = rReturnValue; \ + END_IMPL(); \ } while (false) -#define RETURN(value) \ - RETURN_WITH_PROFILING(value, { }) - -#define RETURN_PROFILED(opcode__, value__) \ - RETURN_WITH_PROFILING(value__, PROFILE_VALUE(opcode__, returnValue__)) +#define RETURN_PROFILED(opcode, value) do { \ + JSValue rpPeturnValue = (value); \ + CHECK_EXCEPTION(); \ + OP(1) = rpPeturnValue; \ + PROFILE_VALUE(opcode, rpPeturnValue); \ + END_IMPL(); \ + } while (false) #define PROFILE_VALUE(opcode, value) do { \ pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \ @@ -159,78 +161,67 @@ namespace JSC { CALL_END_IMPL(crExec, crCallTarget); \ } while (false) -static CommonSlowPaths::ArityCheckData* setupArityCheckData(VM& vm, int slotsToAdd) -{ - CommonSlowPaths::ArityCheckData* result = vm.arityCheckData.get(); - result->paddedStackSpace = slotsToAdd; -#if ENABLE(JIT) - if (vm.canUseJIT()) - result->thunkToCall = vm.getCTIStub(arityFixupGenerator).code().executableAddress(); - else -#endif - result->thunkToCall = 0; - return result; -} - SLOW_PATH_DECL(slow_path_call_arityCheck) { BEGIN(); - int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall); - if (slotsToAdd < 0) { + int SlotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall); + if (SlotsToAdd < 0) { exec = exec->callerFrame(); - ErrorHandlingScope errorScope(exec->vm()); CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec)); RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); } - RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd)); + RETURN_TWO(0, reinterpret_cast<ExecState*>(SlotsToAdd)); } SLOW_PATH_DECL(slow_path_construct_arityCheck) { BEGIN(); - int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct); - if (slotsToAdd < 0) { + int SlotsToAdd = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct); + if (SlotsToAdd < 0) { exec = exec->callerFrame(); - ErrorHandlingScope errorScope(exec->vm()); CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec)); RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); } - RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd)); + RETURN_TWO(0, reinterpret_cast<ExecState*>(SlotsToAdd)); } -SLOW_PATH_DECL(slow_path_create_direct_arguments) +SLOW_PATH_DECL(slow_path_touch_entry) { BEGIN(); - RETURN(DirectArguments::createByCopying(exec)); + exec->codeBlock()->symbolTable()->m_functionEnteredOnce.touch(); + END(); } -SLOW_PATH_DECL(slow_path_create_scoped_arguments) +SLOW_PATH_DECL(slow_path_get_callee) { BEGIN(); - JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue()); - ScopedArgumentsTable* table = scope->symbolTable()->arguments(); - RETURN(ScopedArguments::createByCopying(exec, table, scope)); + JSFunction* callee = jsCast<JSFunction*>(exec->callee()); + pc[2].u.jsCell.set(exec->vm(), exec->codeBlock()->ownerExecutable(), callee); + RETURN(callee); } -SLOW_PATH_DECL(slow_path_create_out_of_band_arguments) +SLOW_PATH_DECL(slow_path_create_arguments) { BEGIN(); - RETURN(ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned)); + JSValue arguments = JSValue(Arguments::create(vm, exec)); + CHECK_EXCEPTION(); + exec->uncheckedR(pc[1].u.operand) = arguments; + exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()) = arguments; + END(); } SLOW_PATH_DECL(slow_path_create_this) { BEGIN(); JSFunction* constructor = jsCast<JSFunction*>(OP(2).jsValue().asCell()); - - auto& cacheWriteBarrier = pc[4].u.jsCell; - if (!cacheWriteBarrier) - cacheWriteBarrier.set(exec->vm(), exec->codeBlock(), constructor); - else if (cacheWriteBarrier.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cacheWriteBarrier.get() != constructor) - cacheWriteBarrier.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects()); + +#if !ASSERT_DISABLED + ConstructData constructData; + ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS); +#endif size_t inlineCapacity = pc[3].u.operand; - Structure* structure = constructor->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure(); + Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure(); RETURN(constructEmptyObject(exec, structure)); } @@ -238,31 +229,34 @@ SLOW_PATH_DECL(slow_path_to_this) { BEGIN(); JSValue v1 = OP(1).jsValue(); - if (v1.isCell()) { - Structure* myStructure = v1.asCell()->structure(vm); - Structure* otherStructure = pc[2].u.structure.get(); - if (myStructure != otherStructure) { - if (otherStructure) - pc[3].u.toThisStatus = ToThisConflicted; - pc[2].u.structure.set(vm, exec->codeBlock(), myStructure); - } - } else { - pc[3].u.toThisStatus = ToThisConflicted; + if (v1.isCell()) + pc[2].u.structure.set(exec->vm(), exec->codeBlock()->ownerExecutable(), v1.asCell()->structure()); + else pc[2].u.structure.clear(); - } RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode)); } -SLOW_PATH_DECL(slow_path_throw_tdz_error) +SLOW_PATH_DECL(slow_path_captured_mov) { BEGIN(); - THROW(createTDZError(exec)); + JSValue value = OP_C(2).jsValue(); + if (VariableWatchpointSet* set = pc[3].u.watchpointSet) + set->notifyWrite(value); + RETURN(value); } -SLOW_PATH_DECL(slow_path_throw_strict_mode_readonly_property_write_error) +SLOW_PATH_DECL(slow_path_new_captured_func) { BEGIN(); - THROW(createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError))); + CodeBlock* codeBlock = exec->codeBlock(); + ASSERT( + codeBlock->codeType() != FunctionCode + || !codeBlock->needsFullScopeChain() + || exec->uncheckedR(codeBlock->activationRegister().offset()).jsValue()); + JSValue value = JSFunction::create(vm, codeBlock->functionDecl(pc[2].u.operand), exec->scope()); + if (VariableWatchpointSet* set = pc[3].u.watchpointSet) + set->notifyWrite(value); + RETURN(value); } SLOW_PATH_DECL(slow_path_not) @@ -337,69 +331,25 @@ SLOW_PATH_DECL(slow_path_to_number) RETURN(jsNumber(OP_C(2).jsValue().toNumber(exec))); } -SLOW_PATH_DECL(slow_path_to_string) -{ - BEGIN(); - RETURN(OP_C(2).jsValue().toString(exec)); -} - SLOW_PATH_DECL(slow_path_negate) { BEGIN(); RETURN(jsNumber(-OP_C(2).jsValue().toNumber(exec))); } -#if ENABLE(DFG_JIT) -static void updateResultProfileForBinaryArithOp(ExecState* exec, Instruction* pc, JSValue result, JSValue left, JSValue right) -{ - CodeBlock* codeBlock = exec->codeBlock(); - unsigned bytecodeOffset = codeBlock->bytecodeOffset(pc); - ResultProfile* profile = codeBlock->ensureResultProfile(bytecodeOffset); - - if (result.isNumber()) { - if (!result.isInt32()) { - if (left.isInt32() && right.isInt32()) - profile->setObservedInt32Overflow(); - - double doubleVal = result.asNumber(); - if (!doubleVal && std::signbit(doubleVal)) - profile->setObservedNegZeroDouble(); - else { - profile->setObservedNonNegZeroDouble(); - - // The Int52 overflow check here intentionally omits 1ll << 51 as a valid negative Int52 value. - // Therefore, we will get a false positive if the result is that value. This is intentionally - // done to simplify the checking algorithm. - static const int64_t int52OverflowPoint = (1ll << 51); - int64_t int64Val = static_cast<int64_t>(std::abs(doubleVal)); - if (int64Val >= int52OverflowPoint) - profile->setObservedInt52Overflow(); - } - } - } else - profile->setObservedNonNumber(); -} -#else -static void updateResultProfileForBinaryArithOp(ExecState*, Instruction*, JSValue, JSValue, JSValue) { } -#endif - SLOW_PATH_DECL(slow_path_add) { BEGIN(); JSValue v1 = OP_C(2).jsValue(); JSValue v2 = OP_C(3).jsValue(); - JSValue result; - + if (v1.isString() && !v2.isObject()) - result = jsString(exec, asString(v1), v2.toString(exec)); - else if (v1.isNumber() && v2.isNumber()) - result = jsNumber(v1.asNumber() + v2.asNumber()); - else - result = jsAddSlowCase(exec, v1, v2); - - RETURN_WITH_PROFILING(result, { - updateResultProfileForBinaryArithOp(exec, pc, result, v1, v2); - }); + RETURN(jsString(exec, asString(v1), v2.toString(exec))); + + if (v1.isNumber() && v2.isNumber()) + RETURN(jsNumber(v1.asNumber() + v2.asNumber())); + + RETURN(jsAddSlowCase(exec, v1, v2)); } // The following arithmetic and bitwise operations need to be sure to run @@ -409,40 +359,25 @@ SLOW_PATH_DECL(slow_path_add) SLOW_PATH_DECL(slow_path_mul) { BEGIN(); - JSValue left = OP_C(2).jsValue(); - JSValue right = OP_C(3).jsValue(); - double a = left.toNumber(exec); - double b = right.toNumber(exec); - JSValue result = jsNumber(a * b); - RETURN_WITH_PROFILING(result, { - updateResultProfileForBinaryArithOp(exec, pc, result, left, right); - }); + double a = OP_C(2).jsValue().toNumber(exec); + double b = OP_C(3).jsValue().toNumber(exec); + RETURN(jsNumber(a * b)); } SLOW_PATH_DECL(slow_path_sub) { BEGIN(); - JSValue left = OP_C(2).jsValue(); - JSValue right = OP_C(3).jsValue(); - double a = left.toNumber(exec); - double b = right.toNumber(exec); - JSValue result = jsNumber(a - b); - RETURN_WITH_PROFILING(result, { - updateResultProfileForBinaryArithOp(exec, pc, result, left, right); - }); + double a = OP_C(2).jsValue().toNumber(exec); + double b = OP_C(3).jsValue().toNumber(exec); + RETURN(jsNumber(a - b)); } SLOW_PATH_DECL(slow_path_div) { BEGIN(); - JSValue left = OP_C(2).jsValue(); - JSValue right = OP_C(3).jsValue(); - double a = left.toNumber(exec); - double b = right.toNumber(exec); - JSValue result = jsNumber(a / b); - RETURN_WITH_PROFILING(result, { - updateResultProfileForBinaryArithOp(exec, pc, result, left, right); - }); + double a = OP_C(2).jsValue().toNumber(exec); + double b = OP_C(3).jsValue().toNumber(exec); + RETURN(jsNumber(a / b)); } SLOW_PATH_DECL(slow_path_mod) @@ -514,10 +449,10 @@ SLOW_PATH_DECL(slow_path_typeof) RETURN(jsTypeStringForValue(exec, OP_C(2).jsValue())); } -SLOW_PATH_DECL(slow_path_is_object_or_null) +SLOW_PATH_DECL(slow_path_is_object) { BEGIN(); - RETURN(jsBoolean(jsIsObjectTypeOrNull(exec, OP_C(2).jsValue()))); + RETURN(jsBoolean(jsIsObjectType(exec, OP_C(2).jsValue()))); } SLOW_PATH_DECL(slow_path_is_function) @@ -545,9 +480,11 @@ SLOW_PATH_DECL(slow_path_del_by_val) uint32_t i; if (subscript.getUInt32(i)) couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i); + else if (isName(subscript)) + couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName()); else { CHECK_EXCEPTION(); - auto property = subscript.toPropertyKey(exec); + Identifier property(exec, subscript.toString(exec)->value(exec)); CHECK_EXCEPTION(); couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property); } @@ -573,228 +510,11 @@ SLOW_PATH_DECL(slow_path_to_primitive) SLOW_PATH_DECL(slow_path_enter) { BEGIN(); - CodeBlock* codeBlock = exec->codeBlock(); - Heap::heap(codeBlock)->writeBarrier(codeBlock); - END(); -} - -SLOW_PATH_DECL(slow_path_get_enumerable_length) -{ - BEGIN(); - JSValue enumeratorValue = OP(2).jsValue(); - if (enumeratorValue.isUndefinedOrNull()) - RETURN(jsNumber(0)); - - JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorValue.asCell()); - - RETURN(jsNumber(enumerator->indexedLength())); -} - -SLOW_PATH_DECL(slow_path_has_indexed_property) -{ - BEGIN(); - JSObject* base = OP(2).jsValue().toObject(exec); - JSValue property = OP(3).jsValue(); - pc[4].u.arrayProfile->observeStructure(base->structure(vm)); - ASSERT(property.isUInt32()); - RETURN(jsBoolean(base->hasProperty(exec, property.asUInt32()))); -} - -SLOW_PATH_DECL(slow_path_has_structure_property) -{ - BEGIN(); - JSObject* base = OP(2).jsValue().toObject(exec); - JSValue property = OP(3).jsValue(); - ASSERT(property.isString()); - JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell()); - if (base->structure(vm)->id() == enumerator->cachedStructureID()) - RETURN(jsBoolean(true)); - RETURN(jsBoolean(base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec)))); -} - -SLOW_PATH_DECL(slow_path_has_generic_property) -{ - BEGIN(); - JSObject* base = OP(2).jsValue().toObject(exec); - JSValue property = OP(3).jsValue(); - bool result; - if (property.isString()) - result = base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec)); - else { - ASSERT(property.isUInt32()); - result = base->hasProperty(exec, property.asUInt32()); - } - RETURN(jsBoolean(result)); -} - -SLOW_PATH_DECL(slow_path_get_direct_pname) -{ - BEGIN(); - JSValue baseValue = OP_C(2).jsValue(); - JSValue property = OP(3).jsValue(); - ASSERT(property.isString()); - RETURN(baseValue.get(exec, asString(property)->toIdentifier(exec))); -} - -SLOW_PATH_DECL(slow_path_get_property_enumerator) -{ - BEGIN(); - JSValue baseValue = OP(2).jsValue(); - if (baseValue.isUndefinedOrNull()) - RETURN(JSPropertyNameEnumerator::create(vm)); - - JSObject* base = baseValue.toObject(exec); - - RETURN(propertyNameEnumerator(exec, base)); -} - -SLOW_PATH_DECL(slow_path_next_structure_enumerator_pname) -{ - BEGIN(); - JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell()); - uint32_t index = OP(3).jsValue().asUInt32(); - - JSString* propertyName = nullptr; - if (index < enumerator->endStructurePropertyIndex()) - propertyName = enumerator->propertyNameAtIndex(index); - RETURN(propertyName ? propertyName : jsNull()); -} - -SLOW_PATH_DECL(slow_path_next_generic_enumerator_pname) -{ - BEGIN(); - JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell()); - uint32_t index = OP(3).jsValue().asUInt32(); - - JSString* propertyName = nullptr; - if (enumerator->endStructurePropertyIndex() <= index && index < enumerator->endGenericPropertyIndex()) - propertyName = enumerator->propertyNameAtIndex(index); - RETURN(propertyName ? propertyName : jsNull()); -} - -SLOW_PATH_DECL(slow_path_to_index_string) -{ - BEGIN(); - RETURN(jsString(exec, Identifier::from(exec, OP(2).jsValue().asUInt32()).string())); -} - -SLOW_PATH_DECL(slow_path_profile_type_clear_log) -{ - BEGIN(); - vm.typeProfilerLog()->processLogEntries(ASCIILiteral("LLInt log full.")); - END(); -} - -SLOW_PATH_DECL(slow_path_assert) -{ - BEGIN(); - ASSERT_WITH_MESSAGE(OP(1).jsValue().asBoolean(), "JS assertion failed at line %d in:\n%s\n", pc[2].u.operand, exec->codeBlock()->sourceCodeForTools().data()); - END(); -} - -SLOW_PATH_DECL(slow_path_save) -{ - // Only save variables and temporary registers. The scope registers are included in them. - // But parameters are not included. Because the generator implementation replaces the values of parameters on each generator.next() call. - BEGIN(); - JSValue generator = OP(1).jsValue(); - GeneratorFrame* frame = nullptr; - JSValue value = generator.get(exec, exec->propertyNames().generatorFramePrivateName); - if (!value.isNull()) - frame = jsCast<GeneratorFrame*>(value); - else { - // FIXME: Once JSGenerator specialized object is introduced, this GeneratorFrame should be embeded into it to avoid allocations. - // https://bugs.webkit.org/show_bug.cgi?id=151545 - frame = GeneratorFrame::create(exec->vm(), exec->codeBlock()->numCalleeLocals()); - PutPropertySlot slot(generator, true, PutPropertySlot::PutById); - asObject(generator)->methodTable(exec->vm())->put(asObject(generator), exec, exec->propertyNames().generatorFramePrivateName, frame, slot); - } - unsigned liveCalleeLocalsIndex = pc[2].u.unsignedValue; - frame->save(exec, exec->codeBlock()->liveCalleeLocalsAtYield(liveCalleeLocalsIndex)); - END(); -} - -SLOW_PATH_DECL(slow_path_resume) -{ - BEGIN(); - JSValue generator = OP(1).jsValue(); - GeneratorFrame* frame = jsCast<GeneratorFrame*>(generator.get(exec, exec->propertyNames().generatorFramePrivateName)); - unsigned liveCalleeLocalsIndex = pc[2].u.unsignedValue; - frame->resume(exec, exec->codeBlock()->liveCalleeLocalsAtYield(liveCalleeLocalsIndex)); - END(); -} - -SLOW_PATH_DECL(slow_path_create_lexical_environment) -{ - BEGIN(); - int scopeReg = pc[2].u.operand; - JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope(); - SymbolTable* symbolTable = jsCast<SymbolTable*>(OP_C(3).jsValue()); - JSValue initialValue = OP_C(4).jsValue(); - ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue()); - JSScope* newScope = JSLexicalEnvironment::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, initialValue); - RETURN(newScope); -} - -SLOW_PATH_DECL(slow_path_push_with_scope) -{ - BEGIN(); - JSObject* newScope = OP_C(2).jsValue().toObject(exec); - CHECK_EXCEPTION(); - - int scopeReg = pc[3].u.operand; - JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope(); - RETURN(JSWithScope::create(exec, newScope, currentScope)); -} - -SLOW_PATH_DECL(slow_path_resolve_scope) -{ - BEGIN(); - const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand); - JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope(); - JSValue resolvedScope = JSScope::resolve(exec, scope, ident); - - ResolveType resolveType = static_cast<ResolveType>(pc[4].u.operand); - - // ModuleVar does not keep the scope register value alive in DFG. - ASSERT(resolveType != ModuleVar); - - if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) { - if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(resolvedScope)) { - if (resolveType == UnresolvedProperty) - pc[4].u.operand = GlobalLexicalVar; - else - pc[4].u.operand = GlobalLexicalVarWithVarInjectionChecks; - pc[6].u.pointer = globalLexicalEnvironment; - } else if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(resolvedScope)) { - if (globalObject->hasProperty(exec, ident)) { - if (resolveType == UnresolvedProperty) - pc[4].u.operand = GlobalProperty; - else - pc[4].u.operand = GlobalPropertyWithVarInjectionChecks; - - pc[6].u.pointer = globalObject; - } - } - } - - RETURN(resolvedScope); -} - -SLOW_PATH_DECL(slow_path_copy_rest) -{ - BEGIN(); - unsigned arraySize = OP_C(2).jsValue().asUInt32(); - if (!arraySize) { - ASSERT(!jsCast<JSArray*>(OP(1).jsValue())->length()); - END(); - } - JSArray* array = jsCast<JSArray*>(OP(1).jsValue()); - ASSERT(arraySize == array->length()); - unsigned numParamsToSkip = pc[3].u.unsignedValue; - for (unsigned i = 0; i < arraySize; i++) - array->putDirectIndex(exec, i, exec->uncheckedArgument(i + numParamsToSkip)); + ScriptExecutable* ownerExecutable = exec->codeBlock()->ownerExecutable(); + Heap::heap(ownerExecutable)->writeBarrier(ownerExecutable); END(); } } // namespace JSC + +#endif // ENABLE(JIT) || ENABLE(LLINT) |