bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error) { ASSERT(m_callback); ASSERT(m_frame); if (!m_frame->script()->isEnabled()) return true; JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); KJS::JSLock lock; JSValue* handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData handleEventCallData; CallType handleEventCallType = handleEventFunction->getCallData(handleEventCallData); CallData callbackCallData; CallType callbackCallType = CallTypeNone; if (handleEventCallType == CallTypeNone) { callbackCallType = m_callback->getCallData(callbackCallData); if (callbackCallType == CallTypeNone) { // FIXME: Should an exception be thrown here? return true; } } RefPtr<JSCustomSQLStatementErrorCallback> protect(this); ArgList args; args.append(toJS(exec, transaction)); args.append(toJS(exec, error)); JSValue* result; globalObject->startTimeoutCheck(); if (handleEventCallType != CallTypeNone) result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args); else result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args); globalObject->stopTimeoutCheck(); if (exec->hadException()) { JSObject* exception = exec->exception()->toObject(exec); String message = exception->get(exec, exec->propertyNames().message)->toString(exec); int lineNumber = exception->get(exec, Identifier(exec, "line"))->toInt32(exec); String sourceURL = exception->get(exec, Identifier(exec, "sourceURL"))->toString(exec); m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); exec->clearException(); // The spec says: // "If the error callback returns false, then move on to the next statement..." // "Otherwise, the error callback did not return false, or there was no error callback" // Therefore an exception and returning true are the same thing - so, return true on an exception return true; } Document::updateDocumentsRendering(); return result->toBoolean(exec); }
PassRefPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception) { RefPtr<FunctionCodeBlock> alternative = codeBlockFor(specializationKind); if (!!alternative) { RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind))); result->setAlternative(alternative); return result.release(); } VM* vm = scope->vm(); JSGlobalObject* globalObject = scope->globalObject(); ParserError error; DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff; ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff; UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, m_source, specializationKind, debuggerMode, profilerMode, error); recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn()); if (!unlinkedCodeBlock) { exception = error.toErrorObject(globalObject, m_source); return 0; } SourceProvider* provider = source().provider(); unsigned sourceOffset = source().startOffset(); unsigned startColumn = source().startColumn(); return adoptRef(new FunctionCodeBlock(this, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn)); }
JSBool JSJSGlobalObject::fromjs_isTimerValid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { // get instance JSGlobalObject *object = static_cast<JSGlobalObject *>(reinterpret_cast<JSScriptable *>(JS_GetPrivate(cx, obj))); if (!object) { JSScriptable::js_throwNullCallException(JSJSGlobalObject::classDescriptor.name, JSJSGlobalObject::functionTable[4].name); return JS_FALSE; } // record context object->js_setCurrentContext(cx); // JSTimer *timer JSObject *p0; if (!JS_ValueToObject(cx, argv[0], &p0)) return JS_FALSE; argv[0] = OBJECT_TO_JSVAL(p0); JSTimer *p0o = NULL; if (p0) { JSScriptable *pobj = reinterpret_cast<JSScriptable*>(JS_GetPrivate(cx, p0)); if (!pobj) { object->js_throwNullParamException(0, JSJSGlobalObject::functionTable[4].name, JSJSGlobalObject::classDescriptor.name); return JS_FALSE; } p0o = static_cast<JSTimer *>(pobj->js_getInterface(JS_JSTimer_GUID)); if (!p0o) { object->js_throwParamTypeException(0, JSJSTimer::classDescriptor.name, JSJSGlobalObject::functionTable[4].name, JSJSGlobalObject::classDescriptor.name); return JS_FALSE; } } // call method ASSERT(object != NULL); bool rv = object->isTimerValid(p0o); // handle return value *rval = BOOLEAN_TO_JSVAL(rv); // success return JS_TRUE; }
bool FunctionExecutable::compileForConstruct(ExecState*, ScopeChainNode* scopeChainNode) { JSGlobalData* globalData = scopeChainNode->globalData; RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source); if (!body) return false; if (m_forceUsesArguments) body->setUsesArguments(); body->finishParsing(m_parameters, m_name); recordParse(body->features(), body->lineNo(), body->lastLine()); ScopeChain scopeChain(scopeChainNode); JSGlobalObject* globalObject = scopeChain.globalObject(); ASSERT(!m_codeBlockForConstruct); m_codeBlockForConstruct = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), true); OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct)); generator->generate(); m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters; ASSERT(m_numParametersForConstruct); m_numVariables = m_codeBlockForConstruct->m_numVars; m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable(); body->destroyData(); return true; }
std::error_code parseRuleList(const String& rules, Vector<ContentExtensionRule>& ruleList) { #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double loadExtensionStartTime = monotonicallyIncreasingTime(); #endif RefPtr<VM> vm = VM::create(); JSLockHolder locker(vm.get()); JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull())); ExecState* exec = globalObject->globalExec(); auto error = loadEncodedRules(*exec, rules, ruleList); vm = nullptr; if (error) return error; if (ruleList.isEmpty()) return ContentExtensionError::JSONContainsNoRules; #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double loadExtensionEndTime = monotonicallyIncreasingTime(); dataLogF("Time spent loading extension %f\n", (loadExtensionEndTime - loadExtensionStartTime)); #endif return { }; }
String Database::toJSON() const { JSGlobalObject* globalObject = JSGlobalObject::create( m_vm, JSGlobalObject::createStructure(m_vm, jsNull())); return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0); }
JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope) { RELEASE_ASSERT(scope); JSGlobalObject* globalObject = scope->globalObject(); RELEASE_ASSERT(globalObject); ASSERT(&globalObject->vm() == &vm); JSObject* exception = 0; UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception); if (exception) return exception; m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock); BatchedTransitionOptimizer optimizer(vm, globalObject); for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); if (vm.typeProfiler() || vm.controlFlowProfiler()) { vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), unlinkedFunctionExecutable->typeProfilingStartOffset(), unlinkedFunctionExecutable->typeProfilingEndOffset()); } } const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); for (auto& entry : variableDeclarations) { ASSERT(entry.value.isVar()); globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get())); } return 0; }
EncodedJSValue jsTestNondeterministicNondeterministicSetterExceptionAttr(ExecState* state, EncodedJSValue thisValue, PropertyName) { UNUSED_PARAM(state); UNUSED_PARAM(thisValue); JSValue decodedThisValue = JSValue::decode(thisValue); auto* castedThis = jsDynamicCast<JSTestNondeterministic*>(decodedThisValue); if (UNLIKELY(!castedThis)) { return throwGetterTypeError(*state, "TestNondeterministic", "nondeterministicSetterExceptionAttr"); } #if ENABLE(WEB_REPLAY) JSGlobalObject* globalObject = state->lexicalGlobalObject(); InputCursor& cursor = globalObject->inputCursor(); static NeverDestroyed<const AtomicString> bindingName("TestNondeterministic.nondeterministicSetterExceptionAttr", AtomicString::ConstructFromLiteral); if (cursor.isCapturing()) { String memoizedResult = castedThis->wrapped().nondeterministicSetterExceptionAttr(); cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0); JSValue result = jsStringWithCache(state, memoizedResult); return JSValue::encode(result); } if (cursor.isReplaying()) { String memoizedResult; MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>(); if (input && input->convertTo<String>(memoizedResult)) { JSValue result = jsStringWithCache(state, memoizedResult); return JSValue::encode(result); } } #endif auto& impl = castedThis->wrapped(); JSValue result = jsStringWithCache(state, impl.nondeterministicSetterExceptionAttr()); return JSValue::encode(result); }
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode) { ASSERT(!m_programCodeBlock); JSObject* exception = 0; JSGlobalData* globalData = &exec->globalData(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); if (!programNode) { ASSERT(exception); return exception; } recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); ScopeChain scopeChain(scopeChainNode); JSGlobalObject* globalObject = scopeChain.globalObject(); m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider())); OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get()))); generator->generate(); programNode->destroyData(); #if ENABLE(JIT) if (exec->globalData().canUseJIT()) { m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get()); #if !ENABLE(OPCODE_SAMPLING) if (!BytecodeGenerator::dumpsGeneratedCode()) m_programCodeBlock->discardBytecode(); #endif } #endif return 0; }
JSValueRef JSEvaluateScriptInternal(const JSLockHolder&, ExecState* exec, JSContextRef ctx, JSObjectRef thisObject, const SourceCode& source, JSValueRef* exception) { UNUSED_PARAM(ctx); JSObject* jsThisObject = toJS(thisObject); // evaluate sets "this" to the global object if it is NULL VM& vm = exec->vm(); JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec); NakedPtr<Exception> evaluationException; JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException); if (evaluationException) { if (exception) *exception = toRef(exec, evaluationException->value()); #if ENABLE(REMOTE_INSPECTOR) // FIXME: If we have a debugger attached we could learn about ParseError exceptions through // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The // Debugger path is currently ignored by inspector. // NOTE: If we don't have a debugger, this SourceCode will be forever lost to the inspector. // We could stash it in the inspector in case an inspector is ever opened. globalObject->inspectorController().reportAPIException(exec, evaluationException); #endif return nullptr; } if (returnValue) return toRef(exec, returnValue); // happens, for example, when the only statement is an empty (';') statement return toRef(exec, jsUndefined()); }
ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) { RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source); if (m_forceUsesArguments) newFunctionBody->setUsesArguments(); newFunctionBody->finishParsing(m_parameters, m_name); ScopeChain scopeChain(scopeChainNode); JSGlobalObject* globalObject = scopeChain.globalObject(); OwnPtr<CodeBlock> newCodeBlock(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset())); globalData->functionCodeBlockBeingReparsed = newCodeBlock.get(); OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get())); generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock)); generator->generate(); ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount()); #if ENABLE(JIT) JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get()); ASSERT(newJITCode.size() == generatedJITCode().size()); #endif globalData->functionCodeBlockBeingReparsed = 0; return newCodeBlock->extractExceptionInfo(); }
EncodedJSValue jsTestNondeterministicNondeterministicWriteableAttr(ExecState* exec, JSObject* slotBase, EncodedJSValue thisValue, PropertyName) { UNUSED_PARAM(exec); UNUSED_PARAM(slotBase); UNUSED_PARAM(thisValue); JSTestNondeterministic* castedThis = jsDynamicCast<JSTestNondeterministic*>(JSValue::decode(thisValue)); if (UNLIKELY(!castedThis)) { if (jsDynamicCast<JSTestNondeterministicPrototype*>(slotBase)) return reportDeprecatedGetterError(*exec, "TestNondeterministic", "nondeterministicWriteableAttr"); return throwGetterTypeError(*exec, "TestNondeterministic", "nondeterministicWriteableAttr"); } #if ENABLE(WEB_REPLAY) JSGlobalObject* globalObject = exec->lexicalGlobalObject(); InputCursor& cursor = globalObject->inputCursor(); static NeverDestroyed<const AtomicString> bindingName("TestNondeterministic.nondeterministicWriteableAttr", AtomicString::ConstructFromLiteral); if (cursor.isCapturing()) { String memoizedResult = castedThis->impl().nondeterministicWriteableAttr(); cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0); JSValue result = jsStringWithCache(exec, memoizedResult); return JSValue::encode(result); } if (cursor.isReplaying()) { String memoizedResult; MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>(); if (input && input->convertTo<String>(memoizedResult)) { JSValue result = jsStringWithCache(exec, memoizedResult); return JSValue::encode(result); } } #endif TestNondeterministic& impl = castedThis->impl(); JSValue result = jsStringWithCache(exec, impl.nondeterministicWriteableAttr()); return JSValue::encode(result); }
// ECMA 15.3.2 The Function Constructor JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) { // Functions need to have a space following the opening { due to for web compatibility // see https://bugs.webkit.org/show_bug.cgi?id=24350 // We also need \n before the closing } to handle // comments at the end of the last line UString program; if (args.isEmpty()) program = "(function() { \n})"; else if (args.size() == 1) program = makeString("(function() { ", args.at(0).toString(exec), "\n})"); else { StringBuilder builder; builder.append("(function("); builder.append(args.at(0).toString(exec)); for (size_t i = 1; i < args.size() - 1; i++) { builder.append(","); builder.append(args.at(i).toString(exec)); } builder.append(") { "); builder.append(args.at(args.size() - 1).toString(exec)); builder.append("\n})"); program = builder.build(); } int errLine; UString errMsg; SourceCode source = makeSource(program, sourceURL, lineNumber); RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); if (!function) return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); ScopeChain scopeChain(globalObject, globalObject->globalData(), globalObject, exec->globalThisValue()); return new (exec) JSFunction(exec, function, scopeChain.node()); }
// ECMA 15.3.2 The Function Constructor JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) { UString program; if (args.isEmpty()) program = "(function(){})"; else if (args.size() == 1) program = "(function(){" + args.at(exec, 0)->toString(exec) + "})"; else { program = "(function(" + args.at(exec, 0)->toString(exec); for (size_t i = 1; i < args.size() - 1; i++) program += "," + args.at(exec, i)->toString(exec); program += "){" + args.at(exec, args.size() - 1)->toString(exec) + "})"; } int errLine; UString errMsg; SourceCode source = makeSource(program, sourceURL, lineNumber); RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); FunctionBodyNode* body = functionBody(programNode.get()); if (!body) return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue()); return new (exec) JSFunction(exec, functionName, body, scopeChain.node()); }
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSObject* jsThisObject = toJS(thisObject); // evaluate sets "this" to the global object if it is NULL JSGlobalObject* globalObject = exec->dynamicGlobalObject(); SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber); Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject); if (completion.complType() == Throw) { if (exception) *exception = toRef(completion.value()); return 0; } if (completion.value()) return toRef(completion.value()); // happens, for example, when the only statement is an empty (';') statement return toRef(jsUndefined()); }
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType) { SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)"); #if !ENABLE(JIT) UNUSED_PARAM(jitType); #endif JSObject* exception = 0; JSGlobalData* globalData = &exec->globalData(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) { BytecodeDestructionBlocker blocker(m_evalCodeBlock.get()); OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock)); newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release())); m_evalCodeBlock = newCodeBlock.release(); } else { if (!lexicalGlobalObject->evalEnabled()) return throwError(exec, createEvalError(exec, "Eval is disabled")); RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); if (!evalNode) { ASSERT(exception); return exception; } recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release(); ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release())); OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); if ((exception = generator->generate())) { m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative()); evalNode->destroyData(); return exception; } evalNode->destroyData(); m_evalCodeBlock->copyPostParseDataFromAlternative(); } #if ENABLE(JIT) if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType)) return 0; #endif #if ENABLE(JIT) #if ENABLE(INTERPRETER) if (!m_jitCodeForCall) Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock)); else #endif Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size()); #else Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock)); #endif return 0; }
EncodedJSValue doCallToJavaScript(void* executableAddress, ProtoCallFrame* protoCallFrame) { CodeBlock* codeBlock = protoCallFrame->codeBlock(); JSScope* scope = protoCallFrame->scope(); JSObject* callee = protoCallFrame->callee(); int argCountIncludingThis = protoCallFrame->argumentCountIncludingThis(); int argCount = protoCallFrame->argumentCount(); JSValue thisValue = protoCallFrame->thisValue(); JSStack& stack = scope->vm()->interpreter->stack(); CallFrame* newCallFrame = stack.pushFrame(codeBlock, scope, argCountIncludingThis, callee); if (UNLIKELY(!newCallFrame)) { JSGlobalObject* globalObject = scope->globalObject(); ExecState* exec = globalObject->globalExec(); return JSValue::encode(throwStackOverflowError(exec)); } // Set the arguments for the callee: newCallFrame->setThisValue(thisValue); for (int i = 0; i < argCount; ++i) newCallFrame->setArgument(i, protoCallFrame->argument(i)); JSValue result = execute(newCallFrame, executableAddress); stack.popFrame(newCallFrame); return JSValue::encode(result); }
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsThisObject = toJS(thisObject); startingLineNumber = std::max(1, startingLineNumber); // evaluate sets "this" to the global object if it is NULL JSGlobalObject* globalObject = exec->vmEntryGlobalObject(); SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); JSValue evaluationException; JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException); if (evaluationException) { if (exception) *exception = toRef(exec, evaluationException); return 0; } if (returnValue) return toRef(exec, returnValue); // happens, for example, when the only statement is an empty (';') statement return toRef(exec, jsUndefined()); }
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeGetterCompare(ExecState* exec) { // 10.3.3 Intl.Collator.prototype.compare (ECMA-402 2.0) // 1. Let collator be this Collator object. IntlCollator* collator = jsDynamicCast<IntlCollator*>(exec->thisValue()); if (!collator) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Intl.Collator.prototype.compare called on value that's not an object initialized as a Collator"))); JSBoundFunction* boundCompare = collator->boundCompare(); // 2. If collator.[[boundCompare]] is undefined, if (!boundCompare) { VM& vm = exec->vm(); JSGlobalObject* globalObject = collator->globalObject(); // a. Let F be a new built-in function object as defined in 11.3.4. // b. The value of F’s length property is 2. JSFunction* targetObject = JSFunction::create(vm, globalObject, 2, ASCIILiteral("compare"), IntlCollatorFuncCompare, NoIntrinsic); JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(exec)); // c. Let bc be BoundFunctionCreate(F, «this value»). boundCompare = JSBoundFunction::create(vm, globalObject, targetObject, collator, boundArgs, 2, ASCIILiteral("compare")); // d. Set collator.[[boundCompare]] to bc. collator->setBoundCompare(vm, boundCompare); } // 3. Return collator.[[boundCompare]]. return JSValue::encode(boundCompare); }
void InspectorHeapAgent::getRemoteObject(ErrorString& errorString, int heapObjectId, const String* optionalObjectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result) { // Prevent the cell from getting collected as we look it up. VM& vm = m_environment.vm(); JSLockHolder lock(vm); DeferGC deferGC(vm.heap); unsigned heapObjectIdentifier = static_cast<unsigned>(heapObjectId); const Optional<HeapSnapshotNode> optionalNode = nodeForHeapObjectIdentifier(errorString, heapObjectIdentifier); if (!optionalNode) return; JSCell* cell = optionalNode->cell; Structure* structure = cell->structure(m_environment.vm()); if (!structure) { errorString = ASCIILiteral("Unable to get object details"); return; } JSGlobalObject* globalObject = structure->globalObject(); if (!globalObject) { errorString = ASCIILiteral("Unable to get object details"); return; } InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject->globalExec()); if (injectedScript.hasNoValue()) { errorString = ASCIILiteral("Unable to get object details - InjectedScript"); return; } String objectGroup = optionalObjectGroup ? *optionalObjectGroup : String(); result = injectedScript.wrapObject(cell, objectGroup, true); }
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeGetterFormat(ExecState* state) { // 11.3.3 Intl.NumberFormat.prototype.format (ECMA-402 2.0) // 1. Let nf be this NumberFormat object. IntlNumberFormat* nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue()); // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns. if (!nf) nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue().get(state, state->vm().propertyNames->intlSubstituteValuePrivateName)); if (!nf) return JSValue::encode(throwTypeError(state, ASCIILiteral("Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat"))); JSBoundFunction* boundFormat = nf->boundFormat(); // 2. If nf.[[boundFormat]] is undefined, if (!boundFormat) { VM& vm = state->vm(); JSGlobalObject* globalObject = nf->globalObject(); // a. Let F be a new built-in function object as defined in 11.3.4. // b. The value of F’s length property is 1. JSFunction* targetObject = JSFunction::create(vm, globalObject, 1, ASCIILiteral("format"), IntlNumberFormatFuncFormatNumber, NoIntrinsic); JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(state)); // c. Let bf be BoundFunctionCreate(F, «this value»). boundFormat = JSBoundFunction::create(vm, state, globalObject, targetObject, nf, boundArgs, 1, ASCIILiteral("format")); if (vm.exception()) return JSValue::encode(JSValue()); // d. Set nf.[[boundFormat]] to bf. nf->setBoundFormat(vm, boundFormat); } // 3. Return nf.[[boundFormat]]. return JSValue::encode(boundFormat); }
ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(*exec->heap())) ModuleProgramExecutable(exec, source); executable->finishCreation(exec->vm()); ParserError error; DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock( vm, executable, executable->source(), debuggerMode, error); if (globalObject->hasDebugger()) globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message()); if (error.isValid()) { throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source())); return nullptr; } executable->m_unlinkedModuleProgramCodeBlock.set(exec->vm(), executable, unlinkedModuleProgramCode); executable->m_moduleEnvironmentSymbolTable.set(exec->vm(), executable, jsCast<SymbolTable*>(unlinkedModuleProgramCode->constantRegister(unlinkedModuleProgramCode->moduleEnvironmentSymbolTableConstantRegisterOffset()).get())->cloneScopePart(exec->vm())); return executable; }
// Evaluate some JavaScript code in the scope of this frame. JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSObject* scopeExtensionObject, NakedPtr<Exception>& exception) { ASSERT(isValid()); CallFrame* callFrame = m_validMachineFrame; if (!callFrame) return jsUndefined(); VM& vm = callFrame->vm(); JSLockHolder lock(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); CodeBlock* codeBlock = nullptr; if (isTailDeleted()) codeBlock = m_shadowChickenFrame.codeBlock; else codeBlock = callFrame->codeBlock(); if (!codeBlock) return jsUndefined(); DebuggerEvalEnabler evalEnabler(callFrame); EvalContextType evalContextType; if (isFunctionParseMode(codeBlock->unlinkedCodeBlock()->parseMode())) evalContextType = EvalContextType::FunctionEvalContext; else if (codeBlock->unlinkedCodeBlock()->codeType() == EvalCode) evalContextType = codeBlock->unlinkedCodeBlock()->evalContextType(); else evalContextType = EvalContextType::None; VariableEnvironment variablesUnderTDZ; JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ); EvalExecutable* eval = DirectEvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); return jsUndefined(); } JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject(); if (scopeExtensionObject) { JSScope* ignoredPreviousScope = globalObject->globalScope(); globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope)); } JSValue thisValue = this->thisValue(); JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope()); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } if (scopeExtensionObject) globalObject->clearGlobalScopeExtension(); ASSERT(result); return result; }
JSJSGlobalObject::JSJSGlobalObject() { JSGlobalObject *pthis = (static_cast<JSGlobalObject *>(this)); pthis->js_addInterface(JS_JSGlobalObject_GUID, pthis); pthis->js_addClassDescriptor(&JSJSGlobalObject::classDescriptor); pthis->js_addFunctionTable(JSJSGlobalObject::functionTable); jsSink = new JSJSGlobalObjectEventSink(this); jsSink->eventSink_registerTo(pthis); }
ExecState* NPRuntimeObjectMap::globalExec() const { JSGlobalObject* globalObject = this->globalObject(); if (!globalObject) return 0; return globalObject->globalExec(); }
static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec) { JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject(); if (!exec->argumentCount()) return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure())); return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure(), exec->argument(0).toString(exec))); }
static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec) { JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject(); Structure* weakSetStructure = globalObject->weakSetStructure(); JSWeakSet* weakSet = JSWeakSet::create(exec, weakSetStructure); JSValue iterable = exec->argument(0); if (iterable.isUndefinedOrNull()) return JSValue::encode(weakSet); JSValue adderFunction = weakSet->JSObject::get(exec, exec->propertyNames().add); if (exec->hadException()) return JSValue::encode(jsUndefined()); CallData adderFunctionCallData; CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData); if (adderFunctionCallType == CallTypeNone) return JSValue::encode(throwTypeError(exec)); JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol); if (exec->hadException()) return JSValue::encode(jsUndefined()); CallData iteratorFunctionCallData; CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData); if (iteratorFunctionCallType == CallTypeNone) return JSValue::encode(throwTypeError(exec)); ArgList iteratorFunctionArguments; JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (!iterator.isObject()) return JSValue::encode(throwTypeError(exec)); while (true) { JSValue next = iteratorStep(exec, iterator); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (next.isFalse()) return JSValue::encode(weakSet); JSValue nextValue = iteratorValue(exec, next); if (exec->hadException()) return JSValue::encode(jsUndefined()); MarkedArgumentBuffer arguments; arguments.append(nextValue); call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakSet, arguments); if (exec->hadException()) { iteratorClose(exec, iterator); return JSValue::encode(jsUndefined()); } } RELEASE_ASSERT_NOT_REACHED(); return JSValue::encode(weakSet); }
JSValue linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey, JSValue scriptFetcher) { JSLockHolder lock(exec); RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable()); RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread()); JSGlobalObject* globalObject = exec->vmEntryGlobalObject(); return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(exec->vm(), moduleKey), scriptFetcher); }
JSInternalPromise* linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey) { JSLockHolder lock(exec); RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable()); RELEASE_ASSERT(!exec->vm().isCollectorBusy()); JSGlobalObject* globalObject = exec->vmEntryGlobalObject(); return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(exec->vm(), moduleKey)); }
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec) { JSGlobalObject* globalObject = exec->callee()->globalObject(); ArgList args(exec); JSValue arg = args.at(0); if (arg.isUndefinedOrNull()) return constructEmptyObject(exec, globalObject->objectPrototype()); return arg.toObject(exec, globalObject); }