void AssemblyHelpers::callExceptionFuzz() { if (!Options::enableExceptionFuzz()) return; EncodedJSValue* buffer = vm()->exceptionFuzzingBuffer(sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters)); for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { #if USE(JSVALUE64) store64(GPRInfo::toRegister(i), buffer + i); #else store32(GPRInfo::toRegister(i), buffer + i); #endif } for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); storeDouble(FPRInfo::toRegister(i), Address(GPRInfo::regT0)); } // Set up one argument. #if CPU(X86) poke(GPRInfo::callFrameRegister, 0); #else move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); #endif move(TrustedImmPtr(bitwise_cast<void*>(operationExceptionFuzz)), GPRInfo::nonPreservedNonReturnGPR); call(GPRInfo::nonPreservedNonReturnGPR); for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); loadDouble(Address(GPRInfo::regT0), FPRInfo::toRegister(i)); } for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { #if USE(JSVALUE64) load64(buffer + i, GPRInfo::toRegister(i)); #else load32(buffer + i, GPRInfo::toRegister(i)); #endif } }
// while static void whilet(Pu *L, Token *ptoken) { int while_begin = L->cur_token; OperatorType while_end = ptoken->optype; for(;;) { NEXT_TOKEN; const __pu_value *t = exp(L); CHECK_EXP(t); bool loop = VALUE_IS_TRUE(*t); // 判断while条件是否满足 if (loop) { vm(L); if (L->isreturn || L->isquit || L->isyield) return; PuType putp = TOKEN.type; switch (putp) { case END: case CONTINUE: L->cur_token = while_begin; continue; case BREAK: L->cur_token = while_end; NEXT_TOKEN; NEXT_TOKEN; default: break; } return; } L->cur_token = while_end; NEXT_TOKEN; NEXT_TOKEN; break; } }
void GpFitness::check_solution(const p_dna&d,Concrete::CData*cdata) { if(cdata==NULL) cdata=m_cdata; LOG("numbers="<<m_numbers); double result=0; double worst_percent=0; // double result_new=0; Tree::Tree t; t.set_fdb(m_fdb); t.flat_to_tree(d->genom()); { std::ofstream of("gp.out"); if(!of){ LOG("Can`t open the file gp.out."); LOG(t.save_to_str()); } else of<<t.save_to_str(); } LOG(t.to_str()); for(int i=0;i<m_cdata->size();++i){ Tree::VarMap vm(make_varmap(m_cdata,i)); double v=t.eval(vm); double y_etalon=m_cdata->y_for_xp(i); LOG(i<<";"<<y_etalon<<";"<<v); double diff=fabs(v-y_etalon); result+=diff; if (diff>worst_percent) worst_percent=diff; } int size_diff=m_cdata->size()-m_numbers.size(); if(size_diff==0) size_diff=1; LOG(result/m_cdata->size()<<", "<<worst_percent); }
// Utils // Some links: // ***** http://www.songho.ca/opengl/gl_transform.html // ** http://www.vb6.us/tutorials/using-mouse-click-3d-space-directx-8 // *** http://www.mvps.org/directx/articles/rayproj.htm // ------------------------------------------------------------------------- Vec3 Camera::screenToWorld(float nX, float nY, float nZ) { float mouse_x = nX; float mouse_y = nY; // @todo printf("ERROR in CAMERA: ofGetWidth(), ofGetHeight() cannot be used! pass as param!"); float screen_w = 100; float screen_h = 200; // float screen_w = ofGetWidth(); // float screen_h = ofGetHeight(); float aspect = screen_w/screen_h; float ndx = -1.0f + (mouse_x/screen_w) * 2.0f; // left: -1, right: 1 float ndy = (1.0f - (mouse_y/(screen_h * 0.5))); // top: -1, bottom: 1 float ndz = 2.0*nZ-1.0; //ndz = nZ; updateViewMatrix(); updateProjectionMatrix(); Vec4 ndc(ndx, ndy, ndz, 1.0); // cout << "ndc cam:" << ndc << endl; // Mat4 mvp = mvm() * pm() ; Mat4 mvp = pm() * vm(); mvp.inverse(); ndc = mvp * ndc; // cout << "out cam:" << ndc << endl; // ndc = affine_inverse(mvp) * ndc; // cout << "@@@@@@@@@@@@@@@@@ cam @@@@@@@@@@@@@@@@@@@@@\n"; //Mat4 inv = affine_inverse(mvp); //cout << inv; // cout << mvp ; // cout << "######################################\n\n"; ndc.w = 1.0f / ndc.w; Vec3 r(ndc.x * ndc.w, ndc.y * ndc.w, ndc.z * ndc.w); return r; }
String CallFrame::friendlyFunctionName() { CodeBlock* codeBlock = this->codeBlock(); if (!codeBlock) return emptyString(); switch (codeBlock->codeType()) { case EvalCode: return ASCIILiteral("eval code"); case ModuleCode: return ASCIILiteral("module code"); case GlobalCode: return ASCIILiteral("global code"); case FunctionCode: if (callee()) return getCalculatedDisplayName(vm(), callee()); return emptyString(); } ASSERT_NOT_REACHED(); return emptyString(); }
void JIT::compileCallEvalSlowCase(const Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter) { linkAllSlowCases(iter); auto bytecode = instruction->as<OpCallEval>(); CallLinkInfo* info = m_codeBlock->addCallLinkInfo(); info->setUpCall(CallLinkInfo::Call, CodeOrigin(m_bytecodeOffset), regT0); int registerOffset = -bytecode.m_argv; int callee = bytecode.m_callee.offset(); addPtr(TrustedImm32(registerOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), callFrameRegister, stackPointerRegister); emitLoad(callee, regT1, regT0); emitDumbVirtualCall(*vm(), info); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); checkStackPointerAlignment(); sampleCodeBlock(m_codeBlock); emitPutCallResult(bytecode); }
void LLVMState::compile(STATE, CompiledCode* code, Class* receiver_class, BlockEnvironment* block_env, bool is_block) { if(!enabled_) return; // TODO: Fix compile policy checks if(!code->keywords()->nil_p()) { vm()->metrics().jit.methods_failed++; return; } // In case the method hasn't been internalized yet if(!code->machine_code()) { code->internalize(state); } JITCompileRequest* req = JITCompileRequest::create(state, code, receiver_class, 0, block_env, is_block); wait_mutex.lock(); req->waiter(&wait_cond); add(state, req); { UnmanagedPhase unmanaged(state); wait_cond.wait(wait_mutex); } wait_mutex.unlock(); if(state->shared().config.jit_show_compiling) { llvm::outs() << "[[[ JIT compiled " << enclosure_name(code) << "#" << symbol_debug_str(code->name()) << (req->is_block() ? " (block) " : " (method) ") << " ]]]\n"; } }
/* similar to eval,but use different args, it's a hack for macro because macro is not eval in one env,actually */ static OBJ fake_eval(const struct analyze_t *arg) { char *bytecode; OBJ ast; OBJ ret; ast = analyze_r(arg); if(ast == OBJ_NULL) { fprintf(stderr,"ast error"); return NULL; } bytecode = generate(ast); if(bytecode == NULL) { fprintf(stderr,"compile error"); return OBJ_NULL; } ret = vm(bytecode); free(bytecode); return ret; }
int main(int argc, char **argv) { VoxelMesh vm(dim3(20, 20, 20), point(0, 0, 0), point(1, 1, 1)); std::vector<metaball> mbs; for (int i = 0; i < 20; i++) { mbs.push_back(metaball(point(randv(), randv(), randv()), 3 * randv() - 1)); } std::cout << "Setting voxel data" << std::endl; vm.for_each_voxel([&mbs] (VoxelMesh &vm, const dim3 &vox) { const point &p = vm.center(vox); /* vm[vox] = 0; for (const auto &m : mbs) vm[vox] += m(p); */ vm[vox] = 1. / (p - point(.5, .5, .5)).norm(); }); bool tri = true; if (argc > 1) tri = std::string(argv[1])[0] == 't'; std::cout << "Generating mesh" << std::endl; double th = 2.1; if (tri) { SurfaceMesh<triangle> sm(vm, th); std::cout << "Saving TRI mesh" << std::endl; sm.save_vtk("res_tri.vtk"); sm.save_txt("res.tri"); } else { SurfaceMesh<quad> sm(vm, th); std::cout << "Saving QUAD mesh" << std::endl; sm.save_vtk("res_quad.vtk"); sm.save_txt("res.quad"); } return 0; }
void calcAndResetEmissions(SeqData const & seqData, Grammar & g, EmitWrappers & ew, EmitAnnoMap & eam, string const & annoName) { // mk emissions unsigned n = seqData.seqSize(); xvector_t tmpV(n); reset(tmpV); vector<xvector_t> vv(ew.vecWrapNames().size(), tmpV); ew.vectorEmissions(vv, seqData); xmatrix_t tmpM(n, n); reset(tmpM); vector<xmatrix_t> vm(ew.matWrapNames().size(), tmpM); ew.matrixEmissions(vm, seqData); // mask according to anno if ( eam.size() and annoName.size() ) { string const & anno = seqData.getAnno(annoName); maskEmissions(vv, ew.vecWrapNames(), anno, eam); maskEmissions(vm, ew.matWrapNames(), anno, eam); } g.resetEmissions(vv, vm); }
void Response::write_response(STATE, const char* response, native_int size) { file::LockGuard guard(fd_, LOCK_EX); if(guard.status() != file::eLockSucceeded) { logger::error("%s: unable to lock response file", strerror(errno)); return; } if(lseek(fd_, 0, SEEK_SET) < 0) { logger::error("%s: console: unable to rewind response file", strerror(errno)); return; } if(ftruncate(fd_, 0) < 0) { logger::error("%s: console: unable to truncate response file", strerror(errno)); return; } if(::write(fd_, response, size) < 0) { logger::error("%s: console: unable to write response", strerror(errno)); } vm()->metrics().console.responses_sent++; }
TEST(VirtualMachineTests, Branching) { VirtualMachine vm(0); SVM_PROGRAM_BEGIN(program); SVM_PRO_PUSH(VirtualMachine::getReservedAllocation() + 4u); SVM_PRO_OP(JUMP); SVM_PRO_OP(HALT); SVM_PRO_PUSH(100.f); SVM_PRO_OP(HALT); SVM_PROGRAM_END; vm.loadProgram(program); vm.run(); ASSERT_EQ(100.f, vm.pop()->getNumber()); SVM_PROGRAM_RESET(program); SVM_PRO_PUSH(false); SVM_PRO_PUSH(VirtualMachine::getReservedAllocation() + 15u); SVM_PRO_OP(JUMPF); SVM_PRO_PUSH(100.f); SVM_PRO_PUSH(true); SVM_PRO_PUSH(VirtualMachine::getReservedAllocation() + 13u); SVM_PRO_OP(JUMPF); SVM_PRO_OP(HALT); SVM_PRO_PUSH(100.f); SVM_PRO_OP(HALT); SVM_PROGRAM_END; vm.loadProgram(program); vm.run(); ASSERT_GE(2u, vm.getStack().size()); EXPECT_EQ(100.f, vm.pop()->getNumber()); EXPECT_EQ(100.f, vm.pop()->getNumber()); }
static int run(const std::string& path, int argc, const char* argv[], const char* envp[]) { Common::NativeAllocator allocator; OSEnvironment::NativeThreadManager threads; OSEnvironment::Managers managers(allocator, threads); CFM::DummyLibraryResolver dummyResolver(allocator); ClassixCore::DlfcnLibraryResolver dlfcnResolver(allocator, managers); ClassixCore::BundleLibraryResolver bundleResolver(allocator, managers); dlfcnResolver.RegisterLibrary("StdCLib"); dlfcnResolver.RegisterLibrary("MathLib"); dlfcnResolver.RegisterLibrary("ThreadsLib"); bundleResolver.AllowLibrary("InterfaceLib"); bundleResolver.AllowLibrary("ControlStripLib"); char* directory = strdup(path.c_str()); char* executableName = directory; for (char* iter = directory; *iter != 0; iter++) { if (*iter == '/') executableName = iter; } *executableName = 0; executableName++; chdir(directory); std::string executable = executableName; free(directory); Classix::VirtualMachine vm(allocator, managers); vm.AddLibraryResolver(dlfcnResolver); vm.AddLibraryResolver(bundleResolver); vm.AddLibraryResolver(dummyResolver); auto stub = vm.LoadMainContainer(executable); return stub(argc, argv, envp); }
int main( int argc, char** argv ) { typedef Feel::Application Application_type; typedef boost::shared_ptr<Application_type> Application_ptrtype; Feel::Environment env( Feel::_argc=argc,Feel::_argv=argv, Feel::_about=test_twolaplaciansdistributed::makeAbout(), Feel::_desc=test_twolaplaciansdistributed::makeOptions() ); auto theApp = Application_ptrtype( new Application_type ); if ( theApp->vm().count( "help" ) ) { std::cout << theApp->optionsDescription() << "\n"; exit( 0 ); } theApp->changeRepository( boost::format( "/testsuite/feeldiscr/%1%/" ) % theApp->about().appName() ); test_twolaplaciansdistributed::run( theApp ); }
int CommandLineInterface::lua_call(const std::vector<std::string>& tokens) { if (tokens.size() < 2) { std::cerr << "Argument expected!" << std::endl; return -1; } lua_getglobal(vm(), tokens[1].c_str()); try { for (int i = 2; i < tokens.size(); i ++) { if (isdigit(*(tokens[i].c_str()))) { struct tm time; getdate_r(tokens[i].c_str(), &time); lua_pushnumber(vm(), mktime(&time)); continue; } if (*(tokens[i].c_str()) == '#') { lua_create_lua_object(vm(), ::cache(tokens[i])); continue; } lua_pushstring(vm(), tokens[i].c_str()); } } catch (std::out_of_range) { std::cerr << "No such object!" << std::endl; return -1; } if (lua_pcall(vm(), tokens.size() - 2, 0, 0)) { std::cerr << lua_tostring(vm(), -1) << std::endl; return -1; } return 0; }
int MalieExec::ExportStrByCode(void) { CMalie_VMParse vm(this); vector<wstring> chapterName; vector<DWORD> chapterIndex; vector<DWORD> chapterRegion; vector<Malie_Moji> && moji = vm.ParseScenario(chapterName,chapterIndex); if (!chapterName.size()) { vector<DWORD>::iterator it = unique(chapterIndex.begin(),chapterIndex.end()); chapterIndex.erase(it,chapterIndex.end()); } auto exportFunc = [&](pair<DWORD,wstring>(&x),FILE *fp){ fwprintf(fp,L"○%08d○\n%s●%08d●\n%s◇%08d◇\n\n\n", x.first,x.second.c_str(),x.first,x.second.c_str(),x.first); }; fprintf(stderr,"\nStarting dumping text to file...\n"); if (chapterIndex.size()) { chapterRegion = chapterIndex; chapterRegion.erase(chapterRegion.begin()); chapterRegion.push_back(moji.size()); for (size_t i=0;i<chapterIndex.size();++i) { wstring && name = i<chapterName.size()? stringf(L"%02d %ls.txt",i,chapterName[i].c_str()): stringf(L"%02d.txt",i); FILE *fp; _wfopen_s(&fp,name.c_str(),L"wt,ccs=UNICODE"); for_each(moji.begin()+chapterIndex[i],moji.begin()+chapterRegion[i],[&](Malie_Moji x) { wstring kotoba; if (!x.name.empty()) { kotoba = x.name+L"※"; } kotoba += ParseString(x.index); exportFunc(pair<DWORD,wstring>(x.index,kotoba),fp); fflush(fp); }); fclose(fp); } } else { FILE *fp; _wfopen_s(&fp,L"MalieMoji.txt",L"wb"); fwrite("\xff\xfe", 1, 2, fp); //for_each(moji.begin(), moji.end(), [&](Malie_Moji x) //{ // wstring kotoba; // if (!x.name.empty()) // { // kotoba = x.name + L"※"; // } // kotoba += ParseString(x.index); // exportFunc(pair<DWORD, wstring>(x.index, kotoba), fp); //}); auto write_crln = [](FILE* fp) { fwrite(L"\r\n", 2, 2, fp); }; for (auto& x : moji) { wchar_t tag[100]; auto cnt = swprintf_s(tag, L"#%05d %s", x.index, x.name.c_str()); fwrite(tag, 2, cnt, fp); write_crln(fp); auto s = GetString(x.index); MalieString str(s); str.init(); auto v = str.export_str(); for (auto& s : v) { fwrite(s.c_str(), 2, s.length(), fp); write_crln(fp); } } fclose(fp); fp = fopen("str.txt", "wb"); fwrite("\xff\xfe", 1, 2, fp); auto fp2 = fopen("str.idx", "wb"); auto write_tbl = [&](map<int, wstring>& tbl) { for (auto& itr : tbl) { fwrite(&itr.first, 1, 4, fp2); fwrite(itr.second.c_str(), 2, itr.second.length(), fp); write_crln(fp); } }; write_tbl(vm.get_name_data_table()); write_tbl(vm.get_sel_data_table()); fclose(fp); fclose(fp2); } fprintf(stderr,"Done.\n"); return 0; }
void PageScriptDebugServer::recompileAllJSFunctions() { JSLockHolder lock(vm()); Debugger::recompileAllJSFunctions(); }
void Heap::collect(SweepToggle sweepToggle) { #if ENABLE(ALLOCATION_LOGGING) dataLogF("JSC GC starting collection.\n"); #endif double before = 0; if (Options::logGC()) { dataLog("[GC", sweepToggle == DoSweep ? " (eager sweep)" : "", ": "); before = currentTimeMS(); } SamplingRegion samplingRegion("Garbage Collection"); RELEASE_ASSERT(!m_deferralDepth); GCPHASE(Collect); ASSERT(vm()->currentThreadIsHoldingAPILock()); RELEASE_ASSERT(vm()->identifierTable == wtfThreadData().currentIdentifierTable()); ASSERT(m_isSafeToCollect); JAVASCRIPTCORE_GC_BEGIN(); RELEASE_ASSERT(m_operationInProgress == NoOperation); m_deferralDepth++; // Make sure that we don't GC in this call. m_vm->prepareToDiscardCode(); m_deferralDepth--; // Decrement deferal manually, so we don't GC when we do so, since we are already GCing!. m_operationInProgress = Collection; m_extraMemoryUsage = 0; if (m_activityCallback) m_activityCallback->willCollect(); double lastGCStartTime = WTF::monotonicallyIncreasingTime(); if (lastGCStartTime - m_lastCodeDiscardTime > minute) { deleteAllCompiledCode(); m_lastCodeDiscardTime = WTF::monotonicallyIncreasingTime(); } { GCPHASE(StopAllocation); m_objectSpace.stopAllocating(); } markRoots(); { GCPHASE(ReapingWeakHandles); m_objectSpace.reapWeakSets(); } JAVASCRIPTCORE_GC_MARKED(); { GCPHASE(SweepingArrayBuffers); m_arrayBuffers.sweep(); } { m_blockSnapshot.resize(m_objectSpace.blocks().set().size()); MarkedBlockSnapshotFunctor functor(m_blockSnapshot); m_objectSpace.forEachBlock(functor); } copyBackingStores(); { GCPHASE(FinalizeUnconditionalFinalizers); finalizeUnconditionalFinalizers(); } { GCPHASE(DeleteCodeBlocks); deleteUnmarkedCompiledCode(); } { GCPHASE(DeleteSourceProviderCaches); m_vm->clearSourceProviderCaches(); } if (sweepToggle == DoSweep) { SamplingRegion samplingRegion("Garbage Collection: Sweeping"); GCPHASE(Sweeping); m_objectSpace.sweep(); m_objectSpace.shrink(); } m_sweeper->startSweeping(m_blockSnapshot); m_bytesAbandoned = 0; { GCPHASE(ResetAllocators); m_objectSpace.resetAllocators(); } size_t currentHeapSize = sizeAfterCollect(); if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize()) HeapStatistics::exitWithFailure(); m_sizeAfterLastCollect = currentHeapSize; // To avoid pathological GC churn in very small and very large heaps, we set // the new allocation limit based on the current size of the heap, with a // fixed minimum. size_t maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize)); m_bytesAllocatedLimit = maxHeapSize - currentHeapSize; m_bytesAllocated = 0; double lastGCEndTime = WTF::monotonicallyIncreasingTime(); m_lastGCLength = lastGCEndTime - lastGCStartTime; if (Options::recordGCPauseTimes()) HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime); RELEASE_ASSERT(m_operationInProgress == Collection); m_operationInProgress = NoOperation; JAVASCRIPTCORE_GC_END(); if (Options::useZombieMode()) zombifyDeadObjects(); if (Options::objectsAreImmortal()) markDeadObjects(); if (Options::showObjectStatistics()) HeapStatistics::showObjectStatistics(this); if (Options::logGC()) { double after = currentTimeMS(); dataLog(after - before, " ms, ", currentHeapSize / 1024, " kb]\n"); } #if ENABLE(ALLOCATION_LOGGING) dataLogF("JSC GC finishing collection.\n"); #endif }
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception* exception, CachedScript* cachedScript) { EventTarget* target = errorEventTarget(); if (!target) return false; #if PLATFORM(IOS) if (target->toDOMWindow() && is<Document>(*this)) { Settings* settings = downcast<Document>(*this).settings(); if (settings && !settings->shouldDispatchJavaScriptWindowOnErrorEvents()) return false; } #endif String message = errorMessage; int line = lineNumber; int column = columnNumber; String sourceName = sourceURL; Deprecated::ScriptValue error = exception && exception->value() ? Deprecated::ScriptValue(vm(), exception->value()) : Deprecated::ScriptValue(); sanitizeScriptError(message, line, column, sourceName, error, cachedScript); ASSERT(!m_inDispatchErrorEvent); m_inDispatchErrorEvent = true; Ref<ErrorEvent> errorEvent = ErrorEvent::create(message, sourceName, line, column, error); target->dispatchEvent(errorEvent); m_inDispatchErrorEvent = false; return errorEvent->defaultPrevented(); }
int main(int argc, char **argv) { args llstArgs; llstArgs.heapSize = 1048576; llstArgs.maxHeapSize = 1048576 * 100; llstArgs.imagePath = "../image/LittleSmalltalk.image"; llstArgs.parse(argc, argv); if (llstArgs.showHelp) { std::cout << args::getHelp() << std::endl; return EXIT_SUCCESS; } if (llstArgs.showVersion) { std::cout << args::getVersion() << std::endl; return EXIT_SUCCESS; } IMemoryManager* mm; if(llstArgs.memoryManagerType == "nc") { mm = new NonCollectMemoryManager(); } else if(llstArgs.memoryManagerType == "" || llstArgs.memoryManagerType == "copy") { #if defined(LLVM) mm = new LLVMMemoryManager(); #else mm = new BakerMemoryManager(); #endif } else{ std::cout << "error: wrong option --mm_type=" << llstArgs.memoryManagerType << ";\n" << "defined options for memory manager type:\n" << "\"copy\" (default) - copying garbage collector;\n" << "\"nc\" - non-collecting memory manager.\n"; return EXIT_FAILURE; } std::auto_ptr<IMemoryManager> memoryManager(mm); memoryManager->initializeHeap(llstArgs.heapSize, llstArgs.maxHeapSize); memoryManager->setLogger(std::tr1::shared_ptr<IGCLogger>(new GCLogger("gc.log"))); std::auto_ptr<Image> smalltalkImage(new Image(memoryManager.get())); smalltalkImage->loadImage(llstArgs.imagePath); SmalltalkVM vm(smalltalkImage.get(), memoryManager.get()); // Creating completion database and filling it with info CompletionEngine* completionEngine = CompletionEngine::Instance(); completionEngine->initialize(globals.globalsObject); completionEngine->addWord("Smalltalk"); #if defined(LLVM) JITRuntime runtime; runtime.initialize(&vm); #endif // Creating runtime context hptr<TContext> initContext = vm.newObject<TContext>(); hptr<TProcess> initProcess = vm.newObject<TProcess>(); initProcess->context = initContext; initContext->arguments = vm.newObject<TObjectArray>(1); initContext->arguments->putField(0, globals.nilObject); initContext->bytePointer = 0; initContext->previousContext = static_cast<TContext*>(globals.nilObject); const uint32_t stackSize = globals.initialMethod->stackSize; initContext->stack = vm.newObject<TObjectArray>(stackSize); initContext->stackTop = 0; initContext->method = globals.initialMethod; // FIXME image builder does not calculate temporary size //uint32_t tempsSize = getIntegerValue(initContext->method->temporarySize); initContext->temporaries = vm.newObject<TObjectArray>(42); // And starting the image execution! SmalltalkVM::TExecuteResult result = vm.execute(initProcess, 0); /* This code will run Smalltalk immediately in LLVM. * Don't forget to uncomment 'Undefined>>boot' */ /* typedef int32_t (*TExecuteProcessFunction)(TProcess*); TExecuteProcessFunction executeProcess = reinterpret_cast<TExecuteProcessFunction>(runtime.getExecutionEngine()->getPointerToFunction(runtime.getModule()->getFunction("executeProcess"))); SmalltalkVM::TExecuteResult result = (SmalltalkVM::TExecuteResult) executeProcess(initProcess); */ // Finally, parsing the result switch (result) { case SmalltalkVM::returnError: std::printf("User defined return\n"); break; case SmalltalkVM::returnBadMethod: std::printf("Could not lookup method\n"); break; case SmalltalkVM::returnReturned: // normal return std::printf("Exited normally\n"); break; case SmalltalkVM::returnTimeExpired: std::printf("Execution time expired\n"); break; default: std::printf("Unknown return code: %d\n", result); } TMemoryManagerInfo info = memoryManager->getStat(); int averageAllocs = info.collectionsCount ? info.allocationsCount / info.collectionsCount : info.allocationsCount; std::printf("\nGC count: %d (%d/%d), average allocations per gc: %d, microseconds spent in GC: %d\n", info.collectionsCount, info.leftToRightCollections, info.rightToLeftCollections, averageAllocs, static_cast<uint32_t>(info.totalCollectionDelay)); vm.printVMStat(); #if defined(LLVM) runtime.printStat(); #endif return EXIT_SUCCESS; }
void Run(string &evalret, const char *programname) { VM vm(st, &code[0], code.size(), linenumbers, programname); vm.EvalProgram(evalret); }
bool foldConstants(BasicBlock* block) { bool changed = false; m_state.beginBasicBlock(block); for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) { if (!m_state.isValid()) break; Node* node = block->at(indexInBlock); bool eliminated = false; switch (node->op()) { case BooleanToNumber: { if (node->child1().useKind() == UntypedUse && !m_interpreter.needsTypeCheck(node->child1(), SpecBoolean)) node->child1().setUseKind(BooleanUse); break; } case CheckArgumentsNotCreated: { if (!isEmptySpeculation( m_state.variables().operand( m_graph.argumentsRegisterFor(node->origin.semantic)).m_type)) break; node->convertToPhantom(); eliminated = true; break; } case CheckStructure: case ArrayifyToStructure: { AbstractValue& value = m_state.forNode(node->child1()); StructureSet set; if (node->op() == ArrayifyToStructure) set = node->structure(); else set = node->structureSet(); if (value.m_currentKnownStructure.isSubsetOf(set)) { m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell. node->convertToPhantom(); eliminated = true; break; } StructureAbstractValue& structureValue = value.m_futurePossibleStructure; if (structureValue.isSubsetOf(set) && structureValue.hasSingleton()) { Structure* structure = structureValue.singleton(); m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell. AdjacencyList children = node->children; children.removeEdge(0); if (!!children.child1()) m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->origin, children); node->children.setChild2(Edge()); node->children.setChild3(Edge()); node->convertToStructureTransitionWatchpoint(structure); eliminated = true; break; } break; } case CheckArray: case Arrayify: { if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1()))) break; node->convertToPhantom(); eliminated = true; break; } case CheckFunction: { if (m_state.forNode(node->child1()).value() != node->function()) break; node->convertToPhantom(); eliminated = true; break; } case CheckInBounds: { JSValue left = m_state.forNode(node->child1()).value(); JSValue right = m_state.forNode(node->child2()).value(); if (left && right && left.isInt32() && right.isInt32() && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) { node->convertToPhantom(); eliminated = true; break; } break; } case MultiGetByOffset: { Edge childEdge = node->child1(); Node* child = childEdge.node(); MultiGetByOffsetData& data = node->multiGetByOffsetData(); Structure* structure = m_state.forNode(child).bestProvenStructure(); if (!structure) break; for (unsigned i = data.variants.size(); i--;) { const GetByIdVariant& variant = data.variants[i]; if (!variant.structureSet().contains(structure)) continue; if (variant.chain()) break; emitGetByOffset(indexInBlock, node, structure, variant, data.identifierNumber); eliminated = true; break; } break; } case MultiPutByOffset: { Edge childEdge = node->child1(); Node* child = childEdge.node(); MultiPutByOffsetData& data = node->multiPutByOffsetData(); Structure* structure = m_state.forNode(child).bestProvenStructure(); if (!structure) break; for (unsigned i = data.variants.size(); i--;) { const PutByIdVariant& variant = data.variants[i]; if (variant.oldStructure() != structure) continue; emitPutByOffset(indexInBlock, node, structure, variant, data.identifierNumber); eliminated = true; break; } break; } case GetById: case GetByIdFlush: { Edge childEdge = node->child1(); Node* child = childEdge.node(); unsigned identifierNumber = node->identifierNumber(); if (childEdge.useKind() != CellUse) break; Structure* structure = m_state.forNode(child).bestProvenStructure(); if (!structure) break; GetByIdStatus status = GetByIdStatus::computeFor( vm(), structure, m_graph.identifiers()[identifierNumber]); if (!status.isSimple() || status.numVariants() != 1) { // FIXME: We could handle prototype cases. // https://bugs.webkit.org/show_bug.cgi?id=110386 break; } emitGetByOffset(indexInBlock, node, structure, status[0], identifierNumber); eliminated = true; break; } case PutById: case PutByIdDirect: { NodeOrigin origin = node->origin; Edge childEdge = node->child1(); Node* child = childEdge.node(); unsigned identifierNumber = node->identifierNumber(); ASSERT(childEdge.useKind() == CellUse); Structure* structure = m_state.forNode(child).bestProvenStructure(); if (!structure) break; PutByIdStatus status = PutByIdStatus::computeFor( vm(), m_graph.globalObjectFor(origin.semantic), structure, m_graph.identifiers()[identifierNumber], node->op() == PutByIdDirect); if (!status.isSimple()) break; if (status.numVariants() != 1) break; emitPutByOffset(indexInBlock, node, structure, status[0], identifierNumber); eliminated = true; break; } case ToPrimitive: { if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString)) break; node->convertToIdentity(); break; } default: break; } if (eliminated) { changed = true; continue; } m_interpreter.execute(indexInBlock); if (!m_state.isValid()) { // If we invalidated then we shouldn't attempt to constant-fold. Here's an // example: // // c: JSConstant(4.2) // x: ValueToInt32(Check:Int32:@const) // // It would be correct for an analysis to assume that execution cannot // proceed past @x. Therefore, constant-folding @x could be rather bad. But, // the CFA may report that it found a constant even though it also reported // that everything has been invalidated. This will only happen in a couple of // the constant folding cases; most of them are also separately defensive // about such things. break; } if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant()) continue; JSValue value = m_state.forNode(node).value(); if (!value) continue; // Check if merging the abstract value of the constant into the abstract value // we've proven for this node wouldn't widen the proof. If it widens the proof // (i.e. says that the set contains more things in it than it previously did) // then we refuse to fold. AbstractValue oldValue = m_state.forNode(node); AbstractValue constantValue; constantValue.set(m_graph, value); constantValue.fixTypeForRepresentation(node); if (oldValue.merge(constantValue)) continue; NodeOrigin origin = node->origin; AdjacencyList children = node->children; if (node->op() == GetLocal) m_graph.dethread(); else ASSERT(!node->hasVariableAccessData(m_graph)); m_graph.convertToConstant(node, value); m_insertionSet.insertNode( indexInBlock, SpecNone, Phantom, origin, children); changed = true; } m_state.reset(); m_insertionSet.execute(block); return changed; }
void JSGlobalObject::reset(JSValue prototype) { ExecState* exec = JSGlobalObject::globalExec(); m_functionPrototype.set(exec->vm(), this, FunctionPrototype::create(exec, this, FunctionPrototype::createStructure(exec->vm(), this, jsNull()))); // The real prototype will be set once ObjectPrototype is created. m_functionStructure.set(exec->vm(), this, JSFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); m_boundFunctionStructure.set(exec->vm(), this, JSBoundFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); m_namedFunctionStructure.set(exec->vm(), this, Structure::addPropertyTransition(exec->vm(), m_functionStructure.get(), exec->vm().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset)); m_internalFunctionStructure.set(exec->vm(), this, InternalFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); JSFunction* callFunction = 0; JSFunction* applyFunction = 0; m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction); m_callFunction.set(exec->vm(), this, callFunction); m_applyFunction.set(exec->vm(), this, applyFunction); m_objectPrototype.set(exec->vm(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->vm(), this, jsNull()))); GetterSetter* protoAccessor = GetterSetter::create(exec); protoAccessor->setGetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoGetter)); protoAccessor->setSetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoSetter)); m_objectPrototype->putDirectAccessor(exec, exec->propertyNames().underscoreProto, protoAccessor, Accessor | DontEnum); m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->vm(), m_objectPrototype.get()); m_nameScopeStructure.set(exec->vm(), this, JSNameScope::createStructure(exec->vm(), this, jsNull())); m_activationStructure.set(exec->vm(), this, JSActivation::createStructure(exec->vm(), this, jsNull())); m_strictEvalActivationStructure.set(exec->vm(), this, StrictEvalActivation::createStructure(exec->vm(), this, jsNull())); m_withScopeStructure.set(exec->vm(), this, JSWithScope::createStructure(exec->vm(), this, jsNull())); m_nullPrototypeObjectStructure.set(exec->vm(), this, JSFinalObject::createStructure(vm(), this, jsNull(), JSFinalObject::defaultInlineCapacity())); m_callbackFunctionStructure.set(exec->vm(), this, JSCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); m_argumentsStructure.set(exec->vm(), this, Arguments::createStructure(exec->vm(), this, m_objectPrototype.get())); m_callbackConstructorStructure.set(exec->vm(), this, JSCallbackConstructor::createStructure(exec->vm(), this, m_objectPrototype.get())); m_callbackObjectStructure.set(exec->vm(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->vm(), this, m_objectPrototype.get())); #if JSC_OBJC_API_ENABLED m_objcCallbackFunctionStructure.set(exec->vm(), this, ObjCCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); m_objcWrapperObjectStructure.set(exec->vm(), this, JSCallbackObject<JSAPIWrapperObject>::createStructure(exec->vm(), this, m_objectPrototype.get())); #endif m_arrayPrototype.set(exec->vm(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithUndecided)); m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithInt32)); m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithDouble)); m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithContiguous)); m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage)); for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i]; m_regExpMatchesArrayStructure.set(exec->vm(), this, RegExpMatchesArray::createStructure(exec->vm(), this, m_arrayPrototype.get())); m_stringPrototype.set(exec->vm(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_stringObjectStructure.set(exec->vm(), this, StringObject::createStructure(exec->vm(), this, m_stringPrototype.get())); m_booleanPrototype.set(exec->vm(), this, BooleanPrototype::create(exec, this, BooleanPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_booleanObjectStructure.set(exec->vm(), this, BooleanObject::createStructure(exec->vm(), this, m_booleanPrototype.get())); m_numberPrototype.set(exec->vm(), this, NumberPrototype::create(exec, this, NumberPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_numberObjectStructure.set(exec->vm(), this, NumberObject::createStructure(exec->vm(), this, m_numberPrototype.get())); m_datePrototype.set(exec->vm(), this, DatePrototype::create(exec, this, DatePrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_dateStructure.set(exec->vm(), this, DateInstance::createStructure(exec->vm(), this, m_datePrototype.get())); RegExp* emptyRegex = RegExp::create(exec->vm(), "", NoFlags); m_regExpPrototype.set(exec->vm(), this, RegExpPrototype::create(exec, this, RegExpPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()), emptyRegex)); m_regExpStructure.set(exec->vm(), this, RegExpObject::createStructure(exec->vm(), this, m_regExpPrototype.get())); m_errorPrototype.set(exec->vm(), this, ErrorPrototype::create(exec, this, ErrorPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); m_errorStructure.set(exec->vm(), this, ErrorInstance::createStructure(exec->vm(), this, m_errorPrototype.get())); // Constructors JSCell* objectConstructor = ObjectConstructor::create(exec, this, ObjectConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_objectPrototype.get()); JSCell* functionConstructor = FunctionConstructor::create(exec, this, FunctionConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_functionPrototype.get()); JSCell* arrayConstructor = ArrayConstructor::create(exec, this, ArrayConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_arrayPrototype.get()); JSCell* stringConstructor = StringConstructor::create(exec, this, StringConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_stringPrototype.get()); JSCell* booleanConstructor = BooleanConstructor::create(exec, this, BooleanConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_booleanPrototype.get()); JSCell* numberConstructor = NumberConstructor::create(exec, this, NumberConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_numberPrototype.get()); JSCell* dateConstructor = DateConstructor::create(exec, this, DateConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_datePrototype.get()); m_regExpConstructor.set(exec->vm(), this, RegExpConstructor::create(exec, this, RegExpConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_regExpPrototype.get())); m_errorConstructor.set(exec->vm(), this, ErrorConstructor::create(exec, this, ErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_errorPrototype.get())); Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->vm(), this, m_errorPrototype.get()); Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()); m_evalErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError"))); m_rangeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("RangeError"))); m_referenceErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("ReferenceError"))); m_syntaxErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("SyntaxError"))); m_typeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError"))); m_URIErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError"))); m_objectPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, objectConstructor, DontEnum); m_functionPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, functionConstructor, DontEnum); m_arrayPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, arrayConstructor, DontEnum); m_booleanPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, booleanConstructor, DontEnum); m_stringPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, stringConstructor, DontEnum); m_numberPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, numberConstructor, DontEnum); m_datePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, dateConstructor, DontEnum); m_regExpPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum); m_errorPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Object, objectConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Function, functionConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Array, arrayConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Boolean, booleanConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().String, stringConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Number, numberConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Date, dateConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().RegExp, m_regExpConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Error, m_errorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().EvalError, m_evalErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().RangeError, m_rangeErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().ReferenceError, m_referenceErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().SyntaxError, m_syntaxErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().TypeError, m_typeErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().URIError, m_URIErrorConstructor.get(), DontEnum); m_evalFunction.set(exec->vm(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.string(), globalFuncEval)); putDirectWithoutTransition(exec->vm(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().JSON, JSONObject::create(exec, this, JSONObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum); putDirectWithoutTransition(exec->vm(), exec->propertyNames().Math, MathObject::create(exec, this, MathObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum); GlobalPropertyInfo staticGlobals[] = { GlobalPropertyInfo(exec->propertyNames().NaN, jsNaN(), DontEnum | DontDelete | ReadOnly), GlobalPropertyInfo(exec->propertyNames().Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly), GlobalPropertyInfo(exec->propertyNames().undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly) }; addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); m_specialPointers[Special::CallFunction] = m_callFunction.get(); m_specialPointers[Special::ApplyFunction] = m_applyFunction.get(); m_specialPointers[Special::ObjectConstructor] = objectConstructor; m_specialPointers[Special::ArrayConstructor] = arrayConstructor; if (m_experimentsEnabled) { NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->vm(), this, m_objectPrototype.get())); m_privateNameStructure.set(exec->vm(), this, NameInstance::createStructure(exec->vm(), this, privateNamePrototype)); JSCell* privateNameConstructor = NameConstructor::create(exec, this, NameConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), privateNamePrototype); privateNamePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, privateNameConstructor, DontEnum); putDirectWithoutTransition(exec->vm(), Identifier(exec, "Name"), privateNameConstructor, DontEnum); } resetPrototype(exec->vm(), prototype); }
void FinalizerThread::initialize(STATE) { Thread::create(state, vm()); synchronization_ = new Synchronization(); }
void FinalizerThread::add_finalizer(STATE, FinalizerObject* obj) { live_list_.push_back(obj); vm()->metrics().gc.objects_queued++; }
void Thread::finalize_instance(STATE) { if(vm() && vm()->zombie_p()) { VM::discard(state, vm()); vm(NULL); } }
AssemblyHelpers::Jump AssemblyHelpers::emitExceptionCheck(ExceptionCheckKind kind, ExceptionJumpWidth width) { callExceptionFuzz(); if (width == FarJumpWidth) kind = (kind == NormalExceptionCheck ? InvertedExceptionCheck : NormalExceptionCheck); Jump result; #if USE(JSVALUE64) result = branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException())); #elif USE(JSVALUE32_64) result = branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(vm()->addressOfException()), TrustedImm32(0)); #endif if (width == NormalJumpWidth) return result; PatchableJump realJump = patchableJump(); result.link(this); return realJump.m_jump; }
WorkerScriptController::~WorkerScriptController() { JSLockHolder lock(vm()); m_workerGlobalScopeWrapper.clear(); m_vm = nullptr; }
bool foldConstants(BasicBlock* block) { bool changed = false; m_state.beginBasicBlock(block); for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) { if (!m_state.isValid()) break; Node* node = block->at(indexInBlock); bool alreadyHandled = false; bool eliminated = false; switch (node->op()) { case BooleanToNumber: { if (node->child1().useKind() == UntypedUse && !m_interpreter.needsTypeCheck(node->child1(), SpecBoolean)) node->child1().setUseKind(BooleanUse); break; } case CheckArgumentsNotCreated: { if (!isEmptySpeculation( m_state.variables().operand( m_graph.argumentsRegisterFor(node->origin.semantic)).m_type)) break; node->convertToPhantom(); eliminated = true; break; } case CheckStructure: case ArrayifyToStructure: { AbstractValue& value = m_state.forNode(node->child1()); StructureSet set; if (node->op() == ArrayifyToStructure) set = node->structure(); else set = node->structureSet(); if (value.m_structure.isSubsetOf(set)) { m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell. node->convertToPhantom(); eliminated = true; break; } break; } case CheckArray: case Arrayify: { if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1()))) break; node->convertToPhantom(); eliminated = true; break; } case PutStructure: { if (m_state.forNode(node->child1()).m_structure.onlyStructure() != node->transition()->next) break; node->convertToPhantom(); eliminated = true; break; } case CheckFunction: { if (m_state.forNode(node->child1()).value() != node->function()->value()) break; node->convertToPhantom(); eliminated = true; break; } case CheckInBounds: { JSValue left = m_state.forNode(node->child1()).value(); JSValue right = m_state.forNode(node->child2()).value(); if (left && right && left.isInt32() && right.isInt32() && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) { node->convertToPhantom(); eliminated = true; break; } break; } case MultiGetByOffset: { Edge baseEdge = node->child1(); Node* base = baseEdge.node(); MultiGetByOffsetData& data = node->multiGetByOffsetData(); // First prune the variants, then check if the MultiGetByOffset can be // strength-reduced to a GetByOffset. AbstractValue baseValue = m_state.forNode(base); m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before. alreadyHandled = true; // Don't allow the default constant folder to do things to this. for (unsigned i = 0; i < data.variants.size(); ++i) { GetByIdVariant& variant = data.variants[i]; variant.structureSet().filter(baseValue); if (variant.structureSet().isEmpty()) { data.variants[i--] = data.variants.last(); data.variants.removeLast(); changed = true; } } if (data.variants.size() != 1) break; emitGetByOffset( indexInBlock, node, baseValue, data.variants[0], data.identifierNumber); changed = true; break; } case MultiPutByOffset: { Edge baseEdge = node->child1(); Node* base = baseEdge.node(); MultiPutByOffsetData& data = node->multiPutByOffsetData(); AbstractValue baseValue = m_state.forNode(base); m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before. alreadyHandled = true; // Don't allow the default constant folder to do things to this. for (unsigned i = 0; i < data.variants.size(); ++i) { PutByIdVariant& variant = data.variants[i]; variant.oldStructure().filter(baseValue); if (variant.oldStructure().isEmpty()) { data.variants[i--] = data.variants.last(); data.variants.removeLast(); changed = true; continue; } if (variant.kind() == PutByIdVariant::Transition && variant.oldStructure().onlyStructure() == variant.newStructure()) { variant = PutByIdVariant::replace( variant.oldStructure(), variant.offset()); changed = true; } } if (data.variants.size() != 1) break; emitPutByOffset( indexInBlock, node, baseValue, data.variants[0], data.identifierNumber); changed = true; break; } case GetById: case GetByIdFlush: { Edge childEdge = node->child1(); Node* child = childEdge.node(); unsigned identifierNumber = node->identifierNumber(); AbstractValue baseValue = m_state.forNode(child); m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before. alreadyHandled = true; // Don't allow the default constant folder to do things to this. if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered() || (node->child1().useKind() == UntypedUse || (baseValue.m_type & ~SpecCell))) break; GetByIdStatus status = GetByIdStatus::computeFor( vm(), baseValue.m_structure.set(), m_graph.identifiers()[identifierNumber]); if (!status.isSimple()) break; for (unsigned i = status.numVariants(); i--;) { if (!status[i].constantChecks().isEmpty() || status[i].alternateBase()) { // FIXME: We could handle prototype cases. // https://bugs.webkit.org/show_bug.cgi?id=110386 break; } } if (status.numVariants() == 1) { emitGetByOffset(indexInBlock, node, baseValue, status[0], identifierNumber); changed = true; break; } if (!isFTL(m_graph.m_plan.mode)) break; MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add(); data->variants = status.variants(); data->identifierNumber = identifierNumber; node->convertToMultiGetByOffset(data); changed = true; break; } case PutById: case PutByIdDirect: case PutByIdFlush: { NodeOrigin origin = node->origin; Edge childEdge = node->child1(); Node* child = childEdge.node(); unsigned identifierNumber = node->identifierNumber(); ASSERT(childEdge.useKind() == CellUse); AbstractValue baseValue = m_state.forNode(child); m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before. alreadyHandled = true; // Don't allow the default constant folder to do things to this. if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered()) break; PutByIdStatus status = PutByIdStatus::computeFor( vm(), m_graph.globalObjectFor(origin.semantic), baseValue.m_structure.set(), m_graph.identifiers()[identifierNumber], node->op() == PutByIdDirect); if (!status.isSimple()) break; ASSERT(status.numVariants()); if (status.numVariants() > 1 && !isFTL(m_graph.m_plan.mode)) break; changed = true; for (unsigned i = status.numVariants(); i--;) addChecks(origin, indexInBlock, status[i].constantChecks()); if (status.numVariants() == 1) { emitPutByOffset(indexInBlock, node, baseValue, status[0], identifierNumber); break; } ASSERT(isFTL(m_graph.m_plan.mode)); MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add(); data->variants = status.variants(); data->identifierNumber = identifierNumber; node->convertToMultiPutByOffset(data); break; } case ToPrimitive: { if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString)) break; node->convertToIdentity(); changed = true; break; } case GetMyArgumentByVal: { InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame; JSValue value = m_state.forNode(node->child1()).m_value; if (inlineCallFrame && value && value.isInt32()) { int32_t index = value.asInt32(); if (index >= 0 && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) { // Roll the interpreter over this. m_interpreter.execute(indexInBlock); eliminated = true; int operand = inlineCallFrame->stackOffset + m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index); m_insertionSet.insertNode( indexInBlock, SpecNone, CheckArgumentsNotCreated, node->origin); m_insertionSet.insertNode( indexInBlock, SpecNone, Phantom, node->origin, node->children); node->convertToGetLocalUnlinked(VirtualRegister(operand)); break; } } break; } case Check: { alreadyHandled = true; m_interpreter.execute(indexInBlock); for (unsigned i = 0; i < AdjacencyList::Size; ++i) { Edge edge = node->children.child(i); if (!edge) break; if (edge.isProved() || edge.willNotHaveCheck()) { node->children.removeEdge(i--); changed = true; } } break; } default: break; } if (eliminated) { changed = true; continue; } if (alreadyHandled) continue; m_interpreter.execute(indexInBlock); if (!m_state.isValid()) { // If we invalidated then we shouldn't attempt to constant-fold. Here's an // example: // // c: JSConstant(4.2) // x: ValueToInt32(Check:Int32:@const) // // It would be correct for an analysis to assume that execution cannot // proceed past @x. Therefore, constant-folding @x could be rather bad. But, // the CFA may report that it found a constant even though it also reported // that everything has been invalidated. This will only happen in a couple of // the constant folding cases; most of them are also separately defensive // about such things. break; } if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant()) continue; // Interesting fact: this freezing that we do right here may turn an fragile value into // a weak value. See DFGValueStrength.h. FrozenValue* value = m_graph.freeze(m_state.forNode(node).value()); if (!*value) continue; NodeOrigin origin = node->origin; AdjacencyList children = node->children; m_graph.convertToConstant(node, value); if (!children.isEmpty()) { m_insertionSet.insertNode( indexInBlock, SpecNone, Phantom, origin, children); } changed = true; } m_state.reset(); m_insertionSet.execute(block); return changed; }
void Response::initialize(STATE) { Thread::create(state, vm()); }