Skip to content

Commit 7a5bc65

Browse files
committed
committing to stage changes, but not happy with the results
Tried to use Flutter as the example adding minimal libraries from it, but it doesn't look like that's a good model. Going to try going back to the dart executable dfe model.
1 parent 1a2cdc8 commit 7a5bc65

23 files changed

+1358
-530
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.1.0
Binary file not shown.

DartTest2/.packages

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Generated by pub on 2019-01-04 21:26:46.715864.
2+
vector_math:file:///C:/Users/jeff/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/vector_math-2.0.8/lib/
3+
dart_test:lib/

DartTest2/DartHelpers.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "DartHelpers.h"
2+
3+
#include <iostream>
4+
5+
namespace dh
6+
{
7+
std::string StdStringFromDart(Dart_Handle dartString)
8+
{
9+
uint8_t* data = nullptr;
10+
intptr_t length = 0;
11+
if (Dart_IsError(Dart_StringToUTF8(dartString, &data, &length)))
12+
return std::string();
13+
return std::string(reinterpret_cast<char*>(data), length);
14+
}
15+
16+
bool LogIfError(Dart_Handle handle)
17+
{
18+
if (Dart_IsUnhandledExceptionError(handle))
19+
{
20+
Dart_Handle stackTrace = Dart_ErrorGetStackTrace(handle);
21+
const std::string traceString = StdStringFromDart(Dart_ToString(stackTrace));
22+
std::cout << "Dart Unhandled Exception: " << traceString;
23+
return true;
24+
}
25+
else if (Dart_IsError(handle))
26+
{
27+
std::cout << "Dart Error: " << Dart_GetError(handle);
28+
return true;
29+
}
30+
else
31+
{
32+
return false;
33+
}
34+
}
35+
}

DartTest2/DartHelpers.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
#include "include/dart_api.h"
6+
7+
// A lot of this duplicates what's in FML or Tonic, but since those
8+
// are part of the Flutter repository I've duplicated them here
9+
namespace dh
10+
{
11+
std::string StdStringFromDart(Dart_Handle dartString);
12+
bool LogIfError(Dart_Handle handle);
13+
14+
class DartIsolateScope
15+
{
16+
public:
17+
DartIsolateScope(Dart_Isolate isolate)
18+
: _isolate(isolate)
19+
{
20+
_previous = Dart_CurrentIsolate();
21+
if (_previous == _isolate)
22+
return;
23+
if (_previous)
24+
Dart_ExitIsolate();
25+
Dart_EnterIsolate(_isolate);
26+
}
27+
28+
~DartIsolateScope()
29+
{
30+
Dart_Isolate current = Dart_CurrentIsolate();
31+
if (_previous == _isolate)
32+
return;
33+
if (current)
34+
Dart_ExitScope();
35+
if (_previous)
36+
Dart_EnterIsolate(_previous);
37+
}
38+
39+
private:
40+
Dart_Isolate _isolate;
41+
Dart_Isolate _previous;
42+
};
43+
}

DartTest2/DartIsolate.cpp

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#include "DartIsolate.h"
2+
3+
#include <iostream>
4+
5+
#include "DartHelpers.h"
6+
#include "DartIsolateGroupData.h"
7+
8+
9+
DartIsolate::DartIsolate()
10+
{
11+
_phase = Phase::Uninitialized;
12+
}
13+
14+
bool DartIsolate::Initialize(Dart_Isolate dartIsolate)
15+
{
16+
if (_phase != Phase::Uninitialized)
17+
return false;
18+
19+
if (dartIsolate == nullptr)
20+
return false;
21+
22+
if (Dart_CurrentIsolate() != dartIsolate)
23+
return false;
24+
25+
_isolate = dartIsolate;
26+
27+
/// TODO: Check if this exit isolate is correct - comment from flutter:
28+
// We are entering a new scope (for the first time since initialization) and
29+
// we want to restore the current scope to null when we exit out of this
30+
// method. This balances the implicit Dart_EnterIsolate call made by
31+
// Dart_CreateIsolateGroup (which calls the Initialize).
32+
Dart_ExitIsolate();
33+
34+
dh::DartIsolateScope scope(_isolate);
35+
36+
if (LogIfError(Dart_SetLibraryTagHandler(HandleLibraryTag))
37+
{
38+
return false;
39+
}
40+
41+
}
42+
43+
Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
44+
const char* packageRoot,
45+
const char* packageConfig,
46+
Dart_IsolateFlags* flags,
47+
char** error)
48+
{
49+
50+
flags->load_vmservice_library = true;
51+
DartIsolate::CreateRootIsolate();
52+
53+
}
54+
55+
Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
56+
const char* advisory_script_uri,
57+
const char* advisory_script_entrypoint,
58+
const char* package_root,
59+
const char* package_config,
60+
Dart_IsolateFlags* flags,
61+
std::shared_ptr<DartIsolate>* parent_isolate_data,
62+
char** error)
63+
{
64+
if (parent_isolate_data == nullptr &&
65+
strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0)
66+
{
67+
// The VM attempts to start the VM service for us on |Dart_Initialize|. In
68+
// such a case, the callback data will be null and the script URI will be
69+
// DART_VM_SERVICE_ISOLATE_NAME. In such cases, we just create the service
70+
// isolate like normal but dont hold a reference to it at all. We also start
71+
// this isolate since we will never again reference it from the engine.
72+
return DartCreateAndStartServiceIsolate(package_root,
73+
package_config,
74+
flags,
75+
error
76+
);
77+
}
78+
79+
//DartIsolateGroupData& parent_group_data =
80+
// (*parent_isolate_data)->GetIsolateGroupData();
81+
82+
//auto isolate_group_data = new DartIsolateGroupData(
83+
// //parent_group_data.GetSettings(),
84+
// //parent_group_data.GetIsolateSnapshot(),
85+
// advisory_script_uri,
86+
// advisory_script_entrypoint,
87+
// //parent_group_data.GetChildIsolatePreparer(),
88+
// //parent_group_data.GetIsolateCreateCallback(),
89+
// p//arent_group_data.GetIsolateShutdownCallback())));
90+
91+
//TaskRunners null_task_runners(advisory_script_uri,
92+
// /* platform= */ nullptr, /* raster= */ nullptr,
93+
// /* ui= */ nullptr,
94+
// /* io= */ nullptr);
95+
96+
//auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
97+
// std::shared_ptr<DartIsolate>(new DartIsolate(
98+
// (*isolate_group_data)->GetSettings(), // settings
99+
// null_task_runners, // task_runners
100+
// fml::WeakPtr<SnapshotDelegate>{}, // snapshot_delegate
101+
// fml::WeakPtr<IOManager>{}, // io_manager
102+
// fml::RefPtr<SkiaUnrefQueue>{}, // unref_queue
103+
// fml::WeakPtr<ImageDecoder>{}, // image_decoder
104+
// advisory_script_uri, // advisory_script_uri
105+
// advisory_script_entrypoint, // advisory_script_entrypoint
106+
// false))); // is_root_isolate
107+
108+
//Dart_Isolate vm_isolate = CreateDartIsolateGroup(
109+
// std::move(isolate_group_data), std::move(isolate_data), flags, error);
110+
111+
if (*error) {
112+
std::cout << "CreateDartIsolateGroup failed: " << error;
113+
}
114+
115+
return vm_isolate;
116+
}
117+
118+
// |Dart_IsolateInitializeCallback|
119+
bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data, char** error) {
120+
Dart_Isolate isolate = Dart_CurrentIsolate();
121+
if (isolate == nullptr) {
122+
*error = _strdup("Isolate should be available in initialize callback.");
123+
std::cout << *error;
124+
return false;
125+
}
126+
127+
auto* isolate_group_data =
128+
static_cast<std::shared_ptr<DartIsolateGroupData>*>(
129+
Dart_CurrentIsolateGroupData());
130+
131+
TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(),
132+
/* platform= */ nullptr, /* raster= */ nullptr,
133+
/* ui= */ nullptr,
134+
/* io= */ nullptr);
135+
136+
auto embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
137+
std::shared_ptr<DartIsolate>(new DartIsolate(
138+
(*isolate_group_data)->GetSettings(), // settings
139+
null_task_runners, // task_runners
140+
fml::WeakPtr<SnapshotDelegate>{}, // snapshot_delegate
141+
fml::WeakPtr<IOManager>{}, // io_manager
142+
fml::RefPtr<SkiaUnrefQueue>{}, // unref_queue
143+
fml::WeakPtr<ImageDecoder>{}, // image_decoder
144+
(*isolate_group_data)->GetAdvisoryScriptURI(), // advisory_script_uri
145+
(*isolate_group_data)
146+
->GetAdvisoryScriptEntrypoint(), // advisory_script_entrypoint
147+
false))); // is_root_isolate
148+
149+
// root isolate should have been created via CreateRootIsolate
150+
if (!InitializeIsolate(*embedder_isolate, isolate, error)) {
151+
return false;
152+
}
153+
154+
// The ownership of the embedder object is controlled by the Dart VM. So the
155+
// only reference returned to the caller is weak.
156+
*child_callback_data = embedder_isolate.release();
157+
158+
Dart_EnterIsolate(isolate);
159+
return true;
160+
}
161+
162+
Dart_Isolate DartIsolate::CreateDartIsolateGroup(
163+
std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
164+
std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
165+
Dart_IsolateFlags* flags,
166+
char** error) {
167+
168+
// Create the Dart VM isolate and give it the embedder object as the baton.
169+
Dart_Isolate isolate = Dart_CreateIsolateGroup(
170+
(*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
171+
(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
172+
(*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
173+
(*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
174+
flags, isolate_group_data.get(), isolate_data.get(), error);
175+
176+
if (isolate == nullptr) {
177+
return nullptr;
178+
}
179+
180+
// Ownership of the isolate data objects has been transferred to the Dart VM.
181+
std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
182+
isolate_group_data.release();
183+
isolate_data.release();
184+
185+
if (!InitializeIsolate(std::move(embedder_isolate), isolate, error)) {
186+
return nullptr;
187+
}
188+
189+
return isolate;
190+
}
191+
192+
bool DartIsolate::InitializeIsolate(
193+
std::shared_ptr<DartIsolate> embedder_isolate,
194+
Dart_Isolate isolate,
195+
char** error) {
196+
if (!embedder_isolate->Initialize(isolate)) {
197+
*error = strdup("Embedder could not initialize the Dart isolate.");
198+
std::cout << *error;
199+
return false;
200+
}
201+
202+
if (!embedder_isolate->LoadLibraries()) {
203+
*error = strdup(
204+
"Embedder could not load libraries in the new Dart isolate.");
205+
std::cout << *error;
206+
return false;
207+
}
208+
209+
// Root isolates will be setup by the engine and the service isolate (which is
210+
// also a root isolate) by the utility routines in the VM. However, secondary
211+
// isolates will be run by the VM if they are marked as runnable.
212+
if (!embedder_isolate->IsRootIsolate()) {
213+
auto child_isolate_preparer =
214+
embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
215+
//FML_DCHECK(child_isolate_preparer);
216+
if (!child_isolate_preparer(embedder_isolate.get())) {
217+
*error = _strdup("Could not prepare the child isolate to run.");
218+
std::cout << *error;
219+
return false;
220+
}
221+
}
222+
223+
return true;
224+
}
225+
226+
// |Dart_IsolateShutdownCallback|
227+
void DartIsolate::DartIsolateShutdownCallback(
228+
std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
229+
std::shared_ptr<DartIsolate>* isolate_data) {
230+
isolate_data->get()->OnShutdownCallback();
231+
}
232+
233+
// |Dart_IsolateGroupCleanupCallback|
234+
void DartIsolate::DartIsolateGroupCleanupCallback(
235+
std::shared_ptr<DartIsolateGroupData>* isolate_data) {
236+
delete isolate_data;
237+
}
238+
239+
// |Dart_IsolateCleanupCallback|
240+
void DartIsolate::DartIsolateCleanupCallback(
241+
std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
242+
std::shared_ptr<DartIsolate>* isolate_data) {
243+
delete isolate_data;
244+
}

0 commit comments

Comments
 (0)