blob: 869dfd6616bd57f266215544faf4ff64553d3406 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO(dartbug.com/40579): This requires static linking to either link
// dart.exe or dart_precompiled_runtime.exe on Windows.
// The sample currently fails on Windows in AOT mode.
#include "include/dart_api.h"
#include "include/dart_native_api.h"
#define CHECK(H) \
do { \
Dart_Handle __handle__ = H; \
if (Dart_IsError(__handle__)) { \
const char* message = Dart_GetError(__handle__); \
fprintf(stderr, "Check \"" #H "\" failed: %s", message); \
abort(); \
} \
} while (false)
#define ASSERT(E) \
if (!(E)) { \
fprintf(stderr, "Assertion \"" #E "\" failed at %s:%d!\n", __FILE__, \
__LINE__); \
abort(); \
}
static bool is_dart_precompiled_runtime = true;
// Some invalid accesses are allowed in AOT since we don't retain @pragma
// annotations. Therefore we skip the negative tests in AOT.
#define FAIL(name, result) \
if (!is_dart_precompiled_runtime) { \
Fail(name, result); \
}
void Fail(const char* name, Dart_Handle result) {
ASSERT(Dart_IsApiError(result));
const char* error = Dart_GetError(result);
ASSERT(strstr(error, name));
ASSERT(strstr(error, "It is illegal to access"));
}
#define FAIL_INVOKE_FIELD(name, result) \
if (!is_dart_precompiled_runtime) { \
FailInvokeField(name, result); \
}
static void FailInvokeField(const char* name, Dart_Handle result) {
ASSERT(Dart_IsApiError(result));
const char* error = Dart_GetError(result);
ASSERT(strstr(error, name));
ASSERT(strstr(error, "Entry-points do not allow invoking fields"));
}
static void FailClosurizeConstructor(const char* name, Dart_Handle result) {
ASSERT(Dart_IsUnhandledExceptionError(result));
const char* error = Dart_GetError(result);
ASSERT(strstr(error, name));
ASSERT(strstr(error, "No static getter"));
}
static void TestFields(Dart_Handle target) {
FAIL("fld0", Dart_GetField(target, Dart_NewStringFromCString("fld0")));
FAIL("fld0",
Dart_SetField(target, Dart_NewStringFromCString("fld0"), Dart_Null()));
FAIL_INVOKE_FIELD(
"fld0",
Dart_Invoke(target, Dart_NewStringFromCString("fld0"), 0, nullptr));
CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld1")));
CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld1"), Dart_Null()));
FAIL_INVOKE_FIELD(
"fld1",
Dart_Invoke(target, Dart_NewStringFromCString("fld1"), 0, nullptr));
CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld2")));
FAIL("fld2",
Dart_SetField(target, Dart_NewStringFromCString("fld2"), Dart_Null()));
FAIL_INVOKE_FIELD(
"fld2",
Dart_Invoke(target, Dart_NewStringFromCString("fld2"), 0, nullptr));
FAIL("fld3", Dart_GetField(target, Dart_NewStringFromCString("fld3")));
CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld3"), Dart_Null()));
FAIL_INVOKE_FIELD(
"fld3",
Dart_Invoke(target, Dart_NewStringFromCString("fld3"), 0, nullptr));
}
DART_EXPORT void RunTests() {
is_dart_precompiled_runtime = Dart_IsPrecompiledRuntime();
Dart_Handle lib = Dart_RootLibrary();
//////// Test allocation and constructor invocation.
FAIL("C", Dart_GetClass(lib, Dart_NewStringFromCString("C")));
Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
CHECK(D_class);
CHECK(Dart_Allocate(D_class));
FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));
CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));
Dart_Handle D =
Dart_New(D_class, Dart_NewStringFromCString("fact"), 0, nullptr);
CHECK(D);
//////// Test actions against methods
FailClosurizeConstructor(
"defined", Dart_GetField(D_class, Dart_NewStringFromCString("defined")));
FailClosurizeConstructor(
"fact", Dart_GetField(D_class, Dart_NewStringFromCString("fact")));
FAIL("fn0", Dart_Invoke(D, Dart_NewStringFromCString("fn0"), 0, nullptr));
CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1"), 0, nullptr));
FAIL("fn1", Dart_Invoke(D, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1_call"), 0, nullptr));
FAIL("fn0", Dart_GetField(D, Dart_NewStringFromCString("fn0")));
CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1")));
CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1_get")));
FAIL("fn1", Dart_GetField(D, Dart_NewStringFromCString("fn1_call")));
FAIL("fn2",
Dart_Invoke(D_class, Dart_NewStringFromCString("fn2"), 0, nullptr));
CHECK(Dart_Invoke(D_class, Dart_NewStringFromCString("fn3"), 0, nullptr));
CHECK(
Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_call"), 0, nullptr));
FAIL("fn3",
Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_get"), 0, nullptr));
FAIL("fn2", Dart_GetField(D_class, Dart_NewStringFromCString("fn2")));
CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3")));
FAIL("fn3_call",
Dart_GetField(D_class, Dart_NewStringFromCString("fn3_call")));
CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3_get")));
FAIL("fn0", Dart_Invoke(lib, Dart_NewStringFromCString("fn0"), 0, nullptr));
CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1"), 0, nullptr));
FAIL("fn1",
Dart_Invoke(lib, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1_call"), 0, nullptr));
FAIL("fn0", Dart_GetField(lib, Dart_NewStringFromCString("fn0")));
CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1")));
CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1_get")));
FAIL("fn1", Dart_GetField(lib, Dart_NewStringFromCString("fn1_call")));
//////// Test actions against fields
TestFields(D);
Dart_Handle F_class = Dart_GetClass(lib, Dart_NewStringFromCString("F"));
TestFields(F_class);
TestFields(lib);
}