665b268641
Review URL: https://chromereviews.googleplex.com/3525014 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@48 260f80e4-7a28-3924-810f-c04153c831b5
1404 lines
49 KiB
C++
1404 lines
49 KiB
C++
// Copyright (c) 2011, 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 "include/dart_api.h"
|
|
|
|
#include "vm/assert.h"
|
|
#include "vm/dart_api_impl.h"
|
|
#include "vm/dart_api_state.h"
|
|
#include "vm/unit_test.h"
|
|
#include "vm/utils.h"
|
|
#include "vm/verifier.h"
|
|
|
|
namespace dart {
|
|
|
|
UNIT_TEST_CASE(BooleanValues) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Dart_EnterScope(); // Enter a Dart API scope for the unit test.
|
|
|
|
Dart_Handle str = Dart_NewString("test");
|
|
EXPECT(!Dart_IsBoolean(str));
|
|
Dart_Handle val1 = Dart_NewBoolean(true);
|
|
EXPECT(Dart_IsBoolean(val1));
|
|
Dart_Handle val2 = Dart_NewBoolean(false);
|
|
EXPECT(Dart_IsBoolean(val2));
|
|
Dart_Result result = Dart_BooleanValue(val1);
|
|
EXPECT(Dart_IsValidResult(result) && Dart_GetResultAsCBoolean(result));
|
|
result = Dart_BooleanValue(val2);
|
|
EXPECT(Dart_IsValidResult(result) && !Dart_GetResultAsCBoolean(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(DoubleValues) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Dart_EnterScope(); // Enter a Dart API scope for the unit test.
|
|
|
|
const double kDoubleVal1 = 201.29;
|
|
const double kDoubleVal2 = 101.19;
|
|
Dart_Handle val1 = Dart_NewDouble(kDoubleVal1);
|
|
EXPECT(Dart_IsDouble(val1));
|
|
Dart_Handle val2 = Dart_NewDouble(kDoubleVal2);
|
|
EXPECT(Dart_IsDouble(val2));
|
|
Dart_Result result = Dart_DoubleValue(val1);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(kDoubleVal1, Dart_GetResultAsCDouble(result));
|
|
result = Dart_DoubleValue(val2);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(kDoubleVal2, Dart_GetResultAsCDouble(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
#if defined(TARGET_ARCH_IA32) // only ia32 can run execution tests.
|
|
|
|
UNIT_TEST_CASE(NumberValues) {
|
|
// TODO(antonm): add various kinds of ints (smi, mint, bigint).
|
|
const char* kScriptChars =
|
|
"class NumberValuesHelper {\n"
|
|
" static int getInt() { return 1; }\n"
|
|
" static double getDouble() { return 1.0; }\n"
|
|
" static bool getBool() { return false; }\n"
|
|
" static getNull() { return null; }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
Dart_Handle handle;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
Dart_Handle class_name = Dart_NewString("NumberValuesHelper");
|
|
// Check int case.
|
|
result = Dart_InvokeStatic(lib,
|
|
class_name,
|
|
Dart_NewString("getInt"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
handle = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(handle));
|
|
EXPECT(Dart_IsNumber(handle));
|
|
|
|
// Check double case.
|
|
result = Dart_InvokeStatic(lib,
|
|
class_name,
|
|
Dart_NewString("getDouble"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
handle = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(handle));
|
|
EXPECT(Dart_IsNumber(handle));
|
|
|
|
// Check bool case.
|
|
result = Dart_InvokeStatic(lib,
|
|
class_name,
|
|
Dart_NewString("getBool"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
handle = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(handle));
|
|
EXPECT(!Dart_IsNumber(handle));
|
|
|
|
// Check null case.
|
|
result = Dart_InvokeStatic(lib,
|
|
class_name,
|
|
Dart_NewString("getNull"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
handle = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(handle));
|
|
EXPECT(!Dart_IsNumber(handle));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
UNIT_TEST_CASE(IntegerValues) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Dart_EnterScope(); // Enter a Dart API scope for the unit test.
|
|
|
|
const int64_t kIntegerVal1 = 100;
|
|
const int64_t kIntegerVal2 = 0xffffffff;
|
|
const char* kIntegerVal3 = "0x123456789123456789123456789";
|
|
|
|
Dart_Handle val1 = Dart_NewInteger(kIntegerVal1);
|
|
EXPECT(Dart_IsInteger(val1));
|
|
Dart_Result fits = Dart_IntegerFitsIntoInt64(val1);
|
|
EXPECT(Dart_IsValidResult(fits));
|
|
EXPECT(Dart_GetResultAsCBoolean(fits));
|
|
|
|
Dart_Handle val2 = Dart_NewInteger(kIntegerVal2);
|
|
EXPECT(Dart_IsInteger(val2));
|
|
fits = Dart_IntegerFitsIntoInt64(val2);
|
|
EXPECT(Dart_IsValidResult(fits));
|
|
EXPECT(Dart_GetResultAsCBoolean(fits));
|
|
|
|
Dart_Handle val3 = Dart_NewIntegerFromHexCString(kIntegerVal3);
|
|
EXPECT(Dart_IsInteger(val3));
|
|
fits = Dart_IntegerFitsIntoInt64(val3);
|
|
EXPECT(Dart_IsValidResult(fits));
|
|
EXPECT(!Dart_GetResultAsCBoolean(fits));
|
|
|
|
Dart_Result result = Dart_IntegerValue(val1);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(kIntegerVal1, Dart_GetResultAsCInt64(result));
|
|
|
|
result = Dart_IntegerValue(val2);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(kIntegerVal2, Dart_GetResultAsCInt64(result));
|
|
|
|
result = Dart_IntegerValue(val3);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!strcmp(kIntegerVal3, Dart_GetResultAsCString(result)));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(ArrayValues) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Dart_EnterScope(); // Enter a Dart API scope for the unit test.
|
|
|
|
const int kArrayLength = 10;
|
|
Dart_Handle str = Dart_NewString("test");
|
|
EXPECT(!Dart_IsArray(str));
|
|
Dart_Handle val = Dart_NewArray(kArrayLength);
|
|
EXPECT(Dart_IsArray(val));
|
|
Dart_Result result = Dart_GetLength(val);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(kArrayLength, Dart_GetResultAsCIntptr(result));
|
|
|
|
// Check invalid array access.
|
|
result = Dart_ArraySetAt(val, (kArrayLength + 10), Dart_NewInteger(10));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_ArraySetAt(val, -10, Dart_NewInteger(10));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_ArrayGetAt(val, (kArrayLength + 10));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_ArrayGetAt(val, -10);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
for (int i = 0; i < kArrayLength; i++) {
|
|
result = Dart_ArraySetAt(val, i, Dart_NewInteger(i));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
}
|
|
for (int i = 0; i < kArrayLength; i++) {
|
|
result = Dart_ArrayGetAt(val, i);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle val_obj = Dart_GetResult(result);
|
|
result = Dart_IntegerValue(val_obj);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(i, Dart_GetResultAsCInt64(result));
|
|
}
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
// Unit test for entering a scope, creating a local handle and exiting
|
|
// the scope.
|
|
UNIT_TEST_CASE(EnterExitScope) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
ApiState* state = isolate->api_state();
|
|
EXPECT(state != NULL);
|
|
ApiLocalScope* scope = state->top_scope();
|
|
Dart_EnterScope();
|
|
{
|
|
EXPECT(state->top_scope() != NULL);
|
|
Zone zone;
|
|
HandleScope hs;
|
|
const String& str1 = String::Handle(String::New("Test String"));
|
|
Dart_Handle ref = Api::NewLocalHandle(str1);
|
|
String& str2 = String::Handle();
|
|
str2 ^= Api::UnwrapHandle(ref);
|
|
EXPECT(str1.Equals(str2));
|
|
}
|
|
Dart_ExitScope();
|
|
EXPECT(scope == state->top_scope());
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
// Unit test for creating and deleting persistent handles.
|
|
UNIT_TEST_CASE(PersistentHandles) {
|
|
const char* kTestString1 = "Test String1";
|
|
const char* kTestString2 = "Test String2";
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
ApiState* state = isolate->api_state();
|
|
EXPECT(state != NULL);
|
|
ApiLocalScope* scope = state->top_scope();
|
|
Dart_Handle handles[2000];
|
|
Dart_EnterScope();
|
|
{
|
|
Zone zone;
|
|
HandleScope hs;
|
|
const String& str1 = String::Handle(String::New(kTestString1));
|
|
Dart_Handle ref1 = Api::NewLocalHandle(str1);
|
|
for (int i = 0; i < 1000; i++) {
|
|
handles[i] = Dart_NewPersistentHandle(ref1);
|
|
}
|
|
Dart_EnterScope();
|
|
const String& str2 = String::Handle(String::New(kTestString2));
|
|
Dart_Handle ref2 = Api::NewLocalHandle(str2);
|
|
for (int i = 1000; i < 2000; i++) {
|
|
handles[i] = Dart_NewPersistentHandle(ref2);
|
|
}
|
|
for (int i = 500; i < 1500; i++) {
|
|
Dart_DeletePersistentHandle(handles[i]);
|
|
}
|
|
for (int i = 500; i < 1000; i++) {
|
|
handles[i] = Dart_NewPersistentHandle(ref2);
|
|
}
|
|
for (int i = 1000; i < 1500; i++) {
|
|
handles[i] = Dart_NewPersistentHandle(ref1);
|
|
}
|
|
VERIFY_ON_TRANSITION;
|
|
Dart_ExitScope();
|
|
}
|
|
Dart_ExitScope();
|
|
{
|
|
Zone zone;
|
|
HandleScope hs;
|
|
for (int i = 0; i < 500; i++) {
|
|
String& str = String::Handle();
|
|
str ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT(str.Equals(kTestString1, strlen(kTestString1)));
|
|
}
|
|
for (int i = 500; i < 1000; i++) {
|
|
String& str = String::Handle();
|
|
str ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT(str.Equals(kTestString2, strlen(kTestString2)));
|
|
}
|
|
for (int i = 1000; i < 1500; i++) {
|
|
String& str = String::Handle();
|
|
str ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT(str.Equals(kTestString1, strlen(kTestString1)));
|
|
}
|
|
for (int i = 1500; i < 2000; i++) {
|
|
String& str = String::Handle();
|
|
str ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT(str.Equals(kTestString2, strlen(kTestString2)));
|
|
}
|
|
}
|
|
EXPECT(scope == state->top_scope());
|
|
EXPECT_EQ(2000, state->CountPersistentHandles());
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
// Unit test for creating multiple scopes and local handles within them.
|
|
// Ensure that the local handles get all cleaned out when exiting the
|
|
// scope.
|
|
UNIT_TEST_CASE(LocalHandles) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
ApiState* state = isolate->api_state();
|
|
EXPECT(state != NULL);
|
|
ApiLocalScope* scope = state->top_scope();
|
|
Dart_Handle handles[300];
|
|
{
|
|
Zone zone;
|
|
HandleScope hs;
|
|
Smi& val = Smi::Handle();
|
|
|
|
// Start a new scope and allocate some local handles.
|
|
Dart_EnterScope();
|
|
for (int i = 0; i < 100; i++) {
|
|
val ^= Smi::New(i);
|
|
handles[i] = Api::NewLocalHandle(val);
|
|
}
|
|
EXPECT_EQ(100, state->CountLocalHandles());
|
|
for (int i = 0; i < 100; i++) {
|
|
val ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT_EQ(i, val.Value());
|
|
}
|
|
// Start another scope and allocate some more local handles.
|
|
{
|
|
Dart_EnterScope();
|
|
for (int i = 100; i < 200; i++) {
|
|
val ^= Smi::New(i);
|
|
handles[i] = Api::NewLocalHandle(val);
|
|
}
|
|
EXPECT_EQ(200, state->CountLocalHandles());
|
|
for (int i = 100; i < 200; i++) {
|
|
val ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT_EQ(i, val.Value());
|
|
}
|
|
|
|
// Start another scope and allocate some more local handles.
|
|
{
|
|
Dart_EnterScope();
|
|
for (int i = 200; i < 300; i++) {
|
|
val ^= Smi::New(i);
|
|
handles[i] = Api::NewLocalHandle(val);
|
|
}
|
|
EXPECT_EQ(300, state->CountLocalHandles());
|
|
for (int i = 200; i < 300; i++) {
|
|
val ^= Api::UnwrapHandle(handles[i]);
|
|
EXPECT_EQ(i, val.Value());
|
|
}
|
|
EXPECT_EQ(300, state->CountLocalHandles());
|
|
VERIFY_ON_TRANSITION;
|
|
Dart_ExitScope();
|
|
}
|
|
EXPECT_EQ(200, state->CountLocalHandles());
|
|
Dart_ExitScope();
|
|
}
|
|
EXPECT_EQ(100, state->CountLocalHandles());
|
|
Dart_ExitScope();
|
|
}
|
|
EXPECT_EQ(0, state->CountLocalHandles());
|
|
EXPECT(scope == state->top_scope());
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
// Unit test for creating multiple scopes and allocating objects in the
|
|
// zone for the scope. Ensure that the memory is freed when the scope
|
|
// exits.
|
|
UNIT_TEST_CASE(LocalZoneMemory) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
ApiState* state = isolate->api_state();
|
|
EXPECT(state != NULL);
|
|
ApiLocalScope* scope = state->top_scope();
|
|
{
|
|
// Start a new scope and allocate some memory.
|
|
Dart_EnterScope();
|
|
for (int i = 0; i < 100; i++) {
|
|
Api::Allocate(16);
|
|
}
|
|
EXPECT_EQ(1600, state->ZoneSizeInBytes());
|
|
// Start another scope and allocate some more memory.
|
|
{
|
|
Dart_EnterScope();
|
|
for (int i = 0; i < 100; i++) {
|
|
Api::Allocate(16);
|
|
}
|
|
EXPECT_EQ(3200, state->ZoneSizeInBytes());
|
|
{
|
|
// Start another scope and allocate some more memory.
|
|
{
|
|
Dart_EnterScope();
|
|
for (int i = 0; i < 200; i++) {
|
|
Api::Allocate(16);
|
|
}
|
|
EXPECT_EQ(6400, state->ZoneSizeInBytes());
|
|
Dart_ExitScope();
|
|
}
|
|
}
|
|
EXPECT_EQ(3200, state->ZoneSizeInBytes());
|
|
Dart_ExitScope();
|
|
}
|
|
EXPECT_EQ(1600, state->ZoneSizeInBytes());
|
|
Dart_ExitScope();
|
|
}
|
|
EXPECT_EQ(0, state->ZoneSizeInBytes());
|
|
EXPECT(scope == state->top_scope());
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(Isolates) {
|
|
// This test currently assumes that the Dart_Isolate type is an opaque
|
|
// representation of Isolate*.
|
|
Dart_Isolate iso_1 = Dart_CreateIsolate(NULL, NULL);
|
|
EXPECT_EQ(iso_1, Isolate::Current());
|
|
Dart_Isolate isolate = Dart_CurrentIsolate();
|
|
EXPECT_EQ(iso_1, isolate);
|
|
Dart_ExitIsolate();
|
|
EXPECT(NULL == Isolate::Current());
|
|
EXPECT(NULL == Dart_CurrentIsolate());
|
|
Dart_Isolate iso_2 = Dart_CreateIsolate(NULL, NULL);
|
|
EXPECT_EQ(iso_2, Isolate::Current());
|
|
Dart_ExitIsolate();
|
|
EXPECT(NULL == Isolate::Current());
|
|
Dart_EnterIsolate(iso_2);
|
|
EXPECT_EQ(iso_2, Isolate::Current());
|
|
Dart_ShutdownIsolate();
|
|
EXPECT(NULL == Isolate::Current());
|
|
Dart_EnterIsolate(iso_1);
|
|
EXPECT_EQ(iso_1, Isolate::Current());
|
|
Dart_ShutdownIsolate();
|
|
EXPECT(NULL == Isolate::Current());
|
|
}
|
|
|
|
|
|
#if defined(TARGET_ARCH_IA32) // only ia32 can run execution tests.
|
|
|
|
UNIT_TEST_CASE(FieldAccess) {
|
|
const char* kScriptChars =
|
|
"class Fields {\n"
|
|
" Fields(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static int fld3;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class FieldsTest {\n"
|
|
" static Fields testMain() {\n"
|
|
" Fields obj = new Fields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("FieldsTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
// Now access and set various static fields of Fields class.
|
|
result = Dart_GetClass(lib, Dart_NewString("Fields"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle cls = Dart_GetResult(result);
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld1"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld3"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld4"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(10, Dart_GetResultAsCInt64(result));
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("fld4"),
|
|
Dart_NewInteger(20));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld3"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("fld3"),
|
|
Dart_NewInteger(200));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(200, Dart_GetResultAsCInt64(result));
|
|
|
|
// Now access and set various instance fields of the returned object.
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld3"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(10, Dart_GetResultAsCInt64(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(20, Dart_GetResultAsCInt64(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("fld2"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("fld1"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(40, Dart_GetResultAsCInt64(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(HiddenFieldAccess) {
|
|
const char* kScriptChars =
|
|
"class HiddenFields {\n"
|
|
" HiddenFields(int i, int j) : _fld1 = i, _fld2 = j {}\n"
|
|
" int _fld1;\n"
|
|
" final int _fld2;\n"
|
|
" static int _fld3;\n"
|
|
" static final int _fld4 = 10;\n"
|
|
"}\n"
|
|
"class HiddenFieldsTest {\n"
|
|
" static HiddenFields testMain() {\n"
|
|
" HiddenFields obj = new HiddenFields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Load up a test script which extends the native wrapper class.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("HiddenFieldsTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
// Now access and set various static fields of HiddenFields class.
|
|
result = Dart_GetClass(lib, Dart_NewString("HiddenFields"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle cls = Dart_GetResult(result);
|
|
result = Dart_GetStaticField(cls, Dart_NewString("_fld1"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("_fld3"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetStaticField(cls, Dart_NewString("_fld4"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(10, Dart_GetResultAsCInt64(result));
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("_fld4"),
|
|
Dart_NewInteger(20));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetStaticField(cls, Dart_NewString("_fld3"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("_fld3"),
|
|
Dart_NewInteger(200));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(200, Dart_GetResultAsCInt64(result));
|
|
|
|
// Now access and set various instance fields of the returned object.
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("_fld3"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("_fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(10, Dart_GetResultAsCInt64(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("_fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(20, Dart_GetResultAsCInt64(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("_fld2"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("_fld1"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("_fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(40, Dart_GetResultAsCInt64(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(InjectNativeFields1) {
|
|
const char* kScriptChars =
|
|
"class NativeFields extends NativeFieldsWrapper {\n"
|
|
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static int fld3;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class NativeFieldsTest {\n"
|
|
" static NativeFields testMain() {\n"
|
|
" NativeFields obj = new NativeFields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Zone zone;
|
|
HandleScope scope;
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
const int kNumNativeFields = 4;
|
|
|
|
// Create a test library.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Create a native wrapper class with native fields.
|
|
result = Dart_CreateNativeWrapperClass(
|
|
lib,
|
|
Dart_NewString("NativeFieldsWrapper"),
|
|
kNumNativeFields);
|
|
|
|
// Load up a test script in the test library.
|
|
|
|
// Invoke a function which returns an object of type NativeFields.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("NativeFieldsTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
Instance& obj = Instance::Handle();
|
|
obj ^= Api::UnwrapHandle(retobj);
|
|
const Class& cls = Class::Handle(obj.clazz());
|
|
// We expect the newly created "NativeFields" object to have
|
|
// 2 dart instance fields (fld1, fld2) and kNumNativeFields native fields.
|
|
// Hence the size of an instance of "NativeFields" should be
|
|
// (kNumNativeFields + 2) * kWordSize + sizeof the header word.
|
|
// We check to make sure the instance size computed by the VM matches
|
|
// our expectations.
|
|
EXPECT_EQ(Utils::RoundUp(((kNumNativeFields + 2) * kWordSize) + kWordSize,
|
|
kObjectAlignment),
|
|
cls.instance_size());
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(InjectNativeFields2) {
|
|
const char* kScriptChars =
|
|
"class NativeFields extends NativeFieldsWrapper {\n"
|
|
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static int fld3;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class NativeFieldsTest {\n"
|
|
" static NativeFields testMain() {\n"
|
|
" NativeFields obj = new NativeFields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object of type NativeFields.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("NativeFieldsTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
// We expect this to fail as class "NativeFields" extends
|
|
// "NativeFieldsWrapper" and there is no definition of it either
|
|
// in the dart code or through the native field injection mechanism.
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(NativeFieldAccess) {
|
|
const char* kScriptChars =
|
|
"class NativeFields extends NativeFieldsWrapper {\n"
|
|
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static int fld3;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class NativeFieldsTest {\n"
|
|
" static NativeFields testMain() {\n"
|
|
" NativeFields obj = new NativeFields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
const int kNumNativeFields = 4;
|
|
|
|
// Create a test library.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Create a native wrapper class with native fields.
|
|
result = Dart_CreateNativeWrapperClass(
|
|
lib,
|
|
Dart_NewString("NativeFieldsWrapper"),
|
|
kNumNativeFields);
|
|
|
|
// Load up a test script in it.
|
|
|
|
// Invoke a function which returns an object of type NativeFields.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("NativeFieldsTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
// Now access and set various instance fields of the returned object.
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld3"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(10, Dart_GetResultAsCInt64(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(20, Dart_GetResultAsCInt64(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("fld2"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetInstanceField(retobj,
|
|
Dart_NewString("fld1"),
|
|
Dart_NewInteger(40));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(40, Dart_GetResultAsCInt64(result));
|
|
|
|
// Now access and set various native instance fields of the returned object.
|
|
const int kNativeFld0 = 0;
|
|
const int kNativeFld1 = 1;
|
|
const int kNativeFld2 = 2;
|
|
const int kNativeFld3 = 3;
|
|
const int kNativeFld4 = 4;
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld4);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld0);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(0, Dart_GetResultAsCIntptr(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld1);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(0, Dart_GetResultAsCIntptr(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld2);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(0, Dart_GetResultAsCIntptr(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld4, 40);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld0, 4);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld1, 40);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld2, 400);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld3, 4000);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld3);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT_EQ(4000, Dart_GetResultAsCIntptr(result));
|
|
|
|
// Now re-access various dart instance fields of the returned object
|
|
// to ensure that there was no corruption while setting native fields.
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(40, Dart_GetResultAsCInt64(result));
|
|
result = Dart_GetInstanceField(retobj, Dart_NewString("fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(20, Dart_GetResultAsCInt64(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(NegativeNativeFieldAccess) {
|
|
const char* kScriptChars =
|
|
"class NativeFields {\n"
|
|
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static int fld3;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class NativeFieldsTest {\n"
|
|
" static NativeFields testMain1() {\n"
|
|
" NativeFields obj = new NativeFields(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
" static Function testMain2() {\n"
|
|
" return function() {};\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Zone zone;
|
|
HandleScope scope;
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object of type NativeFields.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("NativeFieldsTest"),
|
|
Dart_NewString("testMain1"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
|
|
// Now access and set various native instance fields of the returned object.
|
|
// All of these tests are expected to return failure as there are no
|
|
// native fields in an instance of NativeFields.
|
|
const int kNativeFld0 = 0;
|
|
const int kNativeFld1 = 1;
|
|
const int kNativeFld2 = 2;
|
|
const int kNativeFld3 = 3;
|
|
const int kNativeFld4 = 4;
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld4);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld0);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld1);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld2);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld4, 40);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld3, 40);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld0, 400);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
// Invoke a function which returns a closure object.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("NativeFieldsTest"),
|
|
Dart_NewString("testMain2"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld4);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld0);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld1);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_GetNativeInstanceField(retobj, kNativeFld2);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld4, 40);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld3, 40);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
result = Dart_SetNativeInstanceField(retobj, kNativeFld0, 400);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(GetStaticField_RunsInitializer) {
|
|
const char* kScriptChars =
|
|
"class TestClass {\n"
|
|
" static final int fld1 = 7;\n"
|
|
" static int fld2 = 11;\n"
|
|
" static void testMain() {\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("TestClass"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
|
|
result = Dart_GetClass(lib, Dart_NewString("TestClass"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle cls = Dart_GetResult(result);
|
|
|
|
// For uninitialized fields, the getter is returned
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld1"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(7, Dart_GetResultAsCInt64(result));
|
|
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(11, Dart_GetResultAsCInt64(result));
|
|
|
|
// Overwrite fld2
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("fld2"),
|
|
Dart_NewInteger(13));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
|
|
// We now get the new value for fld2, not the initializer
|
|
result = Dart_GetStaticField(cls, Dart_NewString("fld2"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
result = Dart_IntegerValue(Dart_GetResult(result));
|
|
EXPECT_EQ(13, Dart_GetResultAsCInt64(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(StaticFieldNotFound) {
|
|
const char* kScriptChars =
|
|
"class TestClass {\n"
|
|
" static void testMain() {\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("TestClass"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
|
|
result = Dart_GetClass(lib, Dart_NewString("TestClass"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle cls = Dart_GetResult(result);
|
|
|
|
result = Dart_GetStaticField(cls, Dart_NewString("not_found"));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
EXPECT_STREQ("Specified field is not found in the class",
|
|
Dart_GetErrorCString(result));
|
|
|
|
result = Dart_SetStaticField(cls,
|
|
Dart_NewString("not_found"),
|
|
Dart_NewInteger(13));
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
EXPECT_STREQ("Specified field is not found in the class",
|
|
Dart_GetErrorCString(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(InvokeDynamic) {
|
|
const char* kScriptChars =
|
|
"class InvokeDynamic {\n"
|
|
" InvokeDynamic(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" int method1(int i) { return i + fld1 + fld2 + fld4; }\n"
|
|
" static int method2(int i) { return i + fld4; }\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class InvokeDynamicTest {\n"
|
|
" static InvokeDynamic testMain() {\n"
|
|
" InvokeDynamic obj = new InvokeDynamic(10, 20);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Zone zone;
|
|
HandleScope scope;
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object of type InvokeDynamic.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("InvokeDynamicTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
|
|
// Now invoke a dynamic method and check the result.
|
|
Dart_Handle dart_arguments[1];
|
|
dart_arguments[0] = Dart_NewInteger(1);
|
|
result = Dart_InvokeDynamic(retobj,
|
|
Dart_NewString("method1"),
|
|
1,
|
|
dart_arguments);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle obj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(obj));
|
|
EXPECT(Dart_IsInteger(obj));
|
|
result = Dart_IntegerValue(obj);
|
|
EXPECT_EQ(41, Dart_GetResultAsCInt64(result));
|
|
|
|
result = Dart_InvokeDynamic(retobj, Dart_NewString("method2"), 0, NULL);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
result = Dart_InvokeDynamic(retobj, Dart_NewString("method1"), 0, NULL);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(InvokeClosure) {
|
|
const char* kScriptChars =
|
|
"class InvokeClosure {\n"
|
|
" InvokeClosure(int i, int j) : fld1 = i, fld2 = j {}\n"
|
|
" Function method1(int i) {\n"
|
|
" f(int j) => j + i + fld1 + fld2 + fld4; \n"
|
|
" return f;\n"
|
|
" }\n"
|
|
" static Function method2(int i) {\n"
|
|
" n(int j) => true + i + fld4; \n"
|
|
" return n;\n"
|
|
" }\n"
|
|
" int fld1;\n"
|
|
" final int fld2;\n"
|
|
" static final int fld4 = 10;\n"
|
|
"}\n"
|
|
"class InvokeClosureTest {\n"
|
|
" static Function testMain1() {\n"
|
|
" InvokeClosure obj = new InvokeClosure(10, 20);\n"
|
|
" return obj.method1(10);\n"
|
|
" }\n"
|
|
" static Function testMain2() {\n"
|
|
" return InvokeClosure.method2(10);\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Zone zone;
|
|
HandleScope scope;
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns a closure.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("InvokeClosureTest"),
|
|
Dart_NewString("testMain1"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
EXPECT(Dart_IsClosure(retobj));
|
|
EXPECT(!Dart_IsClosure(Dart_NewInteger(101)));
|
|
|
|
// Now invoke the closure and check the result.
|
|
Dart_Handle dart_arguments[1];
|
|
dart_arguments[0] = Dart_NewInteger(1);
|
|
result = Dart_InvokeClosure(retobj, 1, dart_arguments);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle obj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(obj));
|
|
EXPECT(Dart_IsInteger(obj));
|
|
result = Dart_IntegerValue(obj);
|
|
EXPECT_EQ(51, Dart_GetResultAsCInt64(result));
|
|
|
|
// Invoke closure with wrong number of args, should result in exception.
|
|
result = Dart_InvokeClosure(retobj, 0, NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
obj = Dart_GetResult(result);
|
|
EXPECT(Dart_ExceptionOccurred(obj));
|
|
|
|
// Invoke a function which returns a closure.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("InvokeClosureTest"),
|
|
Dart_NewString("testMain2"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
EXPECT(Dart_IsClosure(retobj));
|
|
EXPECT(!Dart_IsClosure(Dart_NewString("abcdef")));
|
|
|
|
// Now invoke the closure and check the result (should be an exception).
|
|
dart_arguments[0] = Dart_NewInteger(1);
|
|
result = Dart_InvokeClosure(retobj, 1, dart_arguments);
|
|
retobj = Dart_GetResult(result);
|
|
EXPECT(Dart_ExceptionOccurred(retobj));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
void ExceptionNative(Dart_NativeArguments args) {
|
|
Dart_Handle param = Dart_GetNativeArgument(args, 0);
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
char* str = reinterpret_cast<char*>(Api::Allocate(1024));
|
|
str[0] = 0;
|
|
Dart_ThrowException(param);
|
|
UNREACHABLE();
|
|
}
|
|
|
|
|
|
static Dart_NativeFunction native_lookup(Dart_Handle name, int argument_count) {
|
|
return reinterpret_cast<Dart_NativeFunction>(&ExceptionNative);
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(ThrowException) {
|
|
const char* kScriptChars =
|
|
"class ThrowException {\n"
|
|
" ThrowException(int i) : fld1 = i {}\n"
|
|
" int method1(int i) native \"ThrowException_native\";"
|
|
" int method2() {\n"
|
|
" try { method1(10); } catch(var a) { return 5; } return 10;\n"
|
|
" }\n"
|
|
" int fld1;\n"
|
|
"}\n"
|
|
"class ThrowExceptionTest {\n"
|
|
" static ThrowException testMain() {\n"
|
|
" ThrowException obj = new ThrowException(10);\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
ApiState* state = isolate->api_state();
|
|
EXPECT(state != NULL);
|
|
{
|
|
intptr_t size = state->ZoneSizeInBytes();
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Load up a test script which extends the native wrapper class.
|
|
Dart_Handle lib = TestCase::LoadTestScript(
|
|
kScriptChars,
|
|
reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
|
|
|
|
// Invoke a function which returns an object of type ThrowException.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("ThrowExceptionTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(retobj));
|
|
|
|
// Throwing an exception here should result in an error.
|
|
result = Dart_ThrowException(retobj);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
// Now invoke method2 which invokes a natve method where it is
|
|
// ok to throw an exception, check the result which would indicate
|
|
// if an exception was thrown or not.
|
|
result = Dart_InvokeDynamic(retobj, Dart_NewString("method2"), 0, NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle obj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(obj));
|
|
EXPECT(Dart_IsInteger(obj));
|
|
result = Dart_IntegerValue(obj);
|
|
EXPECT_EQ(5, Dart_GetResultAsCInt64(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
EXPECT_EQ(size, state->ZoneSizeInBytes());
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(InstanceOf) {
|
|
const char* kScriptChars =
|
|
"class OtherClass {\n"
|
|
" static returnNull() { return null; }\n"
|
|
"}\n"
|
|
"class InstanceOfTest {\n"
|
|
" InstanceOfTest() {}\n"
|
|
" static InstanceOfTest testMain() {\n"
|
|
" return new InstanceOfTest();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Result result;
|
|
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
{
|
|
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
|
|
|
// Create a test library and Load up a test script in it.
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
|
|
// Invoke a function which returns an object of type InstanceOf..
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("InstanceOfTest"),
|
|
Dart_NewString("testMain"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle instanceOfTestObj = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(instanceOfTestObj));
|
|
|
|
// Fetch InstanceOfTest class.
|
|
result = Dart_GetClass(lib, Dart_NewString("InstanceOfTest"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle cls = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(cls));
|
|
|
|
// Now check instanceOfTestObj reported as an instance of
|
|
// InstanceOfTest class.
|
|
result = Dart_IsInstanceOf(instanceOfTestObj, cls);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(Dart_GetResultAsCBoolean(result));
|
|
|
|
// Fetch OtherClass and check if instanceOfTestObj is instance of it.
|
|
result = Dart_GetClass(lib, Dart_NewString("OtherClass"));
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle otherClass = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(otherClass));
|
|
|
|
result = Dart_IsInstanceOf(instanceOfTestObj, otherClass);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!Dart_GetResultAsCBoolean(result));
|
|
|
|
// Check that primitives are not instances of InstanceOfTest class.
|
|
result = Dart_IsInstanceOf(Dart_NewString("a string"), otherClass);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!Dart_GetResultAsCBoolean(result));
|
|
|
|
result = Dart_IsInstanceOf(Dart_NewInteger(42), otherClass);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!Dart_GetResultAsCBoolean(result));
|
|
|
|
result = Dart_IsInstanceOf(Dart_NewBoolean(true), otherClass);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!Dart_GetResultAsCBoolean(result));
|
|
|
|
// Check that null is not an instance of InstanceOfTest class.
|
|
result = Dart_InvokeStatic(lib,
|
|
Dart_NewString("OtherClass"),
|
|
Dart_NewString("returnNull"),
|
|
0,
|
|
NULL);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle null = Dart_GetResult(result);
|
|
EXPECT(!Dart_ExceptionOccurred(null));
|
|
|
|
result = Dart_IsInstanceOf(null, otherClass);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
EXPECT(!Dart_GetResultAsCBoolean(result));
|
|
|
|
// Check that error is returned if null is passed as a class argument.
|
|
result = Dart_IsInstanceOf(null, null);
|
|
EXPECT(!Dart_IsValidResult(result));
|
|
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
}
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
|
|
UNIT_TEST_CASE(NullReceiver) {
|
|
Dart_CreateIsolate(NULL, NULL);
|
|
Dart_EnterScope(); // Enter a Dart API scope for the unit test.
|
|
{
|
|
Zone zone;
|
|
HandleScope hs;
|
|
|
|
Dart_Handle function_name = Dart_NewString("toString");
|
|
const int number_of_arguments = 0;
|
|
Dart_Handle null_receiver = Api::NewLocalHandle(Object::Handle());
|
|
Dart_Handle dart_arguments[0];
|
|
Dart_Result result = Dart_InvokeDynamic(null_receiver,
|
|
function_name,
|
|
number_of_arguments,
|
|
dart_arguments);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
Dart_Handle retobj = Dart_GetResult(result);
|
|
EXPECT(Dart_IsString(retobj));
|
|
|
|
// Should throw a NullPointerException. Disabled due to bug 5415268.
|
|
/*
|
|
Dart_Handle function_name2 = Dart_NewString("NoNoNo");
|
|
result = Dart_InvokeDynamic(null_receiver,
|
|
function_name2,
|
|
number_of_arguments,
|
|
dart_arguments);
|
|
EXPECT(Dart_IsValidResult(result));
|
|
retobj = Dart_GetResult(result);
|
|
EXPECT(Dart_ExceptionOccurred(retobj)); */
|
|
}
|
|
Dart_ExitScope(); // Exit the Dart API scope.
|
|
Dart_ShutdownIsolate();
|
|
}
|
|
|
|
#endif // TARGET_ARCH_IA32.
|
|
|
|
} // namespace dart
|