JsErrorCode ChakraHost::RunSerializedScript(const wchar_t* szPath, const wchar_t* szSerializedPath, const wchar_t* szSourceUri, JsValueRef* result) { HANDLE hFile = NULL; HANDLE hMap = NULL; JsErrorCode status = JsNoError; ULONG bufferSize = 0L; BYTE* buffer = nullptr; wchar_t* szScriptBuffer = nullptr; IfFailRet(LoadFileContents(szPath, &szScriptBuffer)); if (!CompareLastWrite(szSerializedPath, szPath)) { IfFailRet(JsSerializeScript(szScriptBuffer, buffer, &bufferSize)); buffer = new BYTE[bufferSize]; IfFailRet(JsSerializeScript(szScriptBuffer, buffer, &bufferSize)); FILE* file; _wfopen_s(&file, szSerializedPath, L"wb"); fwrite(buffer, sizeof(BYTE), bufferSize, file); fclose(file); } else { IfFailRet(LoadByteCode(szSerializedPath, &buffer, &hFile, &hMap)); } SerializedSourceContext* context = new SerializedSourceContext(); context->byteBuffer = buffer; context->scriptBuffer = szScriptBuffer; context->fileHandle = hFile; context->mapHandle = hMap; IfFailRet(JsRunSerializedScriptWithCallback(&LoadSourceCallback, &UnloadSourceCallback, buffer, (JsSourceContext)context, szSourceUri, result)); return status; }
//--------------------------------------------------------------------------- bool tTJS::LoadByteCode( class tTJSBinaryStream* stream, tTJSVariant *result, iTJSDispatch2 *context, const tjs_char *name ) { bool ret = false; tjs_uint8* buff = NULL; try { tjs_uint64 streamlen = stream->GetSize(); if( streamlen >= tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE ) { tjs_uint8 header[tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE]; stream->Read( header, tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE ); if( tTJSByteCodeLoader::IsTJS2ByteCode( header ) ) { stream->Seek( 0, TJS_BS_SEEK_SET ); buff = new tjs_uint8[static_cast<unsigned int>(streamlen)]; stream->Read( buff, static_cast<tjs_uint>(streamlen) ); LoadByteCode( buff, static_cast<size_t>(streamlen), result, context, name ); ret = true; } else { assert( tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE == tTJSBinarySerializer::HEADER_LENGTH ); if( result != NULL && tTJSBinarySerializer::IsBinary( header ) ) { tTJSBinarySerializer binload; tTJSVariant* var = binload.Read( stream );; if( var ) { *result = *var; delete var; ret = true; } } } } } catch(...) { delete[] buff; throw; } delete[] buff; return ret; }
bool ShaderVariation::Create() { Release(); if (!graphics_) return false; if (!owner_) { compilerOutput_ = "Owner shader has expired"; return false; } // Check for up-to-date bytecode on disk String path, name, extension; SplitPath(owner_->GetName(), path, name, extension); extension = type_ == VS ? ".vs3" : ".ps3"; String binaryShaderName = graphics_->GetShaderCacheDir() + name + "_" + StringHash(defines_).ToString() + extension; if (!LoadByteCode(binaryShaderName)) { // Compile shader if don't have valid bytecode if (!Compile()) return false; // Save the bytecode after successful compile, but not if the source is from a package if (owner_->GetTimeStamp()) SaveByteCode(binaryShaderName); } // Then create shader from the bytecode IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice(); if (type_ == VS) { HRESULT hr = device->CreateVertexShader( (const DWORD*)&byteCode_[0], (IDirect3DVertexShader9**)&object_.ptr_); if (FAILED(hr)) { ATOMIC_SAFE_RELEASE(object_.ptr_); compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")"; } } else { HRESULT hr = device->CreatePixelShader( (const DWORD*)&byteCode_[0], (IDirect3DPixelShader9**)&object_.ptr_); if (FAILED(hr)) { ATOMIC_SAFE_RELEASE(object_.ptr_); compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")"; } } // The bytecode is not needed on Direct3D9 after creation, so delete it to save memory byteCode_.Clear(); byteCode_.Reserve(0); return object_.ptr_ != 0; }